//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "stdafx.h" #include #include #include "hammer.h" #include "Box3D.h" // For units #include "EntityReportDlg.h" #include "FaceEditSheet.h" #include "MainFrm.h" #include "MessageWnd.h" #include "ControlBarIDs.h" #include "CustomMessages.h" #include "DynamicDialogWnd.h" #include "filesystem_tools.h" #include "GlobalFunctions.h" #include "Prefabs.h" #include "PrefabsDlg.h" #include "MapDoc.h" #include "Manifest.h" #include "StatusBarIDs.h" #include "Splash.h" #include "Options.h" #include "OptionProperties.h" #include "ObjectProperties.h" #include "OP_Groups.h" #include "MapView2D.h" #include "MapViewLogical.h" #include "MapView3D.h" #include "ChildFrm.h" #include "NewDocType.h" #include "SearchReplaceDlg.h" #include "TextureBrowser.h" #include "TextureSystem.h" #include "ToolManager.h" #include "Material.h" #include "materialsystem/IMaterialSystem.h" #include "materialsystem/MaterialSystem_Config.h" #include "soundbrowser.h" #include "lprvwindow.h" #include "toolframework/ienginetool.h" #include "toolutils/enginetools_int.h" #include "foundrytool.h" #include "cmdhandlers.h" #include "modelbrowser.h" #include #include "tablet.h" // memdbgon must be the last include file in a .cpp file!!! #include IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_COMMAND(ID_EDIT_PROPERTIES, OnEditProperties) ON_UPDATE_COMMAND_UI(ID_EDIT_PROPERTIES, OnUpdateEditFunction) ON_COMMAND(ID_VIEW_MESSAGES, OnViewMessages) ON_UPDATE_COMMAND_UI(ID_VIEW_MESSAGES, OnUpdateViewMessages) ON_UPDATE_COMMAND_UI(ID_FOUNDRY_SENDSELECTEDENTITIESTOENGINE, OnUpdateFoundrySendSelectedEntitiesToEngine) ON_COMMAND(ID_FOUNDRY_SENDSELECTEDENTITIESTOENGINE, OnFoundrySendSelectedEntitiesToEngine) ON_UPDATE_COMMAND_UI(ID_FOUNDRY_MOVEENGINEVIEWTOHAMMER3DVIEW, OnUpdateFoundryMoveEngineViewToHammer3DView) ON_COMMAND(ID_FOUNDRY_MOVEENGINEVIEWTOHAMMER3DVIEW, OnFoundryMoveEngineViewToHammer3DView) ON_UPDATE_COMMAND_UI(ID_FOUNDRY_REMOVESELECTEDENTITIESFROMENGINE, OnUpdateFoundryRemoveSelectedEntitiesFromEngine) ON_COMMAND(ID_FOUNDRY_REMOVESELECTEDENTITIESFROMENGINE, OnFoundryRemoveSelectedEntitiesFromEngine) ON_UPDATE_COMMAND_UI(ID_FOUNDRY_MOVEFOCUSTOENGINE, OnUpdateFoundryMoveFocusToEngine) ON_COMMAND(ID_FOUNDRY_MOVEFOCUSTOENGINE, OnFoundryMoveFocusToEngine) ON_WM_ACTIVATEAPP() ON_WM_SIZE() ON_WM_CLOSE() ON_WM_DESTROY() ON_WM_PAINT() ON_WM_TIMER() ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions) ON_COMMAND(ID_TOOLS_PREFABFACTORY, OnToolsPrefabfactory) ON_COMMAND_EX(ID_HELP_TOPICS, OnHelpOpenURL) ON_COMMAND_EX(ID_HELP_EDITINGSITE, OnHelpOpenURL) ON_COMMAND_EX(ID_HELP_WORLDCRAFT_SUPPORT_MAIL, OnHelpOpenURL) ON_COMMAND(ID_EDIT_UNDOREDOACTIVE, OnEditUndoredoactive) ON_UPDATE_COMMAND_UI(ID_EDIT_UNDOREDOACTIVE, OnUpdateEditUndoredoactive) ON_COMMAND_EX(ID_FILE_NEW, OnFileNew) ON_COMMAND(ID_SAVEWINDOWSTATE, OnSavewindowstate) ON_COMMAND(ID_LOADWINDOWSTATE, OnLoadwindowstate) ON_COMMAND_EX(ID_MAP_UNITS_NONE, OnUnits) ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_NONE, OnUpdateUnits) ON_COMMAND_EX(ID_MAP_UNITS_INCHES, OnUnits) ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_INCHES, OnUpdateUnits) ON_COMMAND_EX(ID_MAP_UNITS_FEET_INCHES, OnUnits) ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_FEET_INCHES, OnUpdateUnits) ON_UPDATE_COMMAND_UI(ID_VIEW_OPAQUE_MATERIALS, OnUpdateOpaqueMaterials) ON_UPDATE_COMMAND_UI(ID_VIEW_2DXZ, OnUpdateView2d) ON_UPDATE_COMMAND_UI(ID_VIEW_2DYZ, OnUpdateView2d) ON_UPDATE_COMMAND_UI(ID_VIEW_2DXY, OnUpdateView2d) ON_UPDATE_COMMAND_UI(ID_VIEW_3DWIREFRAME, OnUpdateView3d) ON_UPDATE_COMMAND_UI(ID_VIEW_3DPOLYGON, OnUpdateView3d) ON_UPDATE_COMMAND_UI(ID_VIEW_3DTEXTURED, OnUpdateView3d) //ON_UPDATE_COMMAND_UI(ID_VIEW_3DENGINE, OnUpdateView3d) ON_COMMAND(ID_VIEW_OPAQUE_MATERIALS, OnOpaqueMaterials) ON_COMMAND_EX(ID_VIEW3D_BRIGHTER, OnView3dChangeBrightness) ON_COMMAND_EX(ID_VIEW3D_DARKER, OnView3dChangeBrightness) ON_UPDATE_COMMAND_UI(ID_VIEW_OBJECTBAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_OBJECTBAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_SELECTION_MODE_BAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_SELECTION_MODE_BAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_FILTERCONTROL, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_FILTERCONTROL, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_MAPVIEWBAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_MAPVIEWBAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_MAPTOOLSBAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_MAPTOOLSBAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_TEXTUREBAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_TEXTUREBAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_MANIFEST_BAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_MANIFEST_BAR, CFrameWnd::OnBarCheck) //ON_UPDATE_COMMAND_UI(ID_VIEW_ANIMATIONBAR, CFrameWnd::OnUpdateControlBarMenu) //ON_COMMAND_EX(ID_VIEW_ANIMATIONBAR, CFrameWnd::OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_MAPOPSBAR, CFrameWnd::OnUpdateControlBarMenu) ON_COMMAND_EX(ID_VIEW_MAPOPSBAR, CFrameWnd::OnBarCheck) ON_COMMAND_EX(ID_TOOLS_POINTER, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_POINTER, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_CAMERA, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERA, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_MAGNIFY, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_MAGNIFY, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_BLOCK, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_BLOCK, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_ENTITY, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_ENTITY, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_APPLYDECALS, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_APPLYDECALS, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_MORPH, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_MORPH, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_SYNC_MESH, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_SYNC_MESH, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_CLIPPER, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_CLIPPER, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_EDITCORDON, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_EDITCORDON, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_PATH, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_PATH, OnUpdateToolUI) ON_COMMAND_EX(ID_TOOLS_OVERLAY, OnChangeTool) ON_UPDATE_COMMAND_UI(ID_TOOLS_OVERLAY, OnUpdateToolUI) ON_COMMAND_EX(ID_MODE_APPLICATOR, OnApplicator) ON_COMMAND_EX(ID_TOOLS_SOUND_BROWSER, OnSoundBrowser) ON_COMMAND(ID_TOOLS_MODEL_BROWSER, OnModelBrowser) ON_COMMAND_EX(ID_FILE_RELOAD_SOUNDS, OnReloadSounds) ON_UPDATE_COMMAND_UI(ID_MODE_APPLICATOR, OnUpdateApplicatorUI) ON_COMMAND(ID_HELP_FINDER, CMDIFrameWnd::OnHelpFinder) ON_COMMAND(ID_HELP, CMDIFrameWnd::OnHelp) ON_COMMAND(ID_CONTEXT_HELP, CMDIFrameWnd::OnContextHelp) ON_COMMAND(ID_DEFAULT_HELP, CMDIFrameWnd::OnHelpFinder) ON_COMMAND(ID_HDR, OnHDR) ON_WM_HELPINFO() ON_WM_SYSCOMMAND() ON_WM_ENTERMENULOOP() ON_MESSAGE( WT_PACKET, OnWTPacket ) //}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_SELECTION, ID_INDICATOR_COORDS, ID_INDICATOR_SIZE, ID_INDICATOR_GRIDZOOM, ID_INDICATOR_SNAP }; const int NUMSTATUSPANES = 7; const char * WINSTATETAG = "WCWINSTATE"; const int WINSTATEEND = -1; const int WINSTATE2DVIEW = 0; const int WINSTATE3DVIEW = 1; const int WINSTATELOGICALVIEW = 2; const float fVersion = 0.1f; struct { int nIndex; UINT nID; UINT nStyle; int cxWidth; } paneinfo[NUMSTATUSPANES] = { { SBI_PROMPT, ID_SEPARATOR, SBPS_STRETCH | SBPS_NOBORDERS, 0 }, { SBI_SELECTION, ID_INDICATOR_SELECTION, SBPS_NORMAL, 300 }, { SBI_COORDS, ID_INDICATOR_COORDS, SBPS_NORMAL, 100 }, { SBI_SIZE, ID_INDICATOR_SIZE, SBPS_NORMAL, 180 }, { SBI_GRIDZOOM, ID_INDICATOR_GRIDZOOM, SBPS_NORMAL, 80 }, { SBI_SNAP, ID_INDICATOR_SNAP, SBPS_NORMAL, 135 }, { SBI_LIGHTPROGRESS,ID_INDICATOR_LIGHTPROGRESS, SBPS_NORMAL, 50 } }; static GameData gd; static CMainFrame *g_pMainWnd; //----------------------------------------------------------------------------- // Purpose: Constructor. //----------------------------------------------------------------------------- CMainFrame::CMainFrame(void) { pTextureBrowser = NULL; pObjectProperties = NULL; m_pModelBrowser = NULL; m_bUndoActive = TRUE; m_bShellSessionActive = false; m_pFaceEditSheet = NULL; m_bMinimized = false; m_pSearchReplaceDlg = NULL; m_pLightingPreviewOutputWindow = NULL; m_bLightingPreviewOutputWindowShowing = false; } //----------------------------------------------------------------------------- // Purpose: Destructor. //----------------------------------------------------------------------------- CMainFrame::~CMainFrame(void) { delete pObjectProperties; delete pTextureBrowser; delete m_pFaceEditSheet; delete m_pSearchReplaceDlg; delete m_pLightingPreviewOutputWindow; delete m_pModelBrowser; g_pMainWnd = NULL; CPrefabLibrary::FreeAllLibraries(); } //----------------------------------------------------------------------------- // Purpose: Called through the shell to begin a session of editing the map // via the shell. The user interface is disabled to prevent a mismatched // versions between Hammer and the shell client. //----------------------------------------------------------------------------- void CMainFrame::BeginShellSession(void) { m_bShellSessionActive = true; } //----------------------------------------------------------------------------- // Purpose: Called through the shell to end a session of editing the map // via the engine. The user interface is enabled. //----------------------------------------------------------------------------- void CMainFrame::EndShellSession(void) { m_bShellSessionActive = false; } //----------------------------------------------------------------------------- // Purpose: If we get here there is no active 3D view. Uncheck the button. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateView3d(CCmdUI *pCmdUI) { pCmdUI->SetCheck(FALSE); } //----------------------------------------------------------------------------- // Purpose: If we get here there is no active 3D view. Uncheck the button. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateOpaqueMaterials(CCmdUI *pCmdUI) { pCmdUI->SetCheck(MaterialSystemConfig().bNoTransparency); } void CMainFrame::OnOpaqueMaterials() { MaterialSystemConfig().bNoTransparency = !MaterialSystemConfig().bNoTransparency; MaterialSystemInterface()->OverrideConfig( MaterialSystemConfig(), false ); } //----------------------------------------------------------------------------- // Purpose: If we get here there is no active 2D view. Uncheck the button. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateView2d(CCmdUI *pCmdUI) { pCmdUI->SetCheck(FALSE); } void CMainFrame::OnEnterMenuLoop( BOOL bIsTrackPopupMenu ) { CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); // if we are translation objects with a tool right now, dont switch to Menu mode if ( pDoc ) { CBaseTool *pTool = pDoc->GetTools()->GetActiveTool(); if ( pTool && pTool->IsTranslating() ) { SendMessage( WM_CANCELMODE ); } } } //----------------------------------------------------------------------------- // Purpose: // Input : lpCreateStruct - // Output : //----------------------------------------------------------------------------- int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { const DWORD dwDefStyles = WS_CHILD | WS_VISIBLE | CBRS_TOP; lpCreateStruct->lpszClass = "VALVEWORLDCRAFT"; if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!wndMDIClient.SubclassWindow(m_hWndMDIClient)) { TRACE ("Failed to subclass MDI client window\n"); return (-1); } // // Map view toolbar. // if (!m_wndMapToolBar.Create(this, dwDefStyles, IDCB_MAPVIEWBAR) || !m_wndMapToolBar.LoadToolBar(IDR_MAPDOC_VALVE)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } m_wndMapToolBar.ModifyStyle(0, TBSTYLE_FLAT); // // Undo redo toolbar. // if (!m_wndUndoRedoToolBar.Create(this, dwDefStyles, IDCB_UNDO_REDO_BAR) || !m_wndUndoRedoToolBar.LoadToolBar(IDR_UNDOREDO)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } m_wndUndoRedoToolBar.ModifyStyle(0, TBSTYLE_FLAT); // // Map editing toolbar. // m_wndMapEditToolBar.Create(this, dwDefStyles, IDCB_MAPTOOLSBAR); m_wndMapEditToolBar.ModifyStyle(0, TBSTYLE_FLAT); m_wndMapEditToolBar.LoadToolBar(IDR_MAPEDITTOOLS_VALVE); m_bmMapEditTools256.LoadBitmap(IDB_MAPEDITTOOLS_256); m_wndMapEditToolBar.SetBitmap((HBITMAP)m_bmMapEditTools256); // // Map operations toolbar. // if (!m_wndMapOps.Create(this, dwDefStyles, IDCB_MAPOPERATIONS) || !m_wndMapOps.LoadToolBar(IDR_MAPOPERATIONS_VALVE)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } m_wndMapOps.ModifyStyle(0, TBSTYLE_FLAT); // // Status bar. // if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(NULL, NUMSTATUSPANES)) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } for(int i = 0; i < NUMSTATUSPANES; i++) { m_wndStatusBar.SetPaneInfo(paneinfo[i].nIndex, paneinfo[i].nID, paneinfo[i].nStyle, paneinfo[i].cxWidth); } EnableDocking(CBRS_ALIGN_ANY); m_wndMapToolBar.SetBarStyle(m_wndMapToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndUndoRedoToolBar.SetBarStyle(m_wndUndoRedoToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndMapEditToolBar.SetBarStyle(m_wndMapEditToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndMapOps.SetBarStyle(m_wndMapOps.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndMapToolBar.EnableDocking(CBRS_ALIGN_ANY); m_wndUndoRedoToolBar.EnableDocking(CBRS_ALIGN_ANY); m_wndMapEditToolBar.EnableDocking(CBRS_ALIGN_ANY); m_wndMapOps.EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndMapEditToolBar, AFX_IDW_DOCKBAR_LEFT); // top bars DockControlBar(&m_wndMapToolBar, AFX_IDW_DOCKBAR_TOP); DockControlBarLeftOf(&m_wndUndoRedoToolBar, &m_wndMapToolBar ); DockControlBarLeftOf(&m_wndMapOps, &m_wndUndoRedoToolBar); // rightside control bars m_ObjectBar.Create(this); m_ObjectBar.SetBarStyle(m_ObjectBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); m_ObjectBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); DockControlBar(&m_ObjectBar, AFX_IDW_DOCKBAR_RIGHT); m_FilterControl.Create(this); m_FilterControl.SetBarStyle(m_FilterControl.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); m_FilterControl.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); DockControlBarLeftOf(&m_FilterControl, &m_ObjectBar); m_TextureBar.Create(this); m_TextureBar.SetBarStyle(m_TextureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); m_TextureBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); DockControlBarLeftOf(&m_TextureBar, &m_FilterControl); m_ManifestFilterControl.Create(this); m_ManifestFilterControl.SetBarStyle(m_ManifestFilterControl.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); m_ManifestFilterControl.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); DockControlBar(&m_ManifestFilterControl, AFX_IDW_DOCKBAR_RIGHT); m_pFaceEditSheet = new CFaceEditSheet( "Face Edit Sheet", this ); m_pFaceEditSheet->Setup(); m_pFaceEditSheet->Create( this ); m_pFaceEditSheet->SetVisibility( false ); m_pLightingPreviewOutputWindow = NULL; // // Create the animation dialog bar. // //m_AnimationDlg.Create(this); //m_AnimationDlg.SetBarStyle(m_TextureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); //m_AnimationDlg.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); //DockControlBarLeftOf(&m_AnimationDlg, &m_TextureBar); // // Create the selection mode dialog bar. // m_SelectModeDlg.Create(this); m_SelectModeDlg.SetBarStyle(m_TextureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED); m_SelectModeDlg.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); DockControlBarLeftOf(&m_SelectModeDlg, &m_TextureBar); // // Create object properties sheet - not visible yet. // pObjectProperties = new CObjectProperties; pObjectProperties->SetupPages(); CWnd *pPropertiesParent = this; if ( APP()->IsFoundryMode() ) pPropertiesParent = NULL; pObjectProperties->Create(pPropertiesParent, WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_THICKFRAME); g_pMainWnd = this; // // Create the smoothing group visualization dialog. // m_SmoothingGroupDlg.Create( IDD_SMOOTHING_GROUP_VISUAL, this ); // // Create message window. // CRect clientrect; wndMDIClient.GetClientRect(clientrect); g_pwndMessage->CreateMessageWindow( this, CRect( 0, clientrect.Height() - 90, clientrect.Width(), clientrect.Height() ) ); CPrefabLibrary::LoadAllLibraries(); ToolManager()->SetTool(TOOL_POINTER); pTextureBrowser = new CTextureBrowser(this); // HACK: Spackle up the maximized window position to (0, 0) to fix an intermittent bug. =( WINDOWPLACEMENT wp; ZeroMemory(&wp, sizeof(wp)); wp.length = sizeof(wp); SetWindowPlacement(&wp); // // !!!NOTE: Always do this last to ensure that the layout does not get recalculated before the // window is maximized. This prevents control bars from being incorrectly wrapped to // the next column. // if (VerifyBarState()) { LoadBarState("Barstate"); } return 0; } void CMainFrame::DockControlBarLeftOf(CControlBar* Bar, CControlBar* LeftOf) { CRect rect; DWORD dw; UINT n; // get MFC to adjust the dimensions of all docked ToolBars // so that GetWindowRect will be accurate RecalcLayout(); LeftOf->GetWindowRect(&rect); rect.OffsetRect(1,0); dw=LeftOf->GetBarStyle(); n = 0; n = (dw&CBRS_ALIGN_TOP) ? AFX_IDW_DOCKBAR_TOP : n; n = (dw&CBRS_ALIGN_BOTTOM && n==0) ? AFX_IDW_DOCKBAR_BOTTOM : n; n = (dw&CBRS_ALIGN_LEFT && n==0) ? AFX_IDW_DOCKBAR_LEFT : n; n = (dw&CBRS_ALIGN_RIGHT && n==0) ? AFX_IDW_DOCKBAR_RIGHT : n; // When we take the default parameters on rect, DockControlBar will dock // each Toolbar on a seperate line. By calculating a rectangle, we in effect // are simulating a Toolbar being dragged to that location and docked. DockControlBar(Bar,n,&rect); } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_MAXIMIZE; cs.lpszClass = "VALVEWORLDCRAFT"; return CMDIFrameWnd::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics #ifdef _DEBUG void CMainFrame::AssertValid() const { CMDIFrameWnd::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CMDIFrameWnd::Dump(dc); } #endif //_DEBUG //----------------------------------------------------------------------------- // Purpose: Maps menu IDs to tool IDs. // Input : uMsg - Menu ID from a WM_COMMAND message. //----------------------------------------------------------------------------- static ToolID_t _ToolMsgToEnum(UINT uMsg) { struct ToolIDMap_t { UINT uMsg; ToolID_t eToolID; }; ToolIDMap_t nIDMap[] = { { ID_TOOLS_POINTER, TOOL_POINTER }, { ID_TOOLS_BLOCK, TOOL_BLOCK }, { ID_TOOLS_ENTITY, TOOL_ENTITY }, { ID_TOOLS_CAMERA, TOOL_CAMERA }, { ID_TOOLS_MAGNIFY, TOOL_MAGNIFY }, { ID_TOOLS_MORPH, TOOL_MORPH }, { ID_TOOLS_CLIPPER, TOOL_CLIPPER }, { ID_TOOLS_EDITCORDON, TOOL_EDITCORDON }, { ID_TOOLS_OVERLAY, TOOL_OVERLAY }, { ID_TOOLS_APPLYDECALS, TOOL_DECAL }, { ID_MODE_APPLICATOR, TOOL_FACEEDIT_MATERIAL }, }; for (int i = 0; i < sizeof(nIDMap) / sizeof(nIDMap[0]); i++) { if (uMsg == nIDMap[i].uMsg) { return nIDMap[i].eToolID; } } return TOOL_POINTER; } class CToolHandler_Disabled : public IToolHandlerInfo { public: virtual BOOL UpdateCmdUI( CCmdUI *pCmdUI ); virtual BOOL Execute( UINT uMsg ); } g_ToolHandlerDisabled; BOOL CToolHandler_Disabled::UpdateCmdUI( CCmdUI *pCmdUI ) { pCmdUI->Enable( FALSE ); pCmdUI->SetCheck( FALSE ); return TRUE; } BOOL CToolHandler_Disabled::Execute( UINT uMsg ) { uMsg; return TRUE; } IToolHandlerInfo * _ToolToHanderInfo(UINT uMsg) { extern IToolHandlerInfo *g_pToolHandlerSyncMesh; switch ( uMsg ) { case ID_TOOLS_SYNC_MESH: return g_pToolHandlerSyncMesh; default: return NULL; // return &g_ToolHandlerDisabled to make a control look disabled } } //----------------------------------------------------------------------------- // Purpose: activates the current tool toolbar button // Input : pUI - interface to button that has had a action happen //----------------------------------------------------------------------------- void CMainFrame::OnUpdateToolUI(CCmdUI *pUI) { if (IsShellSessionActive()) { pUI->Enable(FALSE); } else { // // check for button enabling // CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); bool bIsEditable = ( pDoc ? pDoc->IsSelectionEditable() : false ); if ( pUI->m_nID == ID_TOOLS_APPLYDECALS || pUI->m_nID == ID_TOOLS_OVERLAY || pUI->m_nID == ID_TOOLS_CLIPPER || pUI->m_nID == ID_TOOLS_MORPH ) { } else { bIsEditable = ( pDoc ? true : false ); } #if 0 // // Only enable the displacement toolbar button while editing HalfLife 2 maps. // if ( pUI->m_nID == ID_TOOLS_DISPLACE ) { if ( pDoc != NULL ) { pUI->Enable(pDoc->GetMapFormat() == mfHalfLife2); } else { pUI->Enable( pDoc != NULL ); } } else #endif { pUI->Enable( bIsEditable ); } // Obtain custom tool handler IToolHandlerInfo *pHandlerInfo = _ToolToHanderInfo( pUI->m_nID ); BOOL bHandled = pHandlerInfo ? pHandlerInfo->UpdateCmdUI( pUI ) : FALSE; // Use default handler if custom tool handler didn't work if ( !bHandled ) { ToolID_t eToolID = _ToolMsgToEnum(pUI->m_nID); pUI->Enable(bIsEditable); pUI->SetCheck(eToolID == ToolManager()->GetActiveToolID()); } } } //----------------------------------------------------------------------------- // Purpose: Handles toolbar and menu messages that change the active tool. // Input : nMessageID - the id of the menu item // Output : Returns TRUE to indicate that the message was handled. //----------------------------------------------------------------------------- BOOL CMainFrame::OnChangeTool(UINT nMessageID) { // // Changing tool -- exit face edit mode if necessary. // This is here because face edit mode encompasses two tools: the // material tool and the displacement tool. Which tool we use is set // by the OnSetActive handler of each page of the face edit sheet. // if (IsInFaceEditMode()) { EnableFaceEditMode(false); } // Obtain custom tool handler IToolHandlerInfo *pHandlerInfo = _ToolToHanderInfo( nMessageID ); BOOL bHandled = pHandlerInfo ? pHandlerInfo->Execute( nMessageID ) : FALSE; if ( !bHandled ) { // // Activate the new tool. // ToolID_t eToolID = _ToolMsgToEnum(nMessageID); ToolManager()->SetTool(eToolID); } return TRUE; } //----------------------------------------------------------------------------- // Purpose: Brings up the //----------------------------------------------------------------------------- void CMainFrame::OnViewMessages(void) { g_pwndMessage->ToggleMessageWindow(); } //----------------------------------------------------------------------------- // Purpose: Manages the state of the view messages menu item. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateViewMessages(CCmdUI *pCmdUI) { pCmdUI->SetCheck( g_pwndMessage->IsVisible() ); } //----------------------------------------------------------------------------- // Purpose: Brings up the Object Properties dialog. //----------------------------------------------------------------------------- void CMainFrame::OnEditProperties(void) { pObjectProperties->ShowWindow(pObjectProperties->IsWindowVisible() ? SW_HIDE : SW_SHOW); } //----------------------------------------------------------------------------- // Purpose: Tell all the documents to redraw all their views. //----------------------------------------------------------------------------- void CMainFrame::UpdateAllDocViews(DWORD dwCmd) { for ( int i=0; iGetGame() != NULL) { pDoc->UpdateAllViews( dwCmd ); } } if (dwCmd & MAPVIEW_UPDATE_VISGROUP_ALL) { // This updates everything, so it takes priority. m_FilterControl.UpdateGroupList(); } else if (dwCmd & MAPVIEW_UPDATE_VISGROUP_STATE) { // Only update the hidden/shown state of the visgroups. m_FilterControl.UpdateGroupListChecks(); } } //----------------------------------------------------------------------------- // Purpose: Informs our application object when we are activated or deactivated. // Input : bActive - TRUE to activate, FALSE to deactivate. // hTask - task becoming active. //----------------------------------------------------------------------------- #if _MSC_VER < 1300 void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask) #else void CMainFrame::OnActivateApp(BOOL bActive, DWORD hTask) #endif { CMDIFrameWnd::OnActivateApp(bActive, hTask); // Had to change this code to not call GetWindowPlacement because for some reason // that prevented Hammer from maximizing properly -- it would leave space on top. // So I cache the minimized state instead, which fixes the problem. Sigh. if (!m_bMinimized) { MaterialSystemInterface()->EvictManagedResources(); APP()->OnActivateApp(bActive == TRUE); } } //----------------------------------------------------------------------------- // Purpose: // Input : nID - // lParam - //----------------------------------------------------------------------------- void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) { CMDIFrameWnd::OnSysCommand(nID, lParam); if (nID == SC_MINIMIZE) { m_bMinimized = true; APP()->OnActivateApp(false); } else if ((nID == SC_MAXIMIZE) || (nID == SC_RESTORE)) { m_bMinimized = false; APP()->OnActivateApp(true); } } //----------------------------------------------------------------------------- // Purpose: Called when the active document is deleted. //----------------------------------------------------------------------------- void CMainFrame::OnDeleteActiveDocument(void) { pObjectProperties->MarkDataDirty(); } //----------------------------------------------------------------------------- // Purpose: Handles resize messages. Resizes any children that depend on our size. // Input : nType - // cx - // cy - //----------------------------------------------------------------------------- void CMainFrame::OnSize(UINT nType, int cx, int cy) { CMDIFrameWnd::OnSize(nType, cx, cy); // // Resize the message window if it exists. // if ( g_pwndMessage != NULL ) { CRect clientrect; wndMDIClient.GetClientRect(clientrect); g_pwndMessage->Resize(CRect(0, clientrect.Height() - 130, clientrect.Width(), clientrect.Height())); } } //----------------------------------------------------------------------------- // Purpose: Returns a pointer to the main frame window. //----------------------------------------------------------------------------- CMainFrame *GetMainWnd(void) { return g_pMainWnd; } //----------------------------------------------------------------------------- // Purpose: // Input : nIndex - // pszText - //----------------------------------------------------------------------------- void SetStatusText(int nIndex, LPCTSTR pszText) { GetMainWnd()->GetStatusBar()->SetPaneText(nIndex, pszText); } //----------------------------------------------------------------------------- // Purpose: Invokes the configuration dialog, saving the options if the user // hits the OK button. //----------------------------------------------------------------------------- void CMainFrame::Configure(void) { COptionProperties dlg("Configure Hammer", NULL, 0); if (dlg.DoModal() == IDOK) { Options.Write( TRUE, TRUE ); } } //----------------------------------------------------------------------------- // Purpose: Invokes the configuration dialog. //----------------------------------------------------------------------------- void CMainFrame::OnToolsOptions(void) { Configure(); } //----------------------------------------------------------------------------- // Purpose: Called when the main frame is closing. Cleans up the dialog bars // and saves the options to the registry. //----------------------------------------------------------------------------- void CMainFrame::OnClose() { // Copied from CFrameWnd::OnClose. We can't call APP()->BeginClosing if they // hit cancel in the Save Modified dialog, and CFrameWnd::OnClose doesn't have // a return code to let us know if we're actually closing. Preposterous. // Note: only queries the active document CDocument *pDocument = GetActiveDocument(); if (pDocument != NULL && !pDocument->CanCloseFrame(this)) { // document can't close right now -- don't close it return; } // // Save the splitter configuration of the first child window in our list. // CChildFrame *pChild = GetNextMDIChildWnd(NULL); if (pChild != NULL) { pChild->SaveOptions(); } CWinApp *pApp = AfxGetApp(); if (pApp != NULL && pApp->m_pMainWnd == this) { // attempt to save all documents if (pDocument == NULL && !pApp->SaveAllModified()) { // don't close it return; } pApp->CloseAllDocuments( FALSE ); } // End of copied stuff. APP()->BeginClosing(); // want to save the faceeditor as hidden ShowFaceEditSheetOrTextureBar( false ); SaveBarState("Barstate"); //AfxGetApp()->WriteProfileInt("General", "NewBars", TRUE); // Remove the smoothing group dialog window. m_SmoothingGroupDlg.DestroyWindow(); // save options Options.general.bClosedCorrectly = TRUE; Options.Write( TRUE, TRUE ); CMDIFrameWnd::OnClose(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CMainFrame::OnDestroy(void) { CMDIFrameWnd::OnDestroy(); PostQuitMessage(-1); } //----------------------------------------------------------------------------- // Purpose: Sets a timer for destroying the splash screen. //----------------------------------------------------------------------------- void CMainFrame::OnPaint(void) { static bool bFirst = true; CPaintDC dc(this); // device context for painting if (bFirst) { bFirst = false; SetTimer(FIRST_TIMER, 500, NULL); } } //----------------------------------------------------------------------------- // Purpose: This is called ONCE when the splash wnd is to be destroyed. OnPaint() // sets the timer. This is now also called for the autosave timer. // Input : nIDEvent - //----------------------------------------------------------------------------- void CMainFrame::OnTimer(UINT nIDEvent) { if (!::IsWindow(m_hWnd)) { return; } if( nIDEvent == AUTOSAVE_TIMER ) { APP()->Autosave(); } if( nIDEvent == FIRST_TIMER ) //for the splash scren window destruction { // only want it once KillTimer(nIDEvent); // Don't continue if Hammer isn't configured yet! if (Options.configs.nConfigs == 0) return; Options.SetClosedCorrectly( FALSE ); SetBrightness(Options.textures.fBrightness); // repaint texture window m_TextureBar.Invalidate(); //when hammer is ready, start the autosave timer. if ( Options.general.iMaxAutosavesPerMap != 0 ) { SetTimer( AUTOSAVE_TIMER, Options.general.iTimeBetweenSaves * 60 * 1000, NULL ); } } } //----------------------------------------------------------------------------- // Purpose: Called when timer value is changed in the options // Input : void //----------------------------------------------------------------------------- void CMainFrame::ResetAutosaveTimer( void ) { if ( Options.general.iMaxAutosavesPerMap != 0 ) { SetTimer( AUTOSAVE_TIMER, Options.general.iTimeBetweenSaves * 60 * 1000, NULL ); } else { KillTimer( AUTOSAVE_TIMER ); } } //----------------------------------------------------------------------------- // Purpose: // Input : fBrightness - //----------------------------------------------------------------------------- void CMainFrame::SetBrightness(float fBrightness) { if(fBrightness < 0.1f || fBrightness > 5.0f) return; // update options Options.textures.fBrightness = fBrightness; // update display for(int i = 0; i < Options.configs.nConfigs; i++) Options.configs.Configs[i]->Palette.SetBrightness(fBrightness); g_Textures.InformPaletteChanged(); // // if current tool isn't the material tool, then redraw the texture bar // if ( ToolManager()->GetActiveToolID() != TOOL_FACEEDIT_MATERIAL ) { m_TextureBar.RedrawWindow(); } else { m_pFaceEditSheet->RedrawWindow(); } // tell all the documents to redraw 3d views UpdateAllDocViews( MAPVIEW_UPDATE_ONLY_3D | MAPVIEW_UPDATE_COLOR ); } //----------------------------------------------------------------------------- // Purpose: // Input : nID - // Output : Returns TRUE on success, FALSE on failure. //----------------------------------------------------------------------------- BOOL CMainFrame::OnView3dChangeBrightness(UINT nID) { float fBrightness = Options.textures.fBrightness; float fModify = (nID == ID_VIEW3D_BRIGHTER) ? 0.2f : -0.2f; SetBrightness(fBrightness + fModify); return TRUE; } //----------------------------------------------------------------------------- // Purpose: Brings up the sound browser //----------------------------------------------------------------------------- BOOL CMainFrame::OnSoundBrowser(UINT nID) { CSoundBrowser dlg(""); dlg.DoModal(); return TRUE; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- CModelBrowser *CMainFrame::GetModelBrowser() { delete m_pModelBrowser; m_pModelBrowser = NULL; if (m_pModelBrowser == NULL) { m_pModelBrowser = new CModelBrowser( this ); } return m_pModelBrowser; } //----------------------------------------------------------------------------- // Brings up the model browser. //----------------------------------------------------------------------------- void CMainFrame::OnModelBrowser() { CModelBrowser *pModelBrowser = GetModelBrowser(); pModelBrowser->Show(); CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); CUtlVector usedModels; pDoc->GetUsedModels( usedModels ); pModelBrowser->SetUsedModelList( usedModels ); int nRet = pModelBrowser->DoModal(); pModelBrowser->Hide(); if ( nRet == ID_FIND_ASSET ) { // They hit the Find button in the model browser. Invoke the Entity Report dialog // to find all occurences of the chosen model. char szModelName[1024]; pModelBrowser->GetModelName( szModelName, sizeof( szModelName ) ); EntityReportFilterParms_t filter; filter.FilterByKeyValue( "model", szModelName ); CEntityReportDlg::ShowEntityReport( pDoc, this, &filter ); } } //----------------------------------------------------------------------------- // Purpose: Brings up the sound browser //----------------------------------------------------------------------------- BOOL CMainFrame::OnReloadSounds(UINT nID) { for ( int i = 0; i < SOUND_TYPE_COUNT; ++i ) { g_Sounds.BuildSoundList( (SoundType_t)i ); } return TRUE; } //----------------------------------------------------------------------------- // Purpose: Toggles face edit mode, which encompasses two different tools, the // materials editing tool and the displacement editing tool. // // The tool itself is set by the OnSetActive handler for each property // page of the face properties sheet. //----------------------------------------------------------------------------- BOOL CMainFrame::OnApplicator(UINT nID) { bool bNewFaceEditMode = !IsInFaceEditMode(); // // Show/hide face edit sheet/texturebar and update the selection set if need be. // EnableFaceEditMode(bNewFaceEditMode); if (!bNewFaceEditMode) { ToolManager()->SetTool(TOOL_POINTER); } return TRUE; } //----------------------------------------------------------------------------- // Purpose: Enables or disables face edit mode, updating the UI as necessary. // When we are in face edit mode, the texture bar is hidden and the // face edit property sheet is shown. The active tool is changed // to either the material tool or the displacement tool based on which // page in the property sheet is active. //----------------------------------------------------------------------------- void CMainFrame::EnableFaceEditMode(bool bEnable) { CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); if (!pDoc) { return; } ShowFaceEditSheetOrTextureBar(bEnable); pDoc->UpdateForApplicator(bEnable); } //----------------------------------------------------------------------------- // Purpose: Returns true if we are in face edit mode, false if not. //----------------------------------------------------------------------------- bool CMainFrame::IsInFaceEditMode() { if ((ToolManager()->GetActiveToolID() == TOOL_FACEEDIT_MATERIAL) || (ToolManager()->GetActiveToolID() == TOOL_FACEEDIT_DISP)) { return true; } return false; } //----------------------------------------------------------------------------- // Purpose: Manages the state of the texture applicator toobar button and menu item. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateApplicatorUI(CCmdUI *pUI) { if (IsShellSessionActive()) { pUI->Enable(FALSE); } else { pUI->SetCheck(IsInFaceEditMode()); pUI->Enable(CMapDoc::GetActiveMapDoc() ? TRUE : FALSE); } } //----------------------------------------------------------------------------- // Purpose: Invokes the prefab manager dialog. //----------------------------------------------------------------------------- void CMainFrame::OnToolsPrefabfactory(void) { CPrefabsDlg dlg; dlg.DoModal(); CPrefabLibrary::LoadAllLibraries(); m_ObjectBar.UpdateListForTool( ToolManager()->GetActiveToolID()); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CMainFrame::OnHelpFinder(void) { APP()->OpenURL(ID_HELP_TOPICS, GetMainWnd()->GetSafeHwnd()); } //----------------------------------------------------------------------------- // Purpose: // Input : pHelpInfo - // Output : Returns TRUE on success, FALSE on failure. //----------------------------------------------------------------------------- BOOL CMainFrame::OnHelpInfo(HELPINFO *pHelpInfo) { return(Default()); } //----------------------------------------------------------------------------- // Purpose: Opens a URL in the default web browser. //----------------------------------------------------------------------------- void CMainFrame::OpenURL(const char *pszURL) { APP()->OpenURL(pszURL, m_hWnd); } //----------------------------------------------------------------------------- // Purpose: Opens a URL in the default web browser by string ID. //----------------------------------------------------------------------------- void CMainFrame::OpenURL(UINT nID) { APP()->OpenURL(nID, m_hWnd); } //----------------------------------------------------------------------------- // Purpose: Opens the URL that corresponds to the given string ID. This is used // to hook menu items to URLs in the string table. //----------------------------------------------------------------------------- BOOL CMainFrame::OnHelpOpenURL(UINT nID) { OpenURL(nID); return TRUE; } //----------------------------------------------------------------------------- // Purpose: Activates or deactivates Undo/Redo. //----------------------------------------------------------------------------- void CMainFrame::SetUndoActive(BOOL bActive) { m_bUndoActive = bActive; CMapDoc::GetActiveMapDoc()->SetUndoActive(bActive == TRUE); } //----------------------------------------------------------------------------- // Purpose: Toggles the active state of Undo/Redo. //----------------------------------------------------------------------------- void CMainFrame::OnEditUndoredoactive(void) { SetUndoActive(!m_bUndoActive); } //----------------------------------------------------------------------------- // Purpose: Manages the state of the Enable/Disable Undo/Redo menu item. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateEditUndoredoactive(CCmdUI *pCmdUI) { pCmdUI->Enable(IsShellSessionActive() ? FALSE : TRUE); pCmdUI->SetText(m_bUndoActive ? "Disable Undo/Redo" : "Enable Undo/Redo"); } //----------------------------------------------------------------------------- // Purpose: // Input : nCode - //----------------------------------------------------------------------------- void CMainFrame::GlobalNotify(int nCode) { CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); switch (nCode) { // // Active document changed. Update visgroup lists. // case WM_MAPDOC_CHANGED: { // // Update the visgroups & cordons. // m_FilterControl.UpdateGroupList(); m_FilterControl.UpdateCordonList(); // // If the Object Properties dialog has a Groups tab, update // the groups tab. // if (pObjectProperties != NULL) { pObjectProperties->UpdateGrouplist(); } if (pDoc != NULL) { pDoc->UpdateStatusbar(); //m_AnimationDlg.SelectionChanged(*pDoc->Selection_GetList()); } m_ManifestFilterControl.UpdateManifestList(); break; } // // Game configuration changed. Update texture and entity lists. // case WM_GAME_CHANGED: { pTextureBrowser->SetTextureFormat(g_pGameConfig->GetTextureFormat()); m_TextureBar.NotifyGraphicsChanged(); m_pFaceEditSheet->NotifyGraphicsChanged(); if (pDoc != NULL) m_ObjectBar.UpdateListForTool( pDoc->GetTools()->GetActiveToolID()); break; } // // Lighting preview window closed // case LPRV_WINDOWCLOSED: { m_bLightingPreviewOutputWindowShowing = false; break; } } } //----------------------------------------------------------------------------- // Purpose: // Input : UINT - // Output : Returns TRUE on success, FALSE on failure. //----------------------------------------------------------------------------- BOOL CMainFrame::OnFileNew(UINT) { return FALSE; CNewDocType dlg; dlg.m_iNewType = 0; if(dlg.DoModal() != IDOK) return TRUE; return FALSE; } //----------------------------------------------------------------------------- // Purpose: Saves the position and types of all 2D and 3D views in the active document. // dvs: This really needs to be a text file instead of a binary file! // Input : *pFile - //----------------------------------------------------------------------------- void CMainFrame::SaveWindowStates(std::fstream *pFile) { char szRootDir[MAX_PATH]; char szFullPath[MAX_PATH]; APP()->GetDirectory(DIR_PROGRAM, szRootDir); Q_MakeAbsolutePath( szFullPath, MAX_PATH, "winstate.wc", szRootDir ); std::fstream file(szFullPath, std::ios::out | std::ios::binary); CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); if (pDoc == NULL) { return; } file.write(WINSTATETAG, sizeof WINSTATETAG); file.write((char*) &fVersion, sizeof fVersion); CRect rectClient; ::GetClientRect(m_hWndMDIClient, &rectClient); // write out each view POSITION p = pDoc->GetFirstViewPosition(); while (p != NULL) { CView *pView = pDoc->GetNextView(p); // // Determine what type of view it is. // int iDrawType; if (pView->IsKindOf(RUNTIME_CLASS(CMapView2D))) { file.write((char*) &WINSTATE2DVIEW, sizeof WINSTATE2DVIEW); iDrawType = (int)((CMapView2D*)pView)->GetDrawType(); } else if (pView->IsKindOf(RUNTIME_CLASS(CMapView3D))) { file.write((char*) &WINSTATE3DVIEW, sizeof WINSTATE3DVIEW); iDrawType = (int)((CMapView3D*)pView)->GetDrawType(); } else if (pView->IsKindOf(RUNTIME_CLASS(CMapViewLogical))) { file.write((char*) &WINSTATELOGICALVIEW, sizeof WINSTATELOGICALVIEW); iDrawType = (int)((CMapViewLogical*)pView)->GetDrawType(); } else { // // It's a view type whose state we do not save - skip it. // continue; } // // Write view's draw type. // file.write((char*) &iDrawType, sizeof iDrawType); // // Write position of view. // CRect rectView; pView->GetParentFrame()->GetWindowRect(&rectView); CPoint pt1 = rectView.TopLeft(), pt2 = rectView.BottomRight(); ::ScreenToClient(m_hWndMDIClient, &pt1); ::ScreenToClient(m_hWndMDIClient, &pt2); double left, top, right, bottom; left = double(pt1.x) / double(rectClient.right); top = double(pt1.y) / double(rectClient.bottom); right = double(pt2.x) / double(rectClient.right); bottom = double(pt2.y) / double(rectClient.bottom); file.write((char*) &left, sizeof left); file.write((char*) &top, sizeof top); file.write((char*) &right, sizeof right); file.write((char*) &bottom, sizeof bottom); } file.write((char *)&WINSTATEEND, sizeof WINSTATEEND); } //----------------------------------------------------------------------------- // Purpose: // Input : pFile - //----------------------------------------------------------------------------- void CMainFrame::LoadWindowStates(std::fstream *pFile) { char szRootDir[MAX_PATH]; char szFullPath[MAX_PATH]; APP()->GetDirectory(DIR_PROGRAM, szRootDir); Q_MakeAbsolutePath( szFullPath, MAX_PATH, "winstate.wc", szRootDir ); std::fstream file( szFullPath, std::ios::in | std::ios::binary ); if (!file.is_open()) { return; } char tag[sizeof(WINSTATETAG)]; file.read(tag, sizeof tag); if(memcmp(tag, WINSTATETAG, sizeof tag)) { file.seekg(-int(sizeof(tag))); return; } float fThisVersion; file.read((char*) &fThisVersion, sizeof fThisVersion); CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); if(!pDoc) return; // get client rect of MDI CHILD for relative positioning information CRect rectClient; ::GetClientRect(m_hWndMDIClient, &rectClient); // keep list of views we've already modified, so if there // are other views, we have to create them. this prevents // us from having to delete all views and start over, // which is a slower process than simply moving existing // views. CTypedPtrList UsedViews; SetDefaultChildType(FALSE); while (1) { int iViewType; file.read((char *)&iViewType, sizeof iViewType); if ((file.eof()) || (iViewType == WINSTATEEND)) { break; } int iDrawType; file.read((char *)&iDrawType, sizeof iDrawType); CView *pView = NULL; // find a view we haven't used POSITION p = pDoc->GetFirstViewPosition(); while (p != NULL) { CView *pThisView = pDoc->GetNextView(p); // already used? if (UsedViews.Find(pThisView)) continue; // make sure it's the right type .. if (iViewType == WINSTATE2DVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapView2D))) continue; if (iViewType == WINSTATELOGICALVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapViewLogical))) continue; if (iViewType == WINSTATE3DVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapView3D))) continue; // yes! so modify this one. pView = pThisView; UsedViews.AddTail(pView); break; } CChildFrame *pFrame = NULL; BOOL bNew = FALSE; CDocTemplate *pTemplate = NULL; if(!pView) { // if no view was created, we have to create a new one. CMDIChildWnd* pActiveChild = MDIGetActive(); pTemplate = pDoc->GetDocTemplate(); pFrame = (CChildFrame*) pTemplate->CreateNewFrame(pDoc, pActiveChild); pFrame->SetRedraw(FALSE); pTemplate->InitialUpdateFrame(pFrame, pDoc, FALSE); // find view in new frame pView = pFrame->GetActiveView(); UsedViews.AddTail(pView); bNew = TRUE; } else { // find frame based on this view pFrame = (CChildFrame*) pView->GetParentFrame(); if(pFrame->bUsingSplitter) pFrame->SetSplitterMode(FALSE); } // no redraws right now, please. pFrame->SetRedraw(FALSE); if (iViewType == WINSTATE3DVIEW) { // // Handle import of old WinState files before draw types were consolidated // into a single enumeration. // if ((iDrawType >= VIEW2D_XY) && (iDrawType <= VIEW2D_XZ)) { iDrawType += 3; } pFrame->SetViewType((DrawType_t)iDrawType); } else if (iViewType == WINSTATE2DVIEW) { pFrame->SetViewType((DrawType_t)iDrawType); } else if (iViewType == WINSTATELOGICALVIEW) { pFrame->SetViewType( (DrawType_t)iDrawType ); } // read positioning info double left, top, right, bottom; file.read((char*) &left, sizeof left); file.read((char*) &top, sizeof top); file.read((char*) &right, sizeof right); file.read((char*) &bottom, sizeof bottom); CRect r; r.left = int(left * double(rectClient.right)); r.top = int(top * double(rectClient.bottom)); r.right = int(right * double(rectClient.right)); r.bottom = int(bottom * double(rectClient.bottom)); // Set the frame's position. pFrame->MoveWindow(&r, FALSE); // Call OnInitialUpdate before any rendering takes place. if (bNew) { pTemplate->InitialUpdateFrame(pFrame, pDoc, TRUE); } // Enable WM_PAINT messages for the frame window. pFrame->SetRedraw(TRUE); // Update the window. pFrame->Invalidate(); pFrame->UpdateWindow(); } Invalidate(); UpdateWindow(); } void CMainFrame::OnInitMenu( CMenu *pMenu ) { } void CMainFrame::OnHDR( void ) { CMenu *pMenu= GetMenu(); UINT state = pMenu->GetMenuState(ID_HDR, MF_BYCOMMAND); if (state & MF_CHECKED) { pMenu->CheckMenuItem(ID_HDR, MF_UNCHECKED | MF_BYCOMMAND); g_bHDR = false; } else { pMenu->CheckMenuItem(ID_HDR, MF_CHECKED | MF_BYCOMMAND); g_bHDR = true; } DrawMenuBar(); SignalUpdate( EVTYPE_LIGHTING_CHANGED ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CMainFrame::OnSavewindowstate(void) { SaveWindowStates(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CMainFrame::OnLoadwindowstate(void) { LoadWindowStates(); } //----------------------------------------------------------------------------- // Purpose: Changes the format of the units displayed in the status bar. // Input : nID - Menu ID corresponding to a units format. //----------------------------------------------------------------------------- BOOL CMainFrame::OnUnits(UINT nID) { switch (nID) { case ID_MAP_UNITS_NONE: { Box3D::SetWorldUnits(Units_None); break; } case ID_MAP_UNITS_INCHES: { Box3D::SetWorldUnits(Units_Inches); break; } case ID_MAP_UNITS_FEET_INCHES: { Box3D::SetWorldUnits(Units_Feet_Inches); break; } } CMapDoc::GetActiveMapDoc()->UpdateStatusbar(); return TRUE; } //----------------------------------------------------------------------------- // Purpose: Manages the state of decal application toolbar button. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateUnits(CCmdUI *pCmdUI) { pCmdUI->Enable(!IsShellSessionActive()); if (pCmdUI->m_nID == ID_MAP_UNITS_NONE) { pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_None); } else if (pCmdUI->m_nID == ID_MAP_UNITS_INCHES) { pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_Inches); } else if (pCmdUI->m_nID == ID_MAP_UNITS_FEET_INCHES) { pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_Feet_Inches); } } //----------------------------------------------------------------------------- // Purpose: // Input : pMsg - // Output : Returns TRUE on success, FALSE on failure. //----------------------------------------------------------------------------- BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { // // See if the message is a keydown and the current focus window is the // ComboBox in the ObjectBar! // /* if (pMsg->message == WM_KEYDOWN) { if ((GetFocus() == &m_ObjectBar) || (GetFocus() == &this->m_FilterControl)) { AfxMessageBox("Ok"); return(TRUE); } } */ return(CMDIFrameWnd::PreTranslateMessage(pMsg)); } //----------------------------------------------------------------------------- // Purpose: Finds the next CChildFrame in the list of MDI child windows. // Input : pCurChild - Child to search from. //----------------------------------------------------------------------------- CChildFrame *CMainFrame::GetNextMDIChildWnd(CChildFrame *pCurChild) { return GetNextMDIChildWndRecursive(pCurChild); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CChildFrame *CMainFrame::GetNextMDIChildWndRecursive(CWnd *pCurChild) { CWnd *pNextChild = NULL; if (pCurChild == NULL) { // Get the first child window. pNextChild = wndMDIClient.GetWindow(GW_CHILD); } else { // Get the next child window in the list. pNextChild = pCurChild->GetWindow(GW_HWNDNEXT); if (!pNextChild) { // No child windows exist in the MDIClient, // or you are at the end of the list. This check // will terminate any recursion. return NULL; } } // Check the kind of window if (!pNextChild->GetWindow(GW_OWNER)) { if (pNextChild->IsKindOf(RUNTIME_CLASS(CChildFrame))) { return (CChildFrame *)pNextChild; } } // Not one we are interested in. Try the next one. // Recurse over the window manager's list of windows. return GetNextMDIChildWndRecursive(pNextChild); } //----------------------------------------------------------------------------- // Purpose: Returns true if we are currently editing via the engine, false if not. //----------------------------------------------------------------------------- bool CMainFrame::IsShellSessionActive(void) { return(m_bShellSessionActive); } //----------------------------------------------------------------------------- // Purpose: Manages the state of all Edit menu items and toolbar buttons. //----------------------------------------------------------------------------- void CMainFrame::OnUpdateEditFunction(CCmdUI *pCmdUI) { pCmdUI->Enable(!IsShellSessionActive()); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CMainFrame::ShowFaceEditSheetOrTextureBar( bool bShowFaceEditSheet ) { if( bShowFaceEditSheet ) { m_pFaceEditSheet->SetVisibility( true ); ShowControlBar( &m_TextureBar, FALSE, TRUE ); } else { m_pFaceEditSheet->SetVisibility( false ); m_pFaceEditSheet->CloseAllPageDialogs(); ShowControlBar( &m_TextureBar, TRUE, TRUE ); } } //----------------------------------------------------------------------------- // Purpose: Displays the search/replace dialog. It will be hide itself when the // user closes it. //----------------------------------------------------------------------------- void CMainFrame::ShowSearchReplaceDialog(void) { if (m_pSearchReplaceDlg == NULL) { m_pSearchReplaceDlg = new CSearchReplaceDlg; m_pSearchReplaceDlg->Create(this); } m_pSearchReplaceDlg->ShowWindow(SW_SHOW); m_pSearchReplaceDlg->SetFocus(); } //----------------------------------------------------------------------------- // Purpose: Code found on codeproject.com. // // Makes sure we don't have bogus dialog bar information in the registry. // This prevents a crash in the MFC code if a version of the editor with // different toolbars was run before us. // // TODO: fix the registry settings if they are bad so we can still load the bar state // // Output : Returns true if it is safe to load the toolbar settings, false if not. //----------------------------------------------------------------------------- bool CMainFrame::VerifyBarState(void) { CDockState state; state.LoadState("BarState"); for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++) { CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i]; Assert(pInfo != NULL); int nDockedCount = pInfo->m_arrBarID.GetSize(); if (nDockedCount > 0) { for (int j = 0; j < nDockedCount; j++) { UINT nID = (UINT) pInfo->m_arrBarID[j]; if (nID == 0) { continue; // row separator } if (nID > 0xFFFF) { nID &= 0xFFFF; // placeholder - get the ID } if (GetControlBar(nID) == NULL) { return false; } } } if (!pInfo->m_bFloating) // floating dockbars can be created later { if (GetControlBar(pInfo->m_nBarID) == NULL) { return false; // invalid bar ID } } } return true; } //----------------------------------------------------------------------------- // Purpose: // Input : dwData - // nCmd - //----------------------------------------------------------------------------- void CMainFrame::WinHelp(DWORD dwData, UINT nCmd) { // dvs: HACK: just punt them to the main help page APP()->OpenURL(ID_HELP_TOPICS, m_hWnd); } void CMainFrame::OnUpdateFoundrySendSelectedEntitiesToEngine( CCmdUI *pCmdUI ) { pCmdUI->Enable( true ); } void CMainFrame::OnFoundrySendSelectedEntitiesToEngine() { if ( !g_pFoundryTool ) return; g_pFoundryTool->ConsoleCommand( "foundry_send_ents_to_engine" ); } void CMainFrame::OnUpdateFoundryMoveEngineViewToHammer3DView( CCmdUI *pCmdUI ) { // TODO: This should only be on if Foundry is around. pCmdUI->Enable( true ); } void CMainFrame::OnFoundryMoveEngineViewToHammer3DView() { if ( !g_pFoundryTool ) return; g_pFoundryTool->ConsoleCommand( "foundry_sync_engine_view" ); } void CMainFrame::OnUpdateFoundryRemoveSelectedEntitiesFromEngine( CCmdUI *pCmdUI ) { pCmdUI->Enable( true ); } void CMainFrame::OnFoundryRemoveSelectedEntitiesFromEngine() { if ( !g_pFoundryTool ) return; g_pFoundryTool->ConsoleCommand( "foundry_remove_selected" ); } void CMainFrame::OnUpdateFoundryMoveFocusToEngine( CCmdUI *pCmdUI ) { pCmdUI->Enable( true ); } void CMainFrame::OnFoundryMoveFocusToEngine() { if ( !g_pFoundryTool ) return; g_pFoundryTool->ConsoleCommand( "foundry_move_focus_to_engine" ); } LRESULT CMainFrame::OnWTPacket(WPARAM wSerial, LPARAM hCtx) { WinTab_Packet( wSerial, hCtx ); return TRUE; }