| 1 | /* |
|---|
| 2 | ================================================================================= |
|---|
| 3 | This file is part of Cafu, the open-source game engine and graphics engine |
|---|
| 4 | for multiplayer, cross-platform, real-time 3D action. |
|---|
| 5 | Copyright (C) 2002-2012 Carsten Fuchs Software. |
|---|
| 6 | |
|---|
| 7 | Cafu is free software: you can redistribute it and/or modify it under the terms |
|---|
| 8 | of the GNU General Public License as published by the Free Software Foundation, |
|---|
| 9 | either version 3 of the License, or (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|---|
| 12 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|---|
| 13 | PURPOSE. See the GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with Cafu. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | |
|---|
| 18 | For support and more information about Cafu, visit us at <http://www.cafu.de>. |
|---|
| 19 | ================================================================================= |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #include "ChildFrame.hpp" |
|---|
| 23 | #include "ChildFrameViewWin2D.hpp" |
|---|
| 24 | #include "ChildFrameViewWin3D.hpp" |
|---|
| 25 | #include "Camera.hpp" |
|---|
| 26 | #include "DialogConsole.hpp" |
|---|
| 27 | #include "DialogCustomCompile.hpp" |
|---|
| 28 | #include "DialogEditSurfaceProps.hpp" |
|---|
| 29 | #include "DialogInspector.hpp" |
|---|
| 30 | #include "DialogTerrainEdit.hpp" |
|---|
| 31 | #include "GameConfig.hpp" |
|---|
| 32 | #include "MapDocument.hpp" |
|---|
| 33 | #include "Options.hpp" |
|---|
| 34 | #include "ParentFrame.hpp" |
|---|
| 35 | #include "Tool.hpp" |
|---|
| 36 | #include "ToolbarMaterials.hpp" |
|---|
| 37 | #include "ToolbarGroups.hpp" |
|---|
| 38 | #include "ToolCamera.hpp" |
|---|
| 39 | #include "ToolTerrainEdit.hpp" |
|---|
| 40 | #include "ToolManager.hpp" |
|---|
| 41 | |
|---|
| 42 | #include "wx/wx.h" |
|---|
| 43 | #include "wx/artprov.h" |
|---|
| 44 | #include "wx/aui/auibar.h" |
|---|
| 45 | #include "wx/confbase.h" |
|---|
| 46 | #include "wx/filename.h" |
|---|
| 47 | #include "wx/process.h" |
|---|
| 48 | #include "wx/stdpaths.h" |
|---|
| 49 | |
|---|
| 50 | |
|---|
| 51 | #ifdef __WXMSW__ |
|---|
| 52 | static const wxString CompileScriptName="tempCompileScriptCaWE.bat"; |
|---|
| 53 | #else |
|---|
| 54 | static const wxString CompileScriptName="./tempCompileScriptCaWE.bat"; |
|---|
| 55 | #endif |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | // TODO: |
|---|
| 59 | // 1. Rename: Some toolbars are panels now, some dialogs are panels now... |
|---|
| 60 | // 2. Menu icons... |
|---|
| 61 | // 3. Update the pane captions properly, e.g. "2D view, top (XY), zoom: ...". |
|---|
| 62 | // 4. properly load/save the perspectives, i.e. with the list of open 2D and 3D views. |
|---|
| 63 | // 5. Toolbar toggles for: Texture locking und Options.general.NewUVsFaceAligned. |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | AutoSaveTimerT::AutoSaveTimerT(MapDocumentT* Doc, unsigned long ChildFrameNr) |
|---|
| 67 | : m_Doc(Doc), |
|---|
| 68 | m_AutoSaveName(wxStandardPaths::Get().GetUserDataDir()+"/"+wxString::Format("autosave%lu.cmap", ChildFrameNr)) |
|---|
| 69 | { |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | void AutoSaveTimerT::Notify() |
|---|
| 74 | { |
|---|
| 75 | // Auto-save the document under name m_AutoSaveName, overwriting any existing file. |
|---|
| 76 | if (wxFileExists(m_AutoSaveName)) wxRemoveFile(m_AutoSaveName); |
|---|
| 77 | m_Doc->OnSaveDocument(m_AutoSaveName, true); |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | AutoSaveTimerT::~AutoSaveTimerT() |
|---|
| 82 | { |
|---|
| 83 | // Note that the document is already deleted when we get here! |
|---|
| 84 | |
|---|
| 85 | // On closing the child frame, delete the corresponding auto-saved file, |
|---|
| 86 | // because the user is assumed to save it himself, as is usual when closing CaWE. |
|---|
| 87 | // In fact, we only get here after a successful save or if the user explicitly denied the saving a modified file. |
|---|
| 88 | if (wxFileExists(m_AutoSaveName)) wxRemoveFile(m_AutoSaveName); |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | |
|---|
| 92 | /// A class that acts as an observer of the map document and the tools for the child frame. |
|---|
| 93 | /// It updates the associated child frames status bar, tool options bar, etc. |
|---|
| 94 | /// Note that the child frame could also derive from the observer classes and thus be the observer itself, |
|---|
| 95 | /// but having the functionality encapsulated in a separate class like this increases clarity. |
|---|
| 96 | class ChildFrameT::UpdaterT : public ObserverT, public ToolsObserverT |
|---|
| 97 | { |
|---|
| 98 | public: |
|---|
| 99 | |
|---|
| 100 | UpdaterT(ChildFrameT* ChildFrame); |
|---|
| 101 | ~UpdaterT(); |
|---|
| 102 | |
|---|
| 103 | // Methods inherited from ObserverT. |
|---|
| 104 | void NotifySubjectChanged(SubjectT* Subject, MapDocOtherDetailT OtherDetail); |
|---|
| 105 | void NotifySubjectChanged_Selection(SubjectT* Subject, const ArrayT<MapElementT*>& OldSelection, const ArrayT<MapElementT*>& NewSelection); |
|---|
| 106 | // void NotifySubjectChanged_Created(const ArrayT<MapElementT*>& MapElements); |
|---|
| 107 | // void NotifySubjectChanged_Deleted(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements); |
|---|
| 108 | // void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail); |
|---|
| 109 | // void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const ArrayT<BoundingBox3fT>& OldBounds); |
|---|
| 110 | // void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const wxString& Key); |
|---|
| 111 | void NotifySubjectDies(SubjectT* dyingSubject) { } // The subjects always live longer than this updater (in contrast to the view windows etc.). |
|---|
| 112 | |
|---|
| 113 | // Methods inherited from ToolsObserverT. |
|---|
| 114 | void NotifySubjectChanged(ToolsSubjectT* Subject, ToolT* Tool, ToolsUpdatePriorityT Priority); |
|---|
| 115 | |
|---|
| 116 | |
|---|
| 117 | private: |
|---|
| 118 | |
|---|
| 119 | ChildFrameT* m_ChildFrame; |
|---|
| 120 | ToolT* m_PrevTool; |
|---|
| 121 | }; |
|---|
| 122 | |
|---|
| 123 | |
|---|
| 124 | ChildFrameT::UpdaterT::UpdaterT(ChildFrameT* ChildFrame) |
|---|
| 125 | : m_ChildFrame(ChildFrame), |
|---|
| 126 | m_PrevTool(NULL) |
|---|
| 127 | { |
|---|
| 128 | m_ChildFrame->m_Doc->RegisterObserver(this); |
|---|
| 129 | m_ChildFrame->m_ToolManager->RegisterObserver(this); |
|---|
| 130 | |
|---|
| 131 | // Issue the initial notifications. |
|---|
| 132 | NotifySubjectChanged(m_ChildFrame->m_Doc, UPDATE_GRID); |
|---|
| 133 | NotifySubjectChanged_Selection(m_ChildFrame->m_Doc, m_ChildFrame->m_Doc->GetSelection(), m_ChildFrame->m_Doc->GetSelection()); |
|---|
| 134 | NotifySubjectChanged(m_ChildFrame->m_ToolManager, m_ChildFrame->m_ToolManager->GetActiveTool(), UPDATE_NOW); |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | |
|---|
| 138 | ChildFrameT::UpdaterT::~UpdaterT() |
|---|
| 139 | { |
|---|
| 140 | m_ChildFrame->m_Doc->UnregisterObserver(this); |
|---|
| 141 | m_ChildFrame->m_ToolManager->UnregisterObserver(this); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | |
|---|
| 145 | void ChildFrameT::UpdaterT::NotifySubjectChanged(SubjectT* Subject, MapDocOtherDetailT OtherDetail) |
|---|
| 146 | { |
|---|
| 147 | switch (OtherDetail) |
|---|
| 148 | { |
|---|
| 149 | case UPDATE_GRID: |
|---|
| 150 | m_ChildFrame->SetStatusText(wxString::Format(" Snap: %s Grid: %d ", |
|---|
| 151 | m_ChildFrame->m_Doc->IsSnapEnabled() ? "On" : "Off", m_ChildFrame->m_Doc->GetGridSpacing()), SBP_GRID_SNAP); |
|---|
| 152 | break; |
|---|
| 153 | |
|---|
| 154 | case UPDATE_POINTFILE: |
|---|
| 155 | break; |
|---|
| 156 | |
|---|
| 157 | case UPDATE_GLOBALOPTIONS: |
|---|
| 158 | break; |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | |
|---|
| 163 | void ChildFrameT::UpdaterT::NotifySubjectChanged_Selection(SubjectT* Subject, const ArrayT<MapElementT*>& OldSelection, const ArrayT<MapElementT*>& NewSelection) |
|---|
| 164 | { |
|---|
| 165 | switch (NewSelection.Size()) |
|---|
| 166 | { |
|---|
| 167 | case 0: |
|---|
| 168 | m_ChildFrame->SetStatusText(" Nothing is selected.", SBP_SELECTION); |
|---|
| 169 | break; |
|---|
| 170 | |
|---|
| 171 | case 1: |
|---|
| 172 | m_ChildFrame->SetStatusText(wxString(" ")+NewSelection[0]->GetDescription(), SBP_SELECTION); |
|---|
| 173 | break; |
|---|
| 174 | |
|---|
| 175 | default: |
|---|
| 176 | m_ChildFrame->SetStatusText(wxString::Format(" %lu items are selected.", NewSelection.Size()), SBP_SELECTION); |
|---|
| 177 | break; |
|---|
| 178 | } |
|---|
| 179 | } |
|---|
| 180 | |
|---|
| 181 | |
|---|
| 182 | void ChildFrameT::UpdaterT::NotifySubjectChanged(ToolsSubjectT* Subject, ToolT* Tool, ToolsUpdatePriorityT Priority) |
|---|
| 183 | { |
|---|
| 184 | if (Tool->IsActiveTool()) |
|---|
| 185 | { |
|---|
| 186 | if (Tool!=m_PrevTool) |
|---|
| 187 | { |
|---|
| 188 | const ArrayT<ToolT*>& Tools =m_ChildFrame->m_ToolManager->GetTools(); |
|---|
| 189 | wxWindow* Toolbar=NULL; |
|---|
| 190 | |
|---|
| 191 | // Show the options bar of the active tool, hide everything else. |
|---|
| 192 | for (unsigned long ToolNr=0; ToolNr<Tools.Size(); ToolNr++) |
|---|
| 193 | { |
|---|
| 194 | wxWindow* OptionsBar=Tools[ToolNr]->GetOptionsBar(); |
|---|
| 195 | |
|---|
| 196 | if (!OptionsBar) continue; |
|---|
| 197 | |
|---|
| 198 | OptionsBar->Show(Tools[ToolNr]->IsActiveTool()); |
|---|
| 199 | |
|---|
| 200 | if (!Toolbar) Toolbar=OptionsBar->GetParent(); |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | if (Toolbar) Toolbar->Layout(); |
|---|
| 204 | m_PrevTool=Tool; |
|---|
| 205 | } |
|---|
| 206 | |
|---|
| 207 | // Update the status bar. |
|---|
| 208 | Tool->UpdateStatusBar(m_ChildFrame); |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | |
|---|
| 213 | BEGIN_EVENT_TABLE(ChildFrameT, wxMDIChildFrame) |
|---|
| 214 | EVT_CLOSE(ChildFrameT::OnClose) |
|---|
| 215 | EVT_IDLE(ChildFrameT::OnIdle) |
|---|
| 216 | EVT_END_PROCESS(wxID_ANY, ChildFrameT::OnProcessEnd) |
|---|
| 217 | |
|---|
| 218 | EVT_MENU_RANGE (ID_MENU_FILE_CLOSE, ID_MENU_FILE_SAVEAS, ChildFrameT::OnMenuFile) |
|---|
| 219 | EVT_UPDATE_UI_RANGE(ID_MENU_FILE_CLOSE, ID_MENU_FILE_SAVEAS, ChildFrameT::OnMenuFileUpdate) |
|---|
| 220 | EVT_MENU_RANGE (ID_MENU_EDIT_ENTITY_INSPECTOR, ID_MENU_EDIT_ENTITY_INSPECTOR, ChildFrameT::OnMenuEdit) |
|---|
| 221 | EVT_UPDATE_UI_RANGE(ID_MENU_EDIT_ENTITY_INSPECTOR, ID_MENU_EDIT_ENTITY_INSPECTOR, ChildFrameT::OnMenuEditUpdate) |
|---|
| 222 | EVT_MENU_RANGE (ID_MENU_VIEW_TOOLBARS, ID_MENU_VIEW_CENTER_3D_VIEWS, ChildFrameT::OnMenuView) |
|---|
| 223 | EVT_UPDATE_UI_RANGE(ID_MENU_VIEW_TOOLBARS, ID_MENU_VIEW_CENTER_3D_VIEWS, ChildFrameT::OnMenuViewUpdate) |
|---|
| 224 | EVT_BUTTON (ID_MENU_VIEW_CENTER_2D_VIEWS, ChildFrameT::OnMenuView) |
|---|
| 225 | EVT_MENU_RANGE (ID_MENU_TOOLS_TOOL_SELECTION, ID_MENU_TOOLS_TOOL_EDITVERTICES, ChildFrameT::OnMenuTools) |
|---|
| 226 | EVT_UPDATE_UI_RANGE(ID_MENU_TOOLS_TOOL_SELECTION, ID_MENU_TOOLS_TOOL_EDITVERTICES, ChildFrameT::OnMenuToolsUpdate) |
|---|
| 227 | EVT_MENU_RANGE (ID_MENU_COMPILE_FLAG_SAVE_MAP, ID_MENU_COMPILE_ABORT, ChildFrameT::OnMenuCompile) |
|---|
| 228 | |
|---|
| 229 | EVT_ACTIVATE(ChildFrameT::OnWindowActivate) |
|---|
| 230 | EVT_AUI_PANE_CLOSE(ChildFrameT::OnAuiPaneClose) |
|---|
| 231 | // EVT_SIZE(ChildFrameT::OnSize) |
|---|
| 232 | END_EVENT_TABLE() |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | // About the wxMDIChildFrame constructor: |
|---|
| 236 | // Although the parent should actually be the parent frames MDI *client* (sub-)window, according to wx documentation |
|---|
| 237 | // it is fine to pass the MDI parent window itself (rather than its client window) here. See wxMDIChildFrame documentation. |
|---|
| 238 | // Contrary to wx docs, the wxDocMDIChildFrame even *requires* a pointer to wxMDIParentFrame here (not just to a wxFrame, as the docs say)! |
|---|
| 239 | ChildFrameT::ChildFrameT(ParentFrameT* Parent, const wxString& Title, MapDocumentT* Document) |
|---|
| 240 | : wxMDIChildFrame(Parent, wxID_ANY, Title, wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE | wxMAXIMIZE), |
|---|
| 241 | m_Parent(Parent), // Must use a fixed size in place of wxDefaultSize, see <http://trac.wxwidgets.org/ticket/12490> for details. |
|---|
| 242 | m_AUIManager(this), |
|---|
| 243 | m_AUIDefaultPerspective(""), |
|---|
| 244 | m_Doc(Document), |
|---|
| 245 | m_LastSavedAtCommandNr(0), |
|---|
| 246 | m_AutoSaveTimer(m_Doc, Parent->m_ChildFrames.Size()), |
|---|
| 247 | m_ToolManager(NULL), |
|---|
| 248 | m_MaterialsToolbar(NULL), |
|---|
| 249 | m_GroupsToolbar(NULL), |
|---|
| 250 | m_ConsoleDialog(NULL), |
|---|
| 251 | m_SurfacePropsDialog(NULL), |
|---|
| 252 | m_TerrainEditorDialog(NULL), |
|---|
| 253 | m_Updater(NULL), |
|---|
| 254 | FileMenu(NULL), |
|---|
| 255 | CompileMenu(NULL), |
|---|
| 256 | CurrentProcess(NULL), |
|---|
| 257 | CurrentProcessID(0), |
|---|
| 258 | PendingCompileCommands(), |
|---|
| 259 | m_ViewWindows() |
|---|
| 260 | { |
|---|
| 261 | // Register us with the parents list of children. |
|---|
| 262 | m_Parent->m_ChildFrames.PushBack(this); |
|---|
| 263 | |
|---|
| 264 | // Should really pass this in the MapDocumentT ctor (the mapdoc should be a member of us). |
|---|
| 265 | // Correction: NO! While the doc should be a member of us, it might be *created* before us so that its ctor may throw exceptions, |
|---|
| 266 | // and then be given to us (we become the owner). In this case, we have to set us as the child frame here - no chance to do it |
|---|
| 267 | // in the docs ctor. However, I wonder why the doc should know us in the first place...? |
|---|
| 268 | m_Doc->SetChildFrame(this); |
|---|
| 269 | |
|---|
| 270 | // Register the document as our first event handler. |
|---|
| 271 | PushEventHandler(m_Doc); |
|---|
| 272 | |
|---|
| 273 | |
|---|
| 274 | // Create the menu. |
|---|
| 275 | wxMenuBar *item0 = new wxMenuBar; |
|---|
| 276 | |
|---|
| 277 | FileMenu = new wxMenu; |
|---|
| 278 | |
|---|
| 279 | wxMenu* NewMenu = new wxMenu; |
|---|
| 280 | |
|---|
| 281 | NewMenu->Append(ParentFrameT::ID_MENU_FILE_NEW_MAP, wxT("New &Map\tCtrl+N"), wxT("")); |
|---|
| 282 | NewMenu->Append(ParentFrameT::ID_MENU_FILE_NEW_MODEL, wxT("New M&odel\tCtrl+Shift+N"), wxT("")); |
|---|
| 283 | NewMenu->Append(ParentFrameT::ID_MENU_FILE_NEW_GUI, wxT("New &GUI\tCtrl+Alt+N"), wxT("")); |
|---|
| 284 | NewMenu->Append(ParentFrameT::ID_MENU_FILE_NEW_FONT, wxT("New &Font"), wxT("")); |
|---|
| 285 | |
|---|
| 286 | FileMenu->AppendSubMenu(NewMenu, wxT("&New")); |
|---|
| 287 | |
|---|
| 288 | FileMenu->Append(ParentFrameT::ID_MENU_FILE_OPEN, wxT("&Open...\tCtrl+O"), wxT("") ); |
|---|
| 289 | FileMenu->Append(ID_MENU_FILE_CLOSE, wxT("&Close\tCtrl+F4"), wxT("") ); |
|---|
| 290 | FileMenu->Append(ID_MENU_FILE_SAVE, wxT("&Save\tCtrl+S"), wxT("") ); |
|---|
| 291 | FileMenu->Append(ID_MENU_FILE_SAVEAS, wxT("Save &As..."), wxT("") ); |
|---|
| 292 | FileMenu->AppendSeparator(); |
|---|
| 293 | FileMenu->Append(ParentFrameT::ID_MENU_FILE_CONFIGURE, wxT("Conf&igure CaWE..."), wxT("") ); |
|---|
| 294 | FileMenu->Append(ParentFrameT::ID_MENU_FILE_EXIT, wxT("E&xit"), wxT("") ); |
|---|
| 295 | m_Parent->m_FileHistory.UseMenu(FileMenu); |
|---|
| 296 | m_Parent->m_FileHistory.AddFilesToMenu(FileMenu); |
|---|
| 297 | item0->Append( FileMenu, wxT("&File") ); |
|---|
| 298 | |
|---|
| 299 | wxMenu* item2 = new wxMenu; |
|---|
| 300 | item2->Append( wxID_UNDO, wxT("&Undo\tCtrl+Z"), wxT("") ); |
|---|
| 301 | item2->Append( wxID_REDO, wxT("&Redo\tCtrl+Y"), wxT("") ); |
|---|
| 302 | item2->AppendSeparator(); |
|---|
| 303 | item2->Append( wxID_CUT, wxT("Cu&t\tCtrl+X"), wxT("") ); |
|---|
| 304 | item2->Append( wxID_COPY, wxT("&Copy\tCtrl+C"), wxT("") ); |
|---|
| 305 | item2->Append( wxID_PASTE, wxT("&Paste\tCtrl+V"), wxT("") ); |
|---|
| 306 | item2->Append(ID_MENU_EDIT_PASTE_SPECIAL, wxT("Paste &Special..."), wxT("") ); |
|---|
| 307 | item2->Append(ID_MENU_EDIT_DELETE, wxT("&Delete\tShift+Del"), wxT("") ); |
|---|
| 308 | item2->AppendSeparator(); |
|---|
| 309 | item2->Append(ID_MENU_EDIT_SELECT_NONE, wxT("Select &None\tCtrl+Q"), wxT("") ); |
|---|
| 310 | item2->Append( wxID_SELECTALL, wxT("Select &All"), wxT("") ); |
|---|
| 311 | item2->AppendSeparator(); |
|---|
| 312 | item2->AppendCheckItem(ID_MENU_EDIT_ENTITY_INSPECTOR, wxT("Object &Properties\tAlt+Enter"), wxT("") ); |
|---|
| 313 | item0->Append( item2, wxT("&Edit") ); |
|---|
| 314 | |
|---|
| 315 | wxMenu* item3 = new wxMenu; |
|---|
| 316 | item3->AppendCheckItem(ID_MENU_MAP_SNAP_TO_GRID, wxT("&Snap to grid\tShift+W"), wxT("") ); item3->Check(ID_MENU_MAP_SNAP_TO_GRID, m_Doc->IsSnapEnabled()); |
|---|
| 317 | item3->AppendCheckItem(ID_MENU_MAP_SHOW_GRID_2D, wxT("Sho&w grid\tShift+R"), wxT("") ); item3->Check(ID_MENU_MAP_SHOW_GRID_2D, m_Doc->Is2DGridEnabled()); |
|---|
| 318 | // item3->AppendCheckItem(ID_MENU_MAP_SHOW_GRID_3D, wxT("Show 3D grid\tShift+R"), wxT("") ); item3->Check(ID_MENU_MAP_SHOW_GRID_3D, m_Doc->Is3DGridEnabled()); // Maybe later. |
|---|
| 319 | |
|---|
| 320 | wxMenu* item4 = new wxMenu; |
|---|
| 321 | item4->Append(ID_MENU_MAP_FINER_GRID, wxT("&Finer Grid\t["), wxT("") ); |
|---|
| 322 | item4->Append(ID_MENU_MAP_COARSER_GRID, wxT("&Coarser Grid\t]"), wxT("") ); |
|---|
| 323 | item3->Append(ID_MENU_MAP_GRID_SETTINGS, wxT("&Grid settings"), item4 ); |
|---|
| 324 | |
|---|
| 325 | item3->AppendSeparator(); |
|---|
| 326 | item3->Append(ID_MENU_MAP_GOTO_PRIMITIVE, wxT("G&o to Primitive...\tShift+Ctrl+G"), wxT("") ); |
|---|
| 327 | item3->Append(ID_MENU_MAP_SHOW_INFO, wxT("Show &Information..."), wxT("") ); |
|---|
| 328 | item3->Append(ID_MENU_MAP_CHECK_FOR_PROBLEMS, wxT("&Check for Problems...\tAlt+P"), wxT("") ); |
|---|
| 329 | item3->Append(ID_MENU_MAP_PROPERTIES, wxT("&Map Properties..."), wxT("") ); |
|---|
| 330 | item3->AppendSeparator(); |
|---|
| 331 | item3->Append(ID_MENU_MAP_LOAD_POINTFILE, wxT("&Load Pointfile..."), wxT("") ); |
|---|
| 332 | item3->Append(ID_MENU_MAP_UNLOAD_POINTFILE, wxT("&Unload Pointfile"), wxT("") ); |
|---|
| 333 | item0->Append( item3, wxT("&Map") ); |
|---|
| 334 | |
|---|
| 335 | wxMenu* item6 = new wxMenu; |
|---|
| 336 | |
|---|
| 337 | wxMenu* item7 = new wxMenu; |
|---|
| 338 | item7->AppendCheckItem(ID_MENU_VIEW_TOOLBARS_FILE, wxT("&General"), wxT("") ); |
|---|
| 339 | item7->AppendCheckItem(ID_MENU_VIEW_TOOLBARS_TOOLS, wxT("&Tools"), wxT("") ); |
|---|
| 340 | item6->Append(ID_MENU_VIEW_TOOLBARS, wxT("&Toolbars"), item7 ); |
|---|
| 341 | |
|---|
| 342 | wxMenu* ViewPanelsMenu=new wxMenu; |
|---|
| 343 | ViewPanelsMenu->AppendCheckItem(ID_MENU_VIEW_PANELS_TOOLOPTIONS, wxT("&Tool Options"), wxT("") ); |
|---|
| 344 | ViewPanelsMenu->AppendCheckItem(ID_MENU_VIEW_PANELS_MATERIALS, wxT("&Materials"), wxT("") ); |
|---|
| 345 | ViewPanelsMenu->AppendCheckItem(ID_MENU_VIEW_PANELS_GROUPS, wxT("&Groups"), wxT("") ); |
|---|
| 346 | ViewPanelsMenu->AppendCheckItem(ID_MENU_VIEW_PANELS_INSPECTOR, wxT("Object &Properties"), wxT("") ); |
|---|
| 347 | ViewPanelsMenu->AppendCheckItem(ID_MENU_VIEW_PANELS_CONSOLE, wxT("&Console"), wxT("") ); |
|---|
| 348 | item6->Append(ID_MENU_VIEW_PANELS, wxT("&Panels"), ViewPanelsMenu); |
|---|
| 349 | |
|---|
| 350 | item6->Append(ID_MENU_VIEW_NEW_2D_VIEW, "New &2D view", "Opens a new 2D view on the map"); |
|---|
| 351 | item6->Append(ID_MENU_VIEW_NEW_3D_VIEW, "New &3D view", "Opens a new 3D view on the map"); |
|---|
| 352 | item6->AppendSeparator(); |
|---|
| 353 | |
|---|
| 354 | item6->Append(ID_MENU_VIEW_LOAD_USER_PERSPECTIVE, "&Load user window layout", "Loads the user defined window layout"); |
|---|
| 355 | item6->Append(ID_MENU_VIEW_SAVE_USER_PERSPECTIVE, "&Save user window layout", "Saves the current window layout"); |
|---|
| 356 | item6->Append(ID_MENU_VIEW_LOAD_DEFAULT_PERSPECTIVE, "Load &default window layout", "Restores the default window layout"); |
|---|
| 357 | item6->AppendSeparator(); |
|---|
| 358 | item6->Append(ID_MENU_VIEW_CENTER_2D_VIEWS, wxT("Center &2D Views on Selection\tCtrl+E"), wxT("") ); |
|---|
| 359 | item6->Append(ID_MENU_VIEW_CENTER_3D_VIEWS, wxT("Center &3D Views on Selection"), wxT("") ); |
|---|
| 360 | item6->AppendSeparator(); |
|---|
| 361 | item6->Append(ID_MENU_VIEW_SHOW_ENTITY_INFO, wxT("Show Entity &Info"), wxT(""), wxITEM_CHECK); |
|---|
| 362 | item6->Append(ID_MENU_VIEW_SHOW_ENTITY_TARGETS, wxT("Show Entity &Targets"), wxT(""), wxITEM_CHECK ); |
|---|
| 363 | item6->AppendSeparator(); |
|---|
| 364 | item6->Append(ID_MENU_VIEW_HIDE_SELECTED_OBJECTS, wxT("H&ide Selected Objects"), wxT("") ); |
|---|
| 365 | item6->Append(ID_MENU_VIEW_SHOW_HIDDEN_OBJECTS, wxT("&Show Hidden Objects"), wxT("") ); |
|---|
| 366 | item0->Append( item6, wxT("&View") ); |
|---|
| 367 | |
|---|
| 368 | wxMenu* item8 = new wxMenu; |
|---|
| 369 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_SELECTION, wxT("Selection\tShift+S"), wxT("")); |
|---|
| 370 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_CAMERA, wxT("Camera\tShift+C"), wxT("")); |
|---|
| 371 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWBRUSH, wxT("New Brush\tShift+B"), wxT("")); |
|---|
| 372 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWENTITY, wxT("New Entity\tShift+E"), wxT("")); |
|---|
| 373 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWBEZIERPATCH, wxT("New Bezier Patch\tShift+P"), wxT("")); |
|---|
| 374 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWTERRAIN, wxT("New Terrain\tShift+T"), wxT("")); |
|---|
| 375 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWLIGHT, wxT("New Light\tShift+L"), wxT("")); |
|---|
| 376 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_NEWDECAL, wxT("New Decal\tShift+D"), wxT("")); |
|---|
| 377 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_EDITSURFACEPROPERTIES, wxT("Edit Surface Properties\tShift+A"), wxT("")); |
|---|
| 378 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_TERRAINEDITOR, wxT("Terrain Editor\tShift+F"), wxT("")); |
|---|
| 379 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_CLIP, wxT("Clip Brushes\tShift+X"), wxT("")); |
|---|
| 380 | item8->AppendRadioItem(ID_MENU_TOOLS_TOOL_EDITVERTICES, wxT("Edit Brush Vertices\tShift+V"), wxT("")); |
|---|
| 381 | item8->AppendSeparator(); |
|---|
| 382 | item8->Append(ID_MENU_TOOLS_CARVE, wxT("&Carve\tShift+Ctrl+C"), wxT("") ); |
|---|
| 383 | item8->Append(ID_MENU_TOOLS_MAKE_HOLLOW, wxT("Make Hollow\tCtrl+H"), wxT("") ); |
|---|
| 384 | item8->AppendSeparator(); |
|---|
| 385 | item8->Append(ID_MENU_TOOLS_GROUP, wxT("&Group\tCtrl+G"), wxT("") ); |
|---|
| 386 | item8->AppendSeparator(); |
|---|
| 387 | item8->Append(ID_MENU_TOOLS_ASSIGN_PRIM_TO_ENTITY, wxT("&Tie to Entity\tCtrl+T"), wxT("") ); |
|---|
| 388 | item8->Append(ID_MENU_TOOLS_ASSIGN_PRIM_TO_WORLD, wxT("&Move to World\tShift+Ctrl+W"), wxT("") ); |
|---|
| 389 | item8->AppendSeparator(); |
|---|
| 390 | item8->Append(ID_MENU_TOOLS_REPLACE_MATERIALS, wxT("R&eplace Materials"), wxT("") ); |
|---|
| 391 | item8->AppendCheckItem(ID_MENU_TOOLS_MATERIAL_LOCK, wxT("Material &Lock\tShift+L"), wxT("") ); |
|---|
| 392 | item8->AppendSeparator(); |
|---|
| 393 | item8->Append(ID_MENU_TOOLS_SNAP_SELECTION_TO_GRID, wxT("Snap Selection to Grid\tCtrl+B"), wxT("") ); |
|---|
| 394 | item8->Append(ID_MENU_TOOLS_TRANSFORM, wxT("Transform\tCtrl+M"), wxT("") ); |
|---|
| 395 | |
|---|
| 396 | wxMenu* item9 = new wxMenu; |
|---|
| 397 | item9->Append(ID_MENU_TOOLS_ALIGN_LEFT, wxT("to &Left"), wxT("") ); |
|---|
| 398 | item9->Append(ID_MENU_TOOLS_ALIGN_RIGHT, wxT("to &Right"), wxT("") ); |
|---|
| 399 | item9->Append(ID_MENU_TOOLS_ALIGN_HOR_CENTER, wxT("to &hor. Center"), wxT("") ); |
|---|
| 400 | item9->Append(ID_MENU_TOOLS_ALIGN_TOP, wxT("to &Top"), wxT("") ); |
|---|
| 401 | item9->Append(ID_MENU_TOOLS_ALIGN_BOTTOM, wxT("to &Bottom"), wxT("") ); |
|---|
| 402 | item9->Append(ID_MENU_TOOLS_ALIGN_VERT_CENTER, wxT("to &vert. Center"), wxT("") ); |
|---|
| 403 | item8->Append(ID_MENU_TOOLS_ALIGN, wxT("&Align Objects"), item9 ); |
|---|
| 404 | |
|---|
| 405 | wxMenu* item10 = new wxMenu; |
|---|
| 406 | item10->Append(ID_MENU_TOOLS_MIRROR_HOR, wxT("&Horizontally\tCtrl+L"), wxT("") ); |
|---|
| 407 | item10->Append(ID_MENU_TOOLS_MIRROR_VERT, wxT("&Vertically\tCtrl+I"), wxT("") ); |
|---|
| 408 | item8->Append(ID_MENU_TOOLS_MIRROR, wxT("M&irror Objects"), item10 ); |
|---|
| 409 | |
|---|
| 410 | item0->Append( item8, wxT("&Tools") ); |
|---|
| 411 | |
|---|
| 412 | CompileMenu=new wxMenu; |
|---|
| 413 | CompileMenu->AppendCheckItem(ID_MENU_COMPILE_FLAG_SAVE_MAP, "1. &Save Map", ""); CompileMenu->Check(ID_MENU_COMPILE_FLAG_SAVE_MAP, true); |
|---|
| 414 | CompileMenu->AppendCheckItem(ID_MENU_COMPILE_FLAG_RUN_BSP, "2. Run Ca&BSP", ""); CompileMenu->Check(ID_MENU_COMPILE_FLAG_RUN_BSP, true); CompileMenu->Enable(ID_MENU_COMPILE_FLAG_RUN_BSP, false); |
|---|
| 415 | CompileMenu->AppendCheckItem(ID_MENU_COMPILE_FLAG_RUN_PVS, "3. Run Ca&PVS", ""); CompileMenu->Check(ID_MENU_COMPILE_FLAG_RUN_PVS, true); |
|---|
| 416 | CompileMenu->AppendCheckItem(ID_MENU_COMPILE_FLAG_RUN_LIGHT, "4. Run Ca&Light", ""); CompileMenu->Check(ID_MENU_COMPILE_FLAG_RUN_LIGHT, false); // Intentionally off per default, in order to make sure that first-time users are not confronted with a multi-hour CaLight session. |
|---|
| 417 | CompileMenu->AppendCheckItem(ID_MENU_COMPILE_FLAG_RUN_ENGINE, "5. Start &Engine", ""); CompileMenu->Check(ID_MENU_COMPILE_FLAG_RUN_ENGINE, true); |
|---|
| 418 | CompileMenu->AppendSeparator(); |
|---|
| 419 | CompileMenu->Append(ID_MENU_COMPILE_QUICK, "Run &Quick...", ""); |
|---|
| 420 | CompileMenu->Append(ID_MENU_COMPILE_NORMAL, "Run &Normal...", ""); |
|---|
| 421 | CompileMenu->Append(ID_MENU_COMPILE_QUALITY, "Run &High Quality...", ""); |
|---|
| 422 | CompileMenu->Append(ID_MENU_COMPILE_CUSTOM, "Run Custom...", ""); |
|---|
| 423 | CompileMenu->AppendSeparator(); |
|---|
| 424 | CompileMenu->Append(ID_MENU_COMPILE_ABORT, "Abort", ""); CompileMenu->Enable(ID_MENU_COMPILE_ABORT, false); |
|---|
| 425 | item0->Append(CompileMenu, wxT("&Compile") ); |
|---|
| 426 | |
|---|
| 427 | wxMenu* item12 = new wxMenu; |
|---|
| 428 | item12->Append(ParentFrameT::ID_MENU_HELP_CONTENTS, wxT("&CaWE Help\tF1"), wxT("") ); |
|---|
| 429 | item12->AppendSeparator(); |
|---|
| 430 | item12->Append(ParentFrameT::ID_MENU_HELP_CAFU_WEBSITE, wxT("Cafu &Website"), wxT("") ); |
|---|
| 431 | item12->Append(ParentFrameT::ID_MENU_HELP_CAFU_FORUM, wxT("Cafu &Forum"), wxT("") ); |
|---|
| 432 | item12->AppendSeparator(); |
|---|
| 433 | item12->Append(ParentFrameT::ID_MENU_HELP_ABOUT, wxT("&About..."), wxT("") ); |
|---|
| 434 | item0->Append(item12, wxT("&Help") ); |
|---|
| 435 | |
|---|
| 436 | SetMenuBar(item0); |
|---|
| 437 | SetMinSize(wxSize(400,300)); |
|---|
| 438 | |
|---|
| 439 | |
|---|
| 440 | // Create the status bar at the bottom of the frame. |
|---|
| 441 | int StatusBarWidths[6]={ -1, 200, 130, 130, 100, 120 }; |
|---|
| 442 | |
|---|
| 443 | CreateStatusBar(6, wxST_SIZEGRIP); // Create the status bar with 6 panes. |
|---|
| 444 | SetStatusWidths(6, StatusBarWidths); // Set the widths of the individual panes. |
|---|
| 445 | SetStatusBarPane(SBP_MENU_HELP); // Use the first pane (number 0) for displaying menu and toolbar help. |
|---|
| 446 | SetStatusText(" Welcome to CaWE!", SBP_MENU_HELP); // Set an initial text in the first pane. |
|---|
| 447 | |
|---|
| 448 | |
|---|
| 449 | // Create the toolbars. |
|---|
| 450 | wxAuiToolBar* ToolbarFile=new wxAuiToolBar(this, wxID_ANY); |
|---|
| 451 | ToolbarFile->AddTool(ParentFrameT::ID_MENU_FILE_NEW_GUI, "New", wxArtProvider::GetBitmap(wxART_NEW, wxART_TOOLBAR), "Create a new file"); |
|---|
| 452 | ToolbarFile->AddTool(ParentFrameT::ID_MENU_FILE_OPEN, "Open", wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR), "Open an existing file"); |
|---|
| 453 | ToolbarFile->AddTool(ID_MENU_FILE_SAVE, "Save", wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_TOOLBAR), "Save the file"); |
|---|
| 454 | ToolbarFile->AddTool(ID_MENU_FILE_SAVEAS, "Save as", wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_TOOLBAR), "Save the file under a different name"); |
|---|
| 455 | ToolbarFile->AddSeparator(); |
|---|
| 456 | ToolbarFile->AddTool(wxID_UNDO, "Undo", wxArtProvider::GetBitmap(wxART_UNDO, wxART_TOOLBAR), "Undo the last action"); |
|---|
| 457 | ToolbarFile->AddTool(wxID_REDO, "Redo", wxArtProvider::GetBitmap(wxART_REDO, wxART_TOOLBAR), "Redo the previously undone action"); |
|---|
| 458 | ToolbarFile->AddSeparator(); |
|---|
| 459 | ToolbarFile->AddTool(wxID_CUT, "Cut", wxArtProvider::GetBitmap(wxART_CUT, wxART_TOOLBAR), "Cut"); |
|---|
| 460 | ToolbarFile->AddTool(wxID_COPY, "Copy", wxArtProvider::GetBitmap(wxART_COPY, wxART_TOOLBAR), "Copy"); |
|---|
| 461 | ToolbarFile->AddTool(wxID_PASTE, "Paste", wxArtProvider::GetBitmap(wxART_PASTE, wxART_TOOLBAR), "Paste"); |
|---|
| 462 | ToolbarFile->AddTool(ID_MENU_EDIT_DELETE, "Delete", wxArtProvider::GetBitmap(wxART_DELETE, wxART_TOOLBAR), "Delete"); |
|---|
| 463 | ToolbarFile->Realize(); |
|---|
| 464 | |
|---|
| 465 | // Note that we cannot have separators between these tools, because they must all be in the same radio group. |
|---|
| 466 | wxAuiToolBar* ToolbarTools=new wxAuiToolBar(this, wxID_ANY); |
|---|
| 467 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_SELECTION, "Selection", wxArtProvider::GetBitmap("MapEditor/tool-selection", wxART_TOOLBAR, wxSize(21, 18)), "Selection", wxITEM_RADIO); |
|---|
| 468 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_CAMERA, "Camera", wxArtProvider::GetBitmap("MapEditor/tool-camera", wxART_TOOLBAR, wxSize(21, 18)), "Camera", wxITEM_RADIO); |
|---|
| 469 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWBRUSH, "New Brush", wxArtProvider::GetBitmap("MapEditor/tool-new-brush", wxART_TOOLBAR, wxSize(21, 18)), "New Brush", wxITEM_RADIO); |
|---|
| 470 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWENTITY, "New Entity", wxArtProvider::GetBitmap("MapEditor/tool-new-entity", wxART_TOOLBAR, wxSize(21, 18)), "New Entity", wxITEM_RADIO); |
|---|
| 471 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWBEZIERPATCH, "New Bezier Patch", wxArtProvider::GetBitmap("MapEditor/tool-new-bezierpatch", wxART_TOOLBAR, wxSize(21, 18)), "New Bezier Patch", wxITEM_RADIO); |
|---|
| 472 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWTERRAIN, "New Terrain", wxArtProvider::GetBitmap("MapEditor/tool-new-terrain", wxART_TOOLBAR, wxSize(21, 18)), "New Terrain", wxITEM_RADIO); |
|---|
| 473 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWLIGHT, "New Light", wxArtProvider::GetBitmap("MapEditor/tool-new-light", wxART_TOOLBAR, wxSize(21, 18)), "New Light", wxITEM_RADIO); |
|---|
| 474 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_NEWDECAL, "New Decal", wxArtProvider::GetBitmap("MapEditor/tool-new-decal", wxART_TOOLBAR, wxSize(21, 18)), "New Decal", wxITEM_RADIO); |
|---|
| 475 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_EDITSURFACEPROPERTIES, "Edit Surface Properties", wxArtProvider::GetBitmap("MapEditor/tool-edit-surface-props", wxART_TOOLBAR, wxSize(21, 18)), "Edit Surface Properties", wxITEM_RADIO); |
|---|
| 476 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_TERRAINEDITOR, "Edit Terrain", wxArtProvider::GetBitmap("MapEditor/tool-edit-terrain", wxART_TOOLBAR, wxSize(21, 18)), "Edit Terrain", wxITEM_RADIO); |
|---|
| 477 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_CLIP, "Clip Brushes", wxArtProvider::GetBitmap("MapEditor/tool-clip", wxART_TOOLBAR, wxSize(21, 18)), "Clip Brushes", wxITEM_RADIO); |
|---|
| 478 | ToolbarTools->AddTool(ID_MENU_TOOLS_TOOL_EDITVERTICES, "Edit Brush Vertices", wxArtProvider::GetBitmap("MapEditor/tool-edit-vertices", wxART_TOOLBAR, wxSize(21, 18)), "Edit Brush Vertices", wxITEM_RADIO); |
|---|
| 479 | ToolbarTools->Realize(); |
|---|
| 480 | |
|---|
| 481 | m_AUIManager.AddPane(ToolbarFile, wxAuiPaneInfo().ToolbarPane(). |
|---|
| 482 | Name("File Toolbar").Caption("File Toolbar"). |
|---|
| 483 | Top().Row(0).Position(0).LeftDockable(false).RightDockable(false)); |
|---|
| 484 | |
|---|
| 485 | m_AUIManager.AddPane(ToolbarTools, wxAuiPaneInfo().ToolbarPane(). |
|---|
| 486 | Name("Tools Toolbar").Caption("Tools Toolbar"). |
|---|
| 487 | Top().Row(0).Position(1).LeftDockable(false).RightDockable(false)); |
|---|
| 488 | |
|---|
| 489 | |
|---|
| 490 | wxPanel* ToolbarToolOptions=new wxPanel(this, -1, wxDefaultPosition, wxSize(852, 30)); |
|---|
| 491 | m_ToolManager=new ToolManagerT(*m_Doc, ToolbarToolOptions); // Allocate our tool manager. |
|---|
| 492 | // This can NOT be called here - it will attempt to update the status bar and the tool options bars, |
|---|
| 493 | // which do not yet exist at this point. Instead, the call is made below, near the end of this constructor. |
|---|
| 494 | // m_ToolManager->SetActiveTool(GetToolTIM().FindTypeInfoByName("ToolSelectionT")); |
|---|
| 495 | |
|---|
| 496 | wxSizer* TTOSizer=new wxBoxSizer(wxVERTICAL); // The sizer makes sure that the individual panels each extend to the full width and height of the toolbar. |
|---|
| 497 | |
|---|
| 498 | // Add all tool options bars to the sizer (initially hidden). |
|---|
| 499 | for (unsigned long ToolNr=0; ToolNr<m_ToolManager->GetTools().Size(); ToolNr++) |
|---|
| 500 | { |
|---|
| 501 | ToolT* Tool =m_ToolManager->GetTools()[ToolNr]; |
|---|
| 502 | wxWindow* OptionsBar=Tool->GetOptionsBar(); |
|---|
| 503 | |
|---|
| 504 | if (!OptionsBar) continue; |
|---|
| 505 | |
|---|
| 506 | OptionsBar->Hide(); |
|---|
| 507 | TTOSizer->Add(OptionsBar, 1, wxGROW); |
|---|
| 508 | } |
|---|
| 509 | |
|---|
| 510 | ToolbarToolOptions->SetSizer(TTOSizer); |
|---|
| 511 | // TTOSizer->SetSizeHints(ToolbarToolOptions); // When this line is activated ("commented in"), the size of the pane gets wrong. |
|---|
| 512 | |
|---|
| 513 | m_AUIManager.AddPane(ToolbarToolOptions, wxAuiPaneInfo(). |
|---|
| 514 | Name("Tool Options").Caption("Tool Options"). |
|---|
| 515 | Top().Row(1)); |
|---|
| 516 | |
|---|
| 517 | |
|---|
| 518 | // Create the toolbars and non-modal dialogs. |
|---|
| 519 | // Note that most if not all of these wxAUI panes have extra style wxWS_EX_BLOCK_EVENTS set, |
|---|
| 520 | // so that they do not propagate their events to us, but behave as if they were derived from wxDialog. |
|---|
| 521 | m_MaterialsToolbar=new MaterialsToolbarT(this, m_Doc); |
|---|
| 522 | m_AUIManager.AddPane(m_MaterialsToolbar, wxAuiPaneInfo(). |
|---|
| 523 | Name("Materials").Caption("Materials"). |
|---|
| 524 | Left().Position(0)); |
|---|
| 525 | |
|---|
| 526 | m_GroupsToolbar=new GroupsToolbarT(this, m_Doc); |
|---|
| 527 | m_AUIManager.AddPane(m_GroupsToolbar, wxAuiPaneInfo(). |
|---|
| 528 | Name("Groups").Caption("Groups"). |
|---|
| 529 | Left().Position(1)); |
|---|
| 530 | |
|---|
| 531 | m_InspectorDialog=new InspectorDialogT(this, m_Doc); |
|---|
| 532 | m_AUIManager.AddPane(m_InspectorDialog, wxAuiPaneInfo(). |
|---|
| 533 | Name("Properties").Caption("Object Properties"). |
|---|
| 534 | Float().Hide()); |
|---|
| 535 | |
|---|
| 536 | m_ConsoleDialog=new ConsoleDialogT(this); |
|---|
| 537 | m_AUIManager.AddPane(m_ConsoleDialog, wxAuiPaneInfo(). |
|---|
| 538 | Name("Console").Caption("Console"). |
|---|
| 539 | BestSize(400, 300). |
|---|
| 540 | Bottom().Hide()); |
|---|
| 541 | |
|---|
| 542 | m_SurfacePropsDialog=new EditSurfacePropsDialogT(this, m_Doc); |
|---|
| 543 | m_AUIManager.AddPane(m_SurfacePropsDialog, wxAuiPaneInfo(). |
|---|
| 544 | Name("Surface Properties").Caption("Surface Properties"). |
|---|
| 545 | Float().Hide()); |
|---|
| 546 | |
|---|
| 547 | m_TerrainEditorDialog=new TerrainEditorDialogT(this, *m_Doc->GetGameConfig(), static_cast<ToolTerrainEditorT*>(m_ToolManager->GetTool(ToolTerrainEditorT::TypeInfo))); |
|---|
| 548 | m_AUIManager.AddPane(m_TerrainEditorDialog, wxAuiPaneInfo(). |
|---|
| 549 | Name("Terrain Editor").Caption("Terrain Editor"). |
|---|
| 550 | Float().Hide()); |
|---|
| 551 | |
|---|
| 552 | |
|---|
| 553 | ViewWindow3DT* CenterPaneView=new ViewWindow3DT(this, this, NULL, (ViewWindowT::ViewTypeT)wxConfigBase::Get()->Read("Splitter/ViewType00", ViewWindowT::VT_3D_FULL_MATS)); |
|---|
| 554 | m_AUIManager.AddPane(CenterPaneView, wxAuiPaneInfo(). |
|---|
| 555 | Name("Main View").Caption(CenterPaneView->GetCaption()). |
|---|
| 556 | CenterPane().CaptionVisible().MaximizeButton().MinimizeButton()); |
|---|
| 557 | |
|---|
| 558 | ViewWindow2DT* ViewTopRight=new ViewWindow2DT(this, this, (ViewWindowT::ViewTypeT)wxConfigBase::Get()->Read("Splitter/ViewType01", ViewWindowT::VT_2D_XY)); |
|---|
| 559 | m_AUIManager.AddPane(ViewTopRight, wxAuiPaneInfo(). |
|---|
| 560 | // Name("xy"). |
|---|
| 561 | Caption(ViewTopRight->GetCaption()). |
|---|
| 562 | DestroyOnClose().Right().Position(0).MaximizeButton().MinimizeButton()); |
|---|
| 563 | |
|---|
| 564 | ViewWindow2DT* ViewBottomRight=new ViewWindow2DT(this, this, (ViewWindowT::ViewTypeT)wxConfigBase::Get()->Read("Splitter/ViewType11", ViewWindowT::VT_2D_XZ)); |
|---|
| 565 | m_AUIManager.AddPane(ViewBottomRight, wxAuiPaneInfo(). |
|---|
| 566 | // Name("xy"). |
|---|
| 567 | Caption(ViewBottomRight->GetCaption()). |
|---|
| 568 | DestroyOnClose().Right().Position(1).MaximizeButton().MinimizeButton()); |
|---|
| 569 | |
|---|
| 570 | |
|---|
| 571 | // Save the AUI perspective that we set up in this ctor code as the "default perspective". |
|---|
| 572 | m_AUIDefaultPerspective=m_AUIManager.SavePerspective(); |
|---|
| 573 | |
|---|
| 574 | // Load the AUI user perspective (implies a call to m_AUIManager.Update()). |
|---|
| 575 | m_AUIManager.LoadPerspective(wxConfigBase::Get()->Read("MapEditor_AUIUserPerspective", m_AUIDefaultPerspective)); |
|---|
| 576 | |
|---|
| 577 | |
|---|
| 578 | // Activate the Selection tool as the default tool (having initially no tool active at all can be quite confusing for users). |
|---|
| 579 | // This cannot be done near the creation of the tool manager above, because then the status bar and tool options bars do not yet exist. |
|---|
| 580 | m_ToolManager->SetActiveTool(GetToolTIM().FindTypeInfoByName("ToolSelectionT")); |
|---|
| 581 | |
|---|
| 582 | #ifndef __WXGTK__ |
|---|
| 583 | Centre(wxBOTH); |
|---|
| 584 | #endif |
|---|
| 585 | if (!IsMaximized()) Maximize(true); // Also have wxMAXIMIZE set as frame style. |
|---|
| 586 | Show(true); |
|---|
| 587 | |
|---|
| 588 | m_Updater=new UpdaterT(this); |
|---|
| 589 | |
|---|
| 590 | // Start the autosave timer. |
|---|
| 591 | int Minutes=0; |
|---|
| 592 | wxConfigBase::Get()->Read("General/AutoSave Interval", &Minutes, 10); |
|---|
| 593 | if (Minutes>0) m_AutoSaveTimer.Start(Minutes*60*1000); |
|---|
| 594 | else m_AutoSaveTimer.Stop(); |
|---|
| 595 | } |
|---|
| 596 | |
|---|
| 597 | |
|---|
| 598 | ChildFrameT::~ChildFrameT() |
|---|
| 599 | { |
|---|
| 600 | m_AutoSaveTimer.Stop(); |
|---|
| 601 | |
|---|
| 602 | if (CurrentProcess!=NULL) |
|---|
| 603 | { |
|---|
| 604 | CurrentProcess->Detach(); |
|---|
| 605 | CurrentProcess=NULL; |
|---|
| 606 | CurrentProcessID=0; |
|---|
| 607 | } |
|---|
| 608 | |
|---|
| 609 | m_Parent->m_FileHistory.RemoveMenu(FileMenu); |
|---|
| 610 | |
|---|
| 611 | delete m_Updater; |
|---|
| 612 | m_Updater=NULL; |
|---|
| 613 | |
|---|
| 614 | delete m_ToolManager; |
|---|
| 615 | m_ToolManager=NULL; |
|---|
| 616 | |
|---|
| 617 | // Unregister us from the parents list of children. |
|---|
| 618 | const int Index=m_Parent->m_ChildFrames.Find(this); |
|---|
| 619 | m_Parent->m_ChildFrames.RemoveAt(Index); |
|---|
| 620 | |
|---|
| 621 | // Remove the document as our first event handler. |
|---|
| 622 | PopEventHandler(); |
|---|
| 623 | |
|---|
| 624 | // Delete the document. |
|---|
| 625 | delete m_Doc; |
|---|
| 626 | m_Doc=NULL; |
|---|
| 627 | |
|---|
| 628 | // Uninit the AUI manager. |
|---|
| 629 | m_AUIManager.UnInit(); |
|---|
| 630 | } |
|---|
| 631 | |
|---|
| 632 | |
|---|
| 633 | Vector3fT ChildFrameT::GuessUserVisiblePoint() const |
|---|
| 634 | { |
|---|
| 635 | Vector3fT Point(0, 0, 0); // TODO: Init along the view dir of the MRU camera instead? Or m_SelectionBB.GetCenter()? |
|---|
| 636 | unsigned long HaveAxes=0; // Bit i is set if we have a coordinate for the i-th axis. |
|---|
| 637 | |
|---|
| 638 | for (unsigned long ViewWinNr=0; ViewWinNr<m_ViewWindows.Size() && HaveAxes<7; ViewWinNr++) |
|---|
| 639 | { |
|---|
| 640 | const ViewWindow2DT* ViewWin2D =dynamic_cast<ViewWindow2DT*>(m_ViewWindows[ViewWinNr]); if (!ViewWin2D) continue; |
|---|
| 641 | const int HorzAxis =ViewWin2D->GetAxesInfo().HorzAxis; |
|---|
| 642 | const int VertAxis =ViewWin2D->GetAxesInfo().VertAxis; |
|---|
| 643 | const wxRect ClientRect=wxRect(wxPoint(0, 0), ViewWin2D->GetClientSize()); |
|---|
| 644 | const Vector3fT Center =ViewWin2D->WindowToWorld(wxPoint(ClientRect.x+ClientRect.width/2, ClientRect.y+ClientRect.height/2), 0.0f); |
|---|
| 645 | |
|---|
| 646 | if ((HaveAxes & (1ul << HorzAxis))==0) |
|---|
| 647 | { |
|---|
| 648 | Point[HorzAxis]=Center[HorzAxis]; |
|---|
| 649 | HaveAxes|=(1ul << HorzAxis); |
|---|
| 650 | } |
|---|
| 651 | |
|---|
| 652 | if ((HaveAxes & (1ul << VertAxis))==0) |
|---|
| 653 | { |
|---|
| 654 | Point[VertAxis]=Center[VertAxis]; |
|---|
| 655 | HaveAxes|=(1ul << VertAxis); |
|---|
| 656 | } |
|---|
| 657 | } |
|---|
| 658 | |
|---|
| 659 | return Point; |
|---|
| 660 | } |
|---|
| 661 | |
|---|
| 662 | |
|---|
| 663 | void ChildFrameT::All2DViews_Zoom(float ZoomFactor) |
|---|
| 664 | { |
|---|
| 665 | for (unsigned long ViewWinNr=0; ViewWinNr<m_ViewWindows.Size(); ViewWinNr++) |
|---|
| 666 | { |
|---|
| 667 | ViewWindowT* ViewWin =m_ViewWindows[ViewWinNr]; |
|---|
| 668 | ViewWindow2DT* ViewWin2D=dynamic_cast<ViewWindow2DT*>(ViewWin); |
|---|
| 669 | |
|---|
| 670 | if (ViewWin2D) |
|---|
| 671 | { |
|---|
| 672 | ViewWin2D->SetZoom(ZoomFactor); |
|---|
| 673 | ViewWin2D->Refresh(); |
|---|
| 674 | } |
|---|
| 675 | } |
|---|
| 676 | } |
|---|
| 677 | |
|---|
| 678 | |
|---|
| 679 | void ChildFrameT::All2DViews_Center(const Vector3fT& CenterPoint) |
|---|
| 680 | { |
|---|
| 681 | for (unsigned long ViewWinNr=0; ViewWinNr<m_ViewWindows.Size(); ViewWinNr++) |
|---|
| 682 | { |
|---|
| 683 | ViewWindowT* ViewWin =m_ViewWindows[ViewWinNr]; |
|---|
| 684 | ViewWindow2DT* ViewWin2D=dynamic_cast<ViewWindow2DT*>(ViewWin); |
|---|
| 685 | |
|---|
| 686 | if (ViewWin2D) |
|---|
| 687 | { |
|---|
| 688 | ViewWin2D->CenterView(CenterPoint); |
|---|
| 689 | // ViewWin2D->Refresh(); // Already in CenterView(). |
|---|
| 690 | } |
|---|
| 691 | } |
|---|
| 692 | } |
|---|
| 693 | |
|---|
| 694 | |
|---|
| 695 | bool ChildFrameT::IsPaneShown(wxWindow* Pane) |
|---|
| 696 | { |
|---|
| 697 | wxAuiPaneInfo& PaneInfo=m_AUIManager.GetPane(Pane); |
|---|
| 698 | |
|---|
| 699 | if (!PaneInfo.IsOk()) return false; |
|---|
| 700 | |
|---|
| 701 | return PaneInfo.IsShown(); |
|---|
| 702 | } |
|---|
| 703 | |
|---|
| 704 | |
|---|
| 705 | void ChildFrameT::ShowPane(wxWindow* Pane, bool DoShow) |
|---|
| 706 | { |
|---|
| 707 | wxAuiPaneInfo& PaneInfo=m_AUIManager.GetPane(Pane); |
|---|
| 708 | |
|---|
| 709 | if (!PaneInfo.IsOk()) return; |
|---|
| 710 | |
|---|
| 711 | PaneInfo.Show(DoShow); |
|---|
| 712 | |
|---|
| 713 | if (DoShow && PaneInfo.IsFloating() && PaneInfo.floating_pos==wxDefaultPosition) |
|---|
| 714 | PaneInfo.FloatingPosition(ClientToScreen(wxPoint(20, 20))); |
|---|
| 715 | |
|---|
| 716 | m_AUIManager.Update(); |
|---|
| 717 | } |
|---|
| 718 | |
|---|
| 719 | |
|---|
| 720 | void ChildFrameT::SetCaption(wxWindow* Pane, const wxString& Caption) |
|---|
| 721 | { |
|---|
| 722 | wxAuiPaneInfo& PaneInfo=m_AUIManager.GetPane(Pane); |
|---|
| 723 | |
|---|
| 724 | if (!PaneInfo.IsOk()) return; |
|---|
| 725 | |
|---|
| 726 | PaneInfo.Caption(Caption); |
|---|
| 727 | m_AUIManager.Update(); |
|---|
| 728 | } |
|---|
| 729 | |
|---|
| 730 | |
|---|
| 731 | /**********************/ |
|---|
| 732 | /*** Event Handlers ***/ |
|---|
| 733 | /**********************/ |
|---|
| 734 | |
|---|
| 735 | void ChildFrameT::OnClose(wxCloseEvent& CE) |
|---|
| 736 | { |
|---|
| 737 | if (!CE.CanVeto()) |
|---|
| 738 | { |
|---|
| 739 | Destroy(); |
|---|
| 740 | return; |
|---|
| 741 | } |
|---|
| 742 | |
|---|
| 743 | if (m_Doc->GetHistory().GetLastSaveSuggestedCommandID()==m_LastSavedAtCommandNr) |
|---|
| 744 | { |
|---|
| 745 | // Our document has not been modified since the last save - close this window. |
|---|
| 746 | Destroy(); |
|---|
| 747 | return; |
|---|
| 748 | } |
|---|
| 749 | |
|---|
| 750 | // This "Save Confirmation Alert" essentially follows the GNOME Human Interface Guidelines, |
|---|
| 751 | // see http://developer.gnome.org/hig-book/ for details. |
|---|
| 752 | wxMessageDialog Msg(NULL, "Save changes to map \"" + m_Doc->GetFileName() + "\" before closing?", "CaWE Map Editor", wxYES_NO | wxCANCEL); |
|---|
| 753 | |
|---|
| 754 | Msg.SetExtendedMessage("If you close without saving, your changes will be discarded."); |
|---|
| 755 | Msg.SetYesNoLabels("Save", "Close without Saving"); |
|---|
| 756 | |
|---|
| 757 | switch (Msg.ShowModal()) |
|---|
| 758 | { |
|---|
| 759 | case wxID_YES: |
|---|
| 760 | if (!m_Doc->Save()) |
|---|
| 761 | { |
|---|
| 762 | // The document could not be saved - keep the window open. |
|---|
| 763 | CE.Veto(); |
|---|
| 764 | return; |
|---|
| 765 | } |
|---|
| 766 | |
|---|
| 767 | if (m_Doc->GetHistory().GetLastSaveSuggestedCommandID()!=m_LastSavedAtCommandNr) |
|---|
| 768 | { |
|---|
| 769 | // The save was successful, but maybe it was a map export rather than a native cmap save. |
|---|
| 770 | // In this case, also keep the window open. |
|---|
| 771 | wxMessageBox("The map was exported, not saved. Please save the map before leaving.", "Map not closed.", wxOK | wxICON_INFORMATION); |
|---|
| 772 | CE.Veto(); |
|---|
| 773 | return; |
|---|
| 774 | } |
|---|
| 775 | |
|---|
| 776 | // The map was successfully saved - close the window. |
|---|
| 777 | Destroy(); |
|---|
| 778 | return; |
|---|
| 779 | |
|---|
| 780 | case wxID_NO: |
|---|
| 781 | Destroy(); |
|---|
| 782 | return; |
|---|
| 783 | |
|---|
| 784 | default: // wxID_CANCEL |
|---|
| 785 | CE.Veto(); |
|---|
| 786 | return; |
|---|
| 787 | } |
|---|
| 788 | } |
|---|
| 789 | |
|---|
| 790 | |
|---|
| 791 | void ChildFrameT::OnIdle(wxIdleEvent& IE) |
|---|
| 792 | { |
|---|
| 793 | // We have a compile process running - forward its output to the console. |
|---|
| 794 | // This code is duplicated in ChildFrameT::OnProcessEnd(), to make sure we don't miss anything. |
|---|
| 795 | if (CurrentProcess && CurrentProcess->IsInputAvailable()) |
|---|
| 796 | { |
|---|
| 797 | wxInputStream* InStream=CurrentProcess->GetInputStream(); |
|---|
| 798 | char Buffer[256]; |
|---|
| 799 | |
|---|
| 800 | while (InStream->CanRead()) |
|---|
| 801 | { |
|---|
| 802 | InStream->Read(Buffer, 255); |
|---|
| 803 | |
|---|
| 804 | size_t count=InStream->LastRead(); |
|---|
| 805 | |
|---|
| 806 | #ifdef __WXGTK__ |
|---|
| 807 | if (count==0) break; // This apparently can happen under wxGTK; I don't know why. |
|---|
| 808 | #endif |
|---|
| 809 | wxASSERT(count>0 && count<256); |
|---|
| 810 | Buffer[count]=0; |
|---|
| 811 | |
|---|
| 812 | m_ConsoleDialog->Print(Buffer, wxLIGHT_GREY); |
|---|
| 813 | } |
|---|
| 814 | } |
|---|
| 815 | |
|---|
| 816 | // The following things are only performed if the child frame is the active childframe. |
|---|
| 817 | ChildFrameT* ActiveChild=dynamic_cast<ChildFrameT*>(m_Parent->GetActiveChild()); |
|---|
| 818 | |
|---|
| 819 | if (this==ActiveChild) |
|---|
| 820 | { |
|---|
| 821 | // Set the proper window title with or without a trailing "*", depending on the current save state. |
|---|
| 822 | // The extra check (GetTitle()!=NewTitle) is necessary in order to prevent the title from flickering... |
|---|
| 823 | // can we implement an entirely different solution here, e.g. as in the GUI editor? |
|---|
| 824 | wxString NewTitle=m_Doc->GetFileName() + (m_Doc->GetHistory().GetLastSaveSuggestedCommandID()==m_LastSavedAtCommandNr ? "" : "*"); |
|---|
| 825 | if (GetTitle()!=NewTitle) SetTitle(NewTitle); |
|---|
| 826 | |
|---|
| 827 | // Cache materials for the childframes game configuration (one material per idle event). |
|---|
| 828 | m_Doc->GetGameConfig()->GetMatMan().LazilyUpdateProxies(); |
|---|
| 829 | |
|---|
| 830 | // Update the map documents BSP tree (regarding map elements that have moved or otherwise changed their bounding-box). |
|---|
| 831 | const unsigned long ElemsUpdated=m_Doc->GetBspTree()->Update(); |
|---|
| 832 | |
|---|
| 833 | if (ElemsUpdated>0) |
|---|
| 834 | { |
|---|
| 835 | wxLogDebug("OrthoBspTreeT::Update() updated %lu map elements.", ElemsUpdated); |
|---|
| 836 | } |
|---|
| 837 | |
|---|
| 838 | // Update all 3D views. |
|---|
| 839 | for (unsigned long ViewWinNr=0; ViewWinNr<m_ViewWindows.Size(); ViewWinNr++) |
|---|
| 840 | { |
|---|
| 841 | ViewWindowT* ViewWin =m_ViewWindows[ViewWinNr]; |
|---|
| 842 | ViewWindow3DT* ViewWin3D=dynamic_cast<ViewWindow3DT*>(ViewWin); |
|---|
| 843 | |
|---|
| 844 | if (ViewWin3D) |
|---|
| 845 | { |
|---|
| 846 | ViewWin3D->Refresh(false); |
|---|
| 847 | ViewWin3D->Update(); |
|---|
| 848 | } |
|---|
| 849 | } |
|---|
| 850 | } |
|---|
| 851 | |
|---|
| 852 | IE.RequestMore(); |
|---|
| 853 | } |
|---|
| 854 | |
|---|
| 855 | |
|---|
| 856 | void ChildFrameT::OnProcessEnd(wxProcessEvent& PE) |
|---|
| 857 | { |
|---|
| 858 | // Code duplicated from ChildFrameT::OnIdle(), to make sure we don't miss anything. |
|---|
| 859 | if (CurrentProcess && CurrentProcess->IsInputAvailable()) |
|---|
| 860 | { |
|---|
| 861 | wxInputStream* InStream=CurrentProcess->GetInputStream(); |
|---|
| 862 | char Buffer[256]; |
|---|
| 863 | |
|---|
| 864 | while (InStream->CanRead()) |
|---|
| 865 | { |
|---|
| 866 | InStream->Read(Buffer, 255); |
|---|
| 867 | |
|---|
| 868 | size_t count=InStream->LastRead(); |
|---|
| 869 | |
|---|
| 870 | #ifdef __WXGTK__ |
|---|
| 871 | if (count==0) break; // This apparently can happen under wxGTK; I don't know why. |
|---|
| 872 | #endif |
|---|
| 873 | wxASSERT(count>0 && count<256); |
|---|
| 874 | Buffer[count]=0; |
|---|
| 875 | |
|---|
| 876 | m_ConsoleDialog->Print(Buffer, wxLIGHT_GREY); |
|---|
| 877 | } |
|---|
| 878 | } |
|---|
| 879 | |
|---|
| 880 | if (PE.GetExitCode()!=0) |
|---|
| 881 | { |
|---|
| 882 | EndCompiling(wxString::Format("\nError: Map compilation process %i exited with code %i.\n", PE.GetPid(), PE.GetExitCode()), wxRED); |
|---|
| 883 | return; |
|---|
| 884 | } |
|---|
| 885 | |
|---|
| 886 | if (PendingCompileCommands.Size()==0) |
|---|
| 887 | { |
|---|
| 888 | EndCompiling("\nMap compilation ended successfully."); |
|---|
| 889 | return; |
|---|
| 890 | } |
|---|
| 891 | |
|---|
| 892 | m_ConsoleDialog->Print("\nMap compilation: Running command '"+PendingCompileCommands[0]+"'\n", wxBLUE); |
|---|
| 893 | |
|---|
| 894 | // Delete previous compile process. |
|---|
| 895 | delete CurrentProcess; |
|---|
| 896 | CurrentProcess=NULL; |
|---|
| 897 | CurrentProcessID=0; |
|---|
| 898 | |
|---|
| 899 | // Start new compile process. |
|---|
| 900 | CurrentProcess=new wxProcess(this); |
|---|
| 901 | CurrentProcess->Redirect(); |
|---|
| 902 | |
|---|
| 903 | if (PendingCompileCommands[0].StartsWith(Options.general.EngineExe)) |
|---|
| 904 | CurrentProcessID=wxExecute(PendingCompileCommands[0], wxEXEC_ASYNC | wxEXEC_NOHIDE, CurrentProcess); |
|---|
| 905 | else |
|---|
| 906 | CurrentProcessID=wxExecute(PendingCompileCommands[0], wxEXEC_ASYNC, CurrentProcess); |
|---|
| 907 | |
|---|
| 908 | PendingCompileCommands.RemoveAtAndKeepOrder(0); |
|---|
| 909 | |
|---|
| 910 | if (CurrentProcessID<=0) |
|---|
| 911 | EndCompiling("\nCould not execute the map compilation process!\n", wxRED); |
|---|
| 912 | } |
|---|
| 913 | |
|---|
| 914 | |
|---|
| 915 | void ChildFrameT::OnMenuFile(wxCommandEvent& CE) |
|---|
| 916 | { |
|---|
| 917 | switch (CE.GetId()) |
|---|
| 918 | { |
|---|
| 919 | case ID_MENU_FILE_CLOSE: |
|---|
| 920 | { |
|---|
| 921 | // Close() generates a EVT_CLOSE event which is handled by our OnClose() handler. |
|---|
| 922 | // See wx Window Deletion Overview for more details. |
|---|
| 923 | Close(); |
|---|
| 924 | break; |
|---|
| 925 | } |
|---|
| 926 | |
|---|
| 927 | case ID_MENU_FILE_SAVE: |
|---|
| 928 | { |
|---|
| 929 | const bool SaveOK=m_Doc->Save(); |
|---|
| 930 | |
|---|
| 931 | if (SaveOK && m_Doc->GetFileName().Right(5).MakeLower()==".cmap") |
|---|
| 932 | { |
|---|
| 933 | // Mark the document as "not modified" only if the save was successful AND in cmap file format. |
|---|
| 934 | // All other file formats are exported formats, and may not be able to store all information that is stored in a cmap file. |
|---|
| 935 | // Thus data loss may occur if the document is only saved in an exported, but not in cmap file format. |
|---|
| 936 | // Considering file *exports* not as file *saves* (that mark the document as "not modified" when successful) |
|---|
| 937 | // makes sure that on application exit, the user is warned about possible data loss in such cases. |
|---|
| 938 | m_LastSavedAtCommandNr=m_Doc->GetHistory().GetLastSaveSuggestedCommandID(); |
|---|
| 939 | m_Parent->m_FileHistory.AddFileToHistory(m_Doc->GetFileName()); |
|---|
| 940 | } |
|---|
| 941 | break; |
|---|
| 942 | } |
|---|
| 943 | |
|---|
| 944 | case ID_MENU_FILE_SAVEAS: |
|---|
| 945 | { |
|---|
| 946 | const bool SaveOK=m_Doc->SaveAs(); |
|---|
| 947 | |
|---|
| 948 | if (SaveOK && m_Doc->GetFileName().Right(5).MakeLower()==".cmap") |
|---|
| 949 | { |
|---|
| 950 | // Mark the document as "not modified" only if the save was successful AND in cmap file format. |
|---|
| 951 | // All other file formats are exported formats, and may not be able to store all information that is stored in a cmap file. |
|---|
| 952 | // Thus data loss may occur if the document is only saved in an exported, but not in cmap file format. |
|---|
| 953 | // Considering file *exports* not as file *saves* (that mark the document as "not modified" when successful) |
|---|
| 954 | // makes sure that on application exit, the user is warned about possible data loss in such cases. |
|---|
| 955 | m_LastSavedAtCommandNr=m_Doc->GetHistory().GetLastSaveSuggestedCommandID(); |
|---|
| 956 | m_Parent->m_FileHistory.AddFileToHistory(m_Doc->GetFileName()); |
|---|
| 957 | } |
|---|
| 958 | break; |
|---|
| 959 | } |
|---|
| 960 | } |
|---|
| 961 | } |
|---|
| 962 | |
|---|
| 963 | |
|---|
| 964 | void ChildFrameT::OnMenuFileUpdate(wxUpdateUIEvent& UE) |
|---|
| 965 | { |
|---|
| 966 | switch (UE.GetId()) |
|---|
| 967 | { |
|---|
| 968 | case ID_MENU_FILE_SAVE: |
|---|
| 969 | UE.Enable(m_Doc->GetHistory().GetLastSaveSuggestedCommandID()!=m_LastSavedAtCommandNr); |
|---|
| 970 | break; |
|---|
| 971 | } |
|---|
| 972 | } |
|---|
| 973 | |
|---|
| 974 | |
|---|
| 975 | void ChildFrameT::OnMenuEdit(wxCommandEvent& CE) |
|---|
| 976 | { |
|---|
| 977 | switch (CE.GetId()) |
|---|
| 978 | { |
|---|
| 979 | case ID_MENU_EDIT_ENTITY_INSPECTOR: |
|---|
| 980 | { |
|---|
| 981 | wxAuiPaneInfo& PaneInfo=m_AUIManager.GetPane(m_InspectorDialog); |
|---|
| 982 | |
|---|
| 983 | if (!PaneInfo.IsShown()) |
|---|
| 984 | { |
|---|
| 985 | const int BestPage=m_InspectorDialog->GetBestPage(m_Doc->GetSelection()); |
|---|
| 986 | |
|---|
| 987 | m_InspectorDialog->ChangePage(BestPage); |
|---|
| 988 | } |
|---|
| 989 | |
|---|
| 990 | PaneToggleShow(PaneInfo); |
|---|
| 991 | break; |
|---|
| 992 | } |
|---|
| 993 | } |
|---|
| 994 | } |
|---|
| 995 | |
|---|
| 996 | |
|---|
| 997 | void ChildFrameT::OnMenuEditUpdate(wxUpdateUIEvent& UE) |
|---|
| 998 | { |
|---|
| 999 | switch (UE.GetId()) |
|---|
| 1000 | { |
|---|
| 1001 | case ID_MENU_EDIT_ENTITY_INSPECTOR: |
|---|
| 1002 | UE.Check(m_AUIManager.GetPane(m_InspectorDialog).IsShown()); |
|---|
| 1003 | break; |
|---|
| 1004 | } |
|---|
| 1005 | } |
|---|
| 1006 | |
|---|
| 1007 | |
|---|
| 1008 | void ChildFrameT::PaneToggleShow(wxAuiPaneInfo& PaneInfo) |
|---|
| 1009 | { |
|---|
| 1010 | if (!PaneInfo.IsOk()) return; |
|---|
| 1011 | |
|---|
| 1012 | const bool DoShow=!PaneInfo.IsShown(); |
|---|
| 1013 | PaneInfo.Show(DoShow); |
|---|
| 1014 | |
|---|
| 1015 | if (DoShow && PaneInfo.IsFloating() && PaneInfo.floating_pos==wxDefaultPosition) |
|---|
| 1016 | PaneInfo.FloatingPosition(ClientToScreen(wxPoint(20, 20))); |
|---|
| 1017 | |
|---|
| 1018 | m_AUIManager.Update(); |
|---|
| 1019 | } |
|---|
| 1020 | |
|---|
| 1021 | |
|---|
| 1022 | void ChildFrameT::OnMenuView(wxCommandEvent& CE) |
|---|
| 1023 | { |
|---|
| 1024 | switch (CE.GetId()) |
|---|
| 1025 | { |
|---|
| 1026 | case ID_MENU_VIEW_TOOLBARS_FILE: |
|---|
| 1027 | PaneToggleShow(m_AUIManager.GetPane("File Toolbar")); |
|---|
| 1028 | break; |
|---|
| 1029 | |
|---|
| 1030 | case ID_MENU_VIEW_TOOLBARS_TOOLS: |
|---|
| 1031 | PaneToggleShow(m_AUIManager.GetPane("Tools Toolbar")); |
|---|
| 1032 | break; |
|---|
| 1033 | |
|---|
| 1034 | case ID_MENU_VIEW_PANELS_TOOLOPTIONS: |
|---|
| 1035 | PaneToggleShow(m_AUIManager.GetPane("Tool Options")); |
|---|
| 1036 | break; |
|---|
| 1037 | |
|---|
| 1038 | case ID_MENU_VIEW_PANELS_MATERIALS: |
|---|
| 1039 | PaneToggleShow(m_AUIManager.GetPane(m_MaterialsToolbar)); |
|---|
| 1040 | break; |
|---|
| 1041 | |
|---|
| 1042 | case ID_MENU_VIEW_PANELS_GROUPS: |
|---|
| 1043 | PaneToggleShow(m_AUIManager.GetPane(m_GroupsToolbar)); |
|---|
| 1044 | break; |
|---|
| 1045 | |
|---|
| 1046 | case ID_MENU_VIEW_PANELS_INSPECTOR: |
|---|
| 1047 | PaneToggleShow(m_AUIManager.GetPane(m_InspectorDialog)); |
|---|
| 1048 | break; |
|---|
| 1049 | |
|---|
| 1050 | case ID_MENU_VIEW_PANELS_CONSOLE: |
|---|
| 1051 | PaneToggleShow(m_AUIManager.GetPane(m_ConsoleDialog)); |
|---|
| 1052 | break; |
|---|
| 1053 | |
|---|
| 1054 | case ID_MENU_VIEW_NEW_2D_VIEW: |
|---|
| 1055 | { |
|---|
| 1056 | ViewWindow2DT* NewView=new ViewWindow2DT(this, this, ViewWindowT::VT_2D_XY); |
|---|
| 1057 | m_AUIManager.AddPane(NewView, wxAuiPaneInfo(). |
|---|
| 1058 | // Name("xy"). |
|---|
| 1059 | Caption(NewView->GetCaption()). |
|---|
| 1060 | DestroyOnClose().Float().MaximizeButton().MinimizeButton()); |
|---|
| 1061 | |
|---|
| 1062 | m_AUIManager.Update(); |
|---|
| 1063 | break; |
|---|
| 1064 | } |
|---|
| 1065 | |
|---|
| 1066 | case ID_MENU_VIEW_NEW_3D_VIEW: |
|---|
| 1067 | { |
|---|
| 1068 | ViewWindow3DT* NewView=new ViewWindow3DT(this, this, new CameraT(), (ViewWindowT::ViewTypeT)wxConfigBase::Get()->Read("Splitter/ViewType00", ViewWindowT::VT_3D_FULL_MATS)); |
|---|
| 1069 | m_AUIManager.AddPane(NewView, wxAuiPaneInfo(). |
|---|
| 1070 | // Name("xy"). |
|---|
| 1071 | Caption(NewView->GetCaption()). |
|---|
| 1072 | DestroyOnClose().Float().MaximizeButton().MinimizeButton()); |
|---|
| 1073 | |
|---|
| 1074 | m_AUIManager.Update(); |
|---|
| 1075 | break; |
|---|
| 1076 | } |
|---|
| 1077 | |
|---|
| 1078 | case ID_MENU_VIEW_LOAD_DEFAULT_PERSPECTIVE: |
|---|
| 1079 | m_AUIManager.LoadPerspective(m_AUIDefaultPerspective); |
|---|
| 1080 | break; |
|---|
| 1081 | |
|---|
| 1082 | case ID_MENU_VIEW_LOAD_USER_PERSPECTIVE: |
|---|
| 1083 | m_AUIManager.LoadPerspective(wxConfigBase::Get()->Read("MapEditor_AUIUserPerspective", m_AUIManager.SavePerspective())); |
|---|
| 1084 | break; |
|---|
| 1085 | |
|---|
| 1086 | case ID_MENU_VIEW_SAVE_USER_PERSPECTIVE: |
|---|
| 1087 | wxConfigBase::Get()->Write("MapEditor_AUIUserPerspective", m_AUIManager.SavePerspective()); |
|---|
| 1088 | break; |
|---|
| 1089 | |
|---|
| 1090 | case ID_MENU_VIEW_CENTER_2D_VIEWS: |
|---|
| 1091 | All2DViews_Center(m_Doc->GetMostRecentSelBB().GetCenter()); |
|---|
| 1092 | break; |
|---|
| 1093 | |
|---|
| 1094 | case ID_MENU_VIEW_CENTER_3D_VIEWS: |
|---|
| 1095 | { |
|---|
| 1096 | const BoundingBox3fT& SelBB=m_Doc->GetMostRecentSelBB(); |
|---|
| 1097 | const Vector3fT Pos =SelBB.GetCenter(); |
|---|
| 1098 | |
|---|
| 1099 | for (unsigned long ViewWinNr=0; ViewWinNr<m_ViewWindows.Size(); ViewWinNr++) |
|---|
| 1100 | { |
|---|
| 1101 | ViewWindowT* ViewWin =m_ViewWindows[ViewWinNr]; |
|---|
| 1102 | ViewWindow3DT* ViewWin3D=dynamic_cast<ViewWindow3DT*>(ViewWin); |
|---|
| 1103 | |
|---|
| 1104 | if (ViewWin3D) |
|---|
| 1105 | { |
|---|
| 1106 | const CameraT& Camera=ViewWin3D->GetCamera(); |
|---|
| 1107 | |
|---|
| 1108 | ViewWin3D->MoveCamera(Pos-Camera.GetYAxis()*(std::max(Camera.ViewDirLength, length(SelBB.Max-SelBB.Min)/* /2.0f */))); |
|---|
| 1109 | break; // Only do this for the MRU 3D view - it really doesn't make sense to do it for all. |
|---|
| 1110 | } |
|---|
| 1111 | } |
|---|
| 1112 | |
|---|
| 1113 | break; |
|---|
| 1114 | } |
|---|
| 1115 | } |
|---|
| 1116 | } |
|---|
| 1117 | |
|---|
| 1118 | |
|---|
| 1119 | void ChildFrameT::OnMenuViewUpdate(wxUpdateUIEvent& UE) |
|---|
| 1120 | { |
|---|
| 1121 | switch (UE.GetId()) |
|---|
| 1122 | { |
|---|
| 1123 | case ID_MENU_VIEW_TOOLBARS_FILE: |
|---|
| 1124 | UE.Check(m_AUIManager.GetPane("File Toolbar").IsShown()); |
|---|
| 1125 | break; |
|---|
| 1126 | |
|---|
| 1127 | case ID_MENU_VIEW_TOOLBARS_TOOLS: |
|---|
| 1128 | UE.Check(m_AUIManager.GetPane("Tools Toolbar").IsShown()); |
|---|
| 1129 | break; |
|---|
| 1130 | |
|---|
| 1131 | case ID_MENU_VIEW_PANELS_TOOLOPTIONS: |
|---|
| 1132 | UE.Check(m_AUIManager.GetPane("Tool Options").IsShown()); |
|---|
| 1133 | break; |
|---|
| 1134 | |
|---|
| 1135 | case ID_MENU_VIEW_PANELS_MATERIALS: |
|---|
| 1136 | UE.Check(m_AUIManager.GetPane(m_MaterialsToolbar).IsShown()); |
|---|
| 1137 | break; |
|---|
| 1138 | |
|---|
| 1139 | case ID_MENU_VIEW_PANELS_GROUPS: |
|---|
| 1140 | UE.Check(m_AUIManager.GetPane(m_GroupsToolbar).IsShown()); |
|---|
| 1141 | break; |
|---|
| 1142 | |
|---|
| 1143 | case ID_MENU_VIEW_PANELS_INSPECTOR: |
|---|
| 1144 | UE.Check(m_AUIManager.GetPane(m_InspectorDialog).IsShown()); |
|---|
| 1145 | break; |
|---|
| 1146 | |
|---|
| 1147 | case ID_MENU_VIEW_PANELS_CONSOLE: |
|---|
| 1148 | UE.Check(m_AUIManager.GetPane(m_ConsoleDialog).IsShown()); |
|---|
| 1149 | break; |
|---|
| 1150 | } |
|---|
| 1151 | } |
|---|
| 1152 | |
|---|
| 1153 | |
|---|
| 1154 | void ChildFrameT::OnMenuTools(wxCommandEvent& CE) |
|---|
| 1155 | { |
|---|
| 1156 | // Find the tool whose wxWidgets event ID matches CE.GetId(). |
|---|
| 1157 | const ArrayT<ToolT*>& Tools=m_ToolManager->GetTools(); |
|---|
| 1158 | |
|---|
| 1159 | for (unsigned long ToolNr=0; ToolNr<Tools.Size(); ToolNr++) |
|---|
| 1160 | { |
|---|
| 1161 | ToolT* Tool=Tools[ToolNr]; |
|---|
| 1162 | |
|---|
| 1163 | if (Tool->GetWxEventID()==CE.GetId()) |
|---|
| 1164 | { |
|---|
| 1165 | m_ToolManager->SetActiveTool(Tool->GetType()); |
|---|
| 1166 | break; |
|---|
| 1167 | } |
|---|
| 1168 | } |
|---|
| 1169 | } |
|---|
| 1170 | |
|---|
| 1171 | |
|---|
| 1172 | void ChildFrameT::OnMenuToolsUpdate(wxUpdateUIEvent& UE) |
|---|
| 1173 | { |
|---|
| 1174 | const ToolT* ActiveTool=m_ToolManager->GetActiveTool(); |
|---|
| 1175 | |
|---|
| 1176 | UE.Check(ActiveTool && ActiveTool->GetWxEventID()==UE.GetId()); |
|---|
| 1177 | } |
|---|
| 1178 | |
|---|
| 1179 | |
|---|
| 1180 | void ChildFrameT::OnMenuCompile(wxCommandEvent& CE) |
|---|
| 1181 | { |
|---|
| 1182 | switch (CE.GetId()) |
|---|
| 1183 | { |
|---|
| 1184 | case ID_MENU_COMPILE_QUICK: |
|---|
| 1185 | case ID_MENU_COMPILE_NORMAL: |
|---|
| 1186 | case ID_MENU_COMPILE_QUALITY: |
|---|
| 1187 | case ID_MENU_COMPILE_CUSTOM: |
|---|
| 1188 | { |
|---|
| 1189 | if (CurrentProcess!=NULL) |
|---|
| 1190 | { |
|---|
| 1191 | wxMessageBox("Another process is already running.\nWait until it is finished, then try again."); |
|---|
| 1192 | return; |
|---|
| 1193 | } |
|---|
| 1194 | |
|---|
| 1195 | wxASSERT(PendingCompileCommands.Size()==0 && CurrentProcessID==0); |
|---|
| 1196 | |
|---|
| 1197 | if (CompileMenu->IsChecked(ID_MENU_COMPILE_FLAG_SAVE_MAP)) |
|---|
| 1198 | { |
|---|
| 1199 | // Do a regular map save. |
|---|
| 1200 | m_Doc->Save(); |
|---|
| 1201 | } |
|---|
| 1202 | |
|---|
| 1203 | CustomCompileDialogT CustomCompileDialog(this); |
|---|
| 1204 | |
|---|
| 1205 | // If compile mode is CUSTOM, show Custom Compile Options dialog. |
|---|
| 1206 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM) |
|---|
| 1207 | { |
|---|
| 1208 | if (CustomCompileDialog.ShowModal()!=wxID_OK) return; |
|---|
| 1209 | } |
|---|
| 1210 | |
|---|
| 1211 | // Console Fenster anzeigen. |
|---|
| 1212 | m_AUIManager.GetPane(m_ConsoleDialog).Show(); |
|---|
| 1213 | m_AUIManager.Update(); |
|---|
| 1214 | |
|---|
| 1215 | if (CE.GetId()==ID_MENU_COMPILE_QUICK ) m_ConsoleDialog->Print(wxString("\n> compile (quick) " )+m_Doc->GetFileName()+"\n"); |
|---|
| 1216 | if (CE.GetId()==ID_MENU_COMPILE_NORMAL ) m_ConsoleDialog->Print(wxString("\n> compile (normal) " )+m_Doc->GetFileName()+"\n"); |
|---|
| 1217 | if (CE.GetId()==ID_MENU_COMPILE_QUALITY) m_ConsoleDialog->Print(wxString("\n> compile (quality) ")+m_Doc->GetFileName()+"\n"); |
|---|
| 1218 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM ) m_ConsoleDialog->Print(wxString("\n> compile (custom) " )+m_Doc->GetFileName()+"\n"); |
|---|
| 1219 | |
|---|
| 1220 | |
|---|
| 1221 | // Test the document file name for validity, and construct the target .cw file name from it. |
|---|
| 1222 | wxFileName MapName(m_Doc->GetFileName()); |
|---|
| 1223 | |
|---|
| 1224 | if (!MapName.IsOk()) |
|---|
| 1225 | { |
|---|
| 1226 | m_ConsoleDialog->Print("Map file name \""+MapName.GetFullPath()+"\" is malformed.\n", wxRED); |
|---|
| 1227 | return; |
|---|
| 1228 | } |
|---|
| 1229 | |
|---|
| 1230 | // MapName.Normalize(); |
|---|
| 1231 | MapName.MakeRelativeTo("."); // Make it relative to the current working directory. |
|---|
| 1232 | |
|---|
| 1233 | if (MapName.GetExt()!="cmap") |
|---|
| 1234 | { |
|---|
| 1235 | m_ConsoleDialog->Print("Map file name \""+MapName.GetFullPath()+"\" doesn't end with \".cmap\".\n", wxRED); |
|---|
| 1236 | return; |
|---|
| 1237 | } |
|---|
| 1238 | |
|---|
| 1239 | wxFileName WorldName(m_Doc->GetGameConfig()->ModDir+"/Worlds/"+MapName.GetName()+".cw"); |
|---|
| 1240 | WorldName.MakeRelativeTo("."); // Make it relative to the current working directory. |
|---|
| 1241 | |
|---|
| 1242 | |
|---|
| 1243 | // Create the compile commands. |
|---|
| 1244 | { |
|---|
| 1245 | if (CompileMenu->IsChecked(ID_MENU_COMPILE_FLAG_RUN_BSP)) |
|---|
| 1246 | { |
|---|
| 1247 | if (!wxFileExists(Options.general.BSPExe)) |
|---|
| 1248 | { |
|---|
| 1249 | EndCompiling("\nMap compilation error: '"+Options.general.BSPExe+"' File not found.\n", wxRED); |
|---|
| 1250 | return; |
|---|
| 1251 | } |
|---|
| 1252 | |
|---|
| 1253 | wxString Params=""; |
|---|
| 1254 | |
|---|
| 1255 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM) Params=" "+CustomCompileDialog.GetCaBSPOptions(); |
|---|
| 1256 | |
|---|
| 1257 | PendingCompileCommands.PushBack(Options.general.BSPExe+" \""+MapName.GetFullPath()+"\" \""+WorldName.GetFullPath()+"\""+Params); |
|---|
| 1258 | } |
|---|
| 1259 | |
|---|
| 1260 | if (CompileMenu->IsChecked(ID_MENU_COMPILE_FLAG_RUN_PVS)) |
|---|
| 1261 | { |
|---|
| 1262 | if (!wxFileExists(Options.general.PVSExe)) |
|---|
| 1263 | { |
|---|
| 1264 | EndCompiling("\nMap compilation error: '"+Options.general.PVSExe+"' File not found.\n", wxRED); |
|---|
| 1265 | return; |
|---|
| 1266 | } |
|---|
| 1267 | |
|---|
| 1268 | wxString Params=""; |
|---|
| 1269 | |
|---|
| 1270 | if (CE.GetId()==ID_MENU_COMPILE_QUICK) Params=" -maxRecDepthSL 15"; |
|---|
| 1271 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM) Params=" "+CustomCompileDialog.GetCaPVSOptions(); |
|---|
| 1272 | |
|---|
| 1273 | PendingCompileCommands.PushBack(Options.general.PVSExe+" \""+WorldName.GetFullPath()+"\""+Params); |
|---|
| 1274 | } |
|---|
| 1275 | |
|---|
| 1276 | if (CompileMenu->IsChecked(ID_MENU_COMPILE_FLAG_RUN_LIGHT)) |
|---|
| 1277 | { |
|---|
| 1278 | if (!wxFileExists(Options.general.LightExe)) |
|---|
| 1279 | { |
|---|
| 1280 | EndCompiling("\nMap compilation error: '"+Options.general.LightExe+"' File not found.\n", wxRED); |
|---|
| 1281 | return; |
|---|
| 1282 | } |
|---|
| 1283 | |
|---|
| 1284 | wxFileName ModDirName=wxFileName::DirName(m_Doc->GetGameConfig()->ModDir); |
|---|
| 1285 | wxString Params =""; |
|---|
| 1286 | |
|---|
| 1287 | ModDirName.MakeRelativeTo("."); |
|---|
| 1288 | |
|---|
| 1289 | if (CE.GetId()==ID_MENU_COMPILE_QUICK ) Params=" -fast"; |
|---|
| 1290 | if (CE.GetId()==ID_MENU_COMPILE_QUALITY) Params=" -StopUE 0.1"; |
|---|
| 1291 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM ) Params=" "+CustomCompileDialog.GetCaLightOptions(); |
|---|
| 1292 | |
|---|
| 1293 | PendingCompileCommands.PushBack(Options.general.LightExe+" \""+WorldName.GetFullPath()+"\" -gd="+ModDirName.GetFullPath()+Params); |
|---|
| 1294 | } |
|---|
| 1295 | |
|---|
| 1296 | if (CompileMenu->IsChecked(ID_MENU_COMPILE_FLAG_RUN_ENGINE)) |
|---|
| 1297 | { |
|---|
| 1298 | if (!wxFileExists(Options.general.EngineExe)) |
|---|
| 1299 | { |
|---|
| 1300 | EndCompiling("\nMap compilation error: '"+Options.general.EngineExe+"' File not found.\n", wxRED); |
|---|
| 1301 | return; |
|---|
| 1302 | } |
|---|
| 1303 | |
|---|
| 1304 | wxString Params=""; |
|---|
| 1305 | |
|---|
| 1306 | if (CE.GetId()==ID_MENU_COMPILE_CUSTOM) Params=" "+CustomCompileDialog.GetEngineOptions(); |
|---|
| 1307 | |
|---|
| 1308 | PendingCompileCommands.PushBack(Options.general.EngineExe + |
|---|
| 1309 | " -svGame \"" + m_Doc->GetGameConfig()->Name + "\"" + |
|---|
| 1310 | " -svWorld \"" + WorldName.GetName() + "\"" + Params); |
|---|
| 1311 | } |
|---|
| 1312 | } |
|---|
| 1313 | |
|---|
| 1314 | // Disable the compile buttons. These are re-enabled in ChildFrameT::EndCompiling(). |
|---|
| 1315 | CompileMenu->Enable(ID_MENU_COMPILE_QUICK, false); |
|---|
| 1316 | CompileMenu->Enable(ID_MENU_COMPILE_NORMAL, false); |
|---|
| 1317 | CompileMenu->Enable(ID_MENU_COMPILE_QUALITY, false); |
|---|
| 1318 | CompileMenu->Enable(ID_MENU_COMPILE_CUSTOM, false); |
|---|
| 1319 | CompileMenu->Enable(ID_MENU_COMPILE_ABORT, true); |
|---|
| 1320 | |
|---|
| 1321 | // Create dummy process event and call end process to trigger compilation start. |
|---|
| 1322 | wxProcessEvent PE; // Note: Is initialized with exit code 0. |
|---|
| 1323 | OnProcessEnd(PE); |
|---|
| 1324 | |
|---|
| 1325 | break; |
|---|
| 1326 | } |
|---|
| 1327 | |
|---|
| 1328 | case ID_MENU_COMPILE_ABORT: |
|---|
| 1329 | { |
|---|
| 1330 | if (CurrentProcessID==0) |
|---|
| 1331 | { |
|---|
| 1332 | wxMessageBox("There is currently no process running that could be aborted."); |
|---|
| 1333 | return; |
|---|
| 1334 | } |
|---|
| 1335 | |
|---|
| 1336 | m_AUIManager.GetPane(m_ConsoleDialog).Show(); |
|---|
| 1337 | m_AUIManager.Update(); |
|---|
| 1338 | |
|---|
| 1339 | wxKillError KillErr=wxProcess::Kill(CurrentProcessID, wxSIGKILL); |
|---|
| 1340 | m_ConsoleDialog->Print(wxString::Format("The compile process with ID %i has been terminated. Kill result: %i.\n", CurrentProcessID, KillErr), wxRED); |
|---|
| 1341 | |
|---|
| 1342 | // The TERM signal triggers a call to CurrentProcess->OnTerminate() and thus a call to ChildFrameT::OnProcessEnd(). |
|---|
| 1343 | // wxASSERT(CurrentProcess==NULL && CurrentProcessID==0); |
|---|
| 1344 | // doesn't work here though, because the event system must be running so that the event can actually be processed. |
|---|
| 1345 | break; |
|---|
| 1346 | } |
|---|
| 1347 | |
|---|
| 1348 | default: |
|---|
| 1349 | // We must also handle the ID_MENU_COMPILE_FLAG_* menu events here, locally in ChildFrameT. |
|---|
| 1350 | // Otherwise, the event is propagated to the parent window, where it's ID triggers an entirely unrelated action! |
|---|
| 1351 | break; |
|---|
| 1352 | } |
|---|
| 1353 | } |
|---|
| 1354 | |
|---|
| 1355 | |
|---|
| 1356 | void ChildFrameT::OnWindowActivate(wxActivateEvent& AE) |
|---|
| 1357 | { |
|---|
| 1358 | AE.Skip(); |
|---|
| 1359 | |
|---|
| 1360 | if (!AE.GetActive()) return; |
|---|
| 1361 | |
|---|
| 1362 | // To make sure the proper default material is always set, we reset it here according to current material toolbar MRU. |
|---|
| 1363 | ArrayT<EditorMaterialI*> Materials=m_MaterialsToolbar->GetMRUMaterials(); |
|---|
| 1364 | |
|---|
| 1365 | wxASSERT(Materials.Size()>0); |
|---|
| 1366 | |
|---|
| 1367 | m_Doc->GetGameConfig()->GetMatMan().SetDefaultMaterial(Materials[0]); |
|---|
| 1368 | } |
|---|
| 1369 | |
|---|
| 1370 | |
|---|
| 1371 | void ChildFrameT::OnAuiPaneClose(wxAuiManagerEvent& AE) |
|---|
| 1372 | { |
|---|
| 1373 | if (AE.GetPane()->window==m_SurfacePropsDialog || AE.GetPane()->window==m_TerrainEditorDialog) |
|---|
| 1374 | { |
|---|
| 1375 | // Reset the tool back to "Selection", this will close the specific panes. |
|---|
| 1376 | m_ToolManager->SetActiveTool(GetToolTIM().FindTypeInfoByName("ToolSelectionT")); |
|---|
| 1377 | } |
|---|
| 1378 | else |
|---|
| 1379 | { |
|---|
| 1380 | // Let the default action occur (the pane is closed). |
|---|
| 1381 | AE.Skip(); |
|---|
| 1382 | } |
|---|
| 1383 | } |
|---|
| 1384 | |
|---|
| 1385 | |
|---|
| 1386 | /* void ChildFrameT::OnSize(wxSizeEvent& SE) |
|---|
| 1387 | { |
|---|
| 1388 | // wxLogDebug("ChildFrameT::OnSize"); |
|---|
| 1389 | // HorSplitterRatio=float(SplitterWindowParent->GetSashPosition())/float(GetClientSize().y); |
|---|
| 1390 | // VerSplitterRatio=float(SplitterWindowTop ->GetSashPosition())/float(GetClientSize().x); |
|---|
| 1391 | // wxLogDebug("%f %f %i %i %i %i", HorSplitterRatio, VerSplitterRatio, GetClientSize().x, SplitterWindowParent->GetClientSize().y, SplitterWindowParent->GetSashPosition(), SplitterWindowTop->GetSashPosition()); |
|---|
| 1392 | |
|---|
| 1393 | SplitterWindowParent->SetSashPosition(HorSplitterRatio*SplitterWindowParent->GetClientSize().y); |
|---|
| 1394 | SplitterWindowTop ->SetSashPosition(VerSplitterRatio*SplitterWindowTop ->GetClientSize().x); |
|---|
| 1395 | SplitterWindowBottom->SetSashPosition(VerSplitterRatio*SplitterWindowBottom->GetClientSize().x); |
|---|
| 1396 | |
|---|
| 1397 | SE.Skip(); |
|---|
| 1398 | }*/ |
|---|
| 1399 | |
|---|
| 1400 | |
|---|
| 1401 | void ChildFrameT::EndCompiling(const wxString& ConsoleMessage, const wxColour* Colour) |
|---|
| 1402 | { |
|---|
| 1403 | delete CurrentProcess; |
|---|
| 1404 | CurrentProcess=NULL; |
|---|
| 1405 | CurrentProcessID=0; |
|---|
| 1406 | |
|---|
| 1407 | PendingCompileCommands.Clear(); |
|---|
| 1408 | |
|---|
| 1409 | CompileMenu->Enable(ID_MENU_COMPILE_QUICK, true); |
|---|
| 1410 | CompileMenu->Enable(ID_MENU_COMPILE_NORMAL, true); |
|---|
| 1411 | CompileMenu->Enable(ID_MENU_COMPILE_QUALITY, true); |
|---|
| 1412 | CompileMenu->Enable(ID_MENU_COMPILE_CUSTOM, true); |
|---|
| 1413 | CompileMenu->Enable(ID_MENU_COMPILE_ABORT, false); |
|---|
| 1414 | |
|---|
| 1415 | m_ConsoleDialog->Print(ConsoleMessage, Colour); |
|---|
| 1416 | } |
|---|