📄 mainframe.cpp
字号:
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: mainframe.cpp,v 1.4 2008/03/02 13:57:00 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/// -*- C++ -*- generated by wxGlade 0.4 on Wed Jan 4 20:26:10 2006#include "mainframe.h"#include "sparkglcanvas.h"#include "main.h"#include "propertyframe.h"#include "kinematicframe.h"#include "agentframe.h"#include "sparkedit.h"#include "platform.h"#include <wx/filename.h>#include <wx/mimetype.h>#include <wx/filedlg.h>#include <wx/clipbrd.h>#include <rsgedit/res/xpm_play.xpm>#include <rsgedit/res/xpm_step.xpm>#include <rsgedit/res/xpm_pause.xpm>#include <rsgedit/res/xpm_new.xpm>#include <rsgedit/res/xpm_open.xpm>#include <rsgedit/res/xpm_save.xpm>#include <rsgedit/res/xpm_cut.xpm>#include <rsgedit/res/xpm_copy.xpm>#include <rsgedit/res/xpm_paste.xpm>#include <rsgedit/res/xpm_undo.xpm>#include <rsgedit/res/xpm_redo.xpm>#include <rsgedit/res/xpm_reload.xpm>#include <rsgedit/res/xpm_agent.xpm>#include "sparkcontextevent.h"#include "aboutDlg.h"//! wxWidgets and zeitgeist both use a 'DECLARE_CLASS' macro#undef DECLARE_CLASS#include <zeitgeist/logserver/logserver.h>#include <zeitgeist/scriptserver/scriptserver.h>#include <oxygen/simulationserver/simulationserver.h>#include <oxygen/sceneserver/sceneserver.h>#include <oxygen/sceneserver/fpscontroller.h>#include <kerosin/inputserver/inputcontrol.h>#include "simspark.h"#include "sparkcontext.h"#define TI_LOG 1#define TI_FPS 2BEGIN_EVENT_TABLE(mainframe, wxFrame) EVT_MENU(wxID_EXIT, mainframe::OnExit) EVT_CLOSE(mainframe::OnClose) EVT_UPDATE_UI(ID_SIM_START, mainframe::OnUpdateStartSimulation) EVT_MENU(ID_SIM_START, mainframe::OnStartSimulation) EVT_MENU(ID_SIM_STEP, mainframe::OnStepSimulation) EVT_UPDATE_UI(ID_SIM_PAUSE, mainframe::OnUpdatePauseSimulation) EVT_MENU(ID_SIM_PAUSE, mainframe::OnPauseSimulation) EVT_MENU(ID_VIEW_LOG, mainframe::OnViewLog) EVT_UPDATE_UI(ID_VIEW_LOG, mainframe::OnUpdateViewLog) EVT_MENU(ID_VIEW_TREE, mainframe::OnViewTree) EVT_UPDATE_UI(ID_VIEW_TREE, mainframe::OnUpdateViewTree) EVT_MENU(ID_FILE_NEW, mainframe::OnFileNew) EVT_MENU(ID_FILE_OPEN, mainframe::OnFileOpen) EVT_UPDATE_UI(ID_FILE_OPEN, mainframe::OnUpdateFileOpen) EVT_MENU(ID_FILE_SAVE, mainframe::OnFileSave) EVT_MENU(ID_FILE_SAVEAS, mainframe::OnFileSaveAs) EVT_UPDATE_UI(ID_FILE_SAVE, mainframe::OnUpdateFileSave) EVT_MENU(ID_AGENT_OPEN, mainframe::OnAgentOpen) EVT_MENU(ID_FILE_RELOAD, mainframe::OnFileReload) EVT_UPDATE_UI(ID_FILE_RELOAD, mainframe::OnUpdateFileReload) EVT_MENU(ID_HELP_ABOUT, mainframe::OnHelpAbout) EVT_MENU(ID_CONTEXT_PROPERTIES, mainframe::OnContextProperties) EVT_MENU(ID_CONTEXT_EDIT_SOURCE, mainframe::OnContextEditSource) EVT_MENU(ID_CONTEXT_COPY_FILENAME, mainframe::OnContextCopyFileName) EVT_MENU(ID_CONTEXT_COPY_PATH, mainframe::OnContextCopyPath) EVT_MENU(ID_CONTEXT_KINEMATIC, mainframe::OnContextKinematic) EVT_BUTTON(ID_LOG_CLEAR, mainframe::OnLogClear) EVT_BUTTON(ID_LOG_COPY, mainframe::OnLogCopy) EVT_CHECKBOX(ID_LOG_CHANNEL_DEBUG, mainframe::OnLogChannel) EVT_CHECKBOX(ID_LOG_CHANNEL_NORMAL, mainframe::OnLogChannel) EVT_CHECKBOX(ID_LOG_CHANNEL_WARNING, mainframe::OnLogChannel) EVT_CHECKBOX(ID_LOG_CHANNEL_ERROR, mainframe::OnLogChannel) EVT_TIMER(TI_LOG, mainframe::OnLogTimer) EVT_TIMER(TI_FPS, mainframe::OnFPSTimer) EVT_TREE_ITEM_EXPANDING(1, mainframe::OnTreeItemExpanding) EVT_TREE_SEL_CHANGED(1, mainframe::OnTreeSelChanged) EVT_TREE_ITEM_ACTIVATED(1, mainframe::OnTreeItemActivated) EVT_TREE_ITEM_RIGHT_CLICK(1, mainframe::OnTreeItemRightClick) EVT_FLATNOTEBOOK_PAGE_CLOSING(wxID_ANY, mainframe::OnTabClosing) EVT_FLATNOTEBOOK_PAGE_CHANGED(wxID_ANY, mainframe::OnTabChanged) EVT_FLATNOTEBOOK_CONTEXT_MENU(wxID_ANY, mainframe::OnTabContextMenu) EVT_MENU(ID_TAB_CLOSE, mainframe::OnTabClose) EVT_MENU(ID_TAB_CLOSE_OTHER, mainframe::OnTabCloseOther) EVT_MENU(ID_TAB_STARTSCRIPT, mainframe::OnTabStartScript) EVT_SCI_SAVEPOINTREACHED(wxID_ANY, mainframe::OnEditSavePointReached) EVT_SCI_SAVEPOINTLEFT(wxID_ANY, mainframe::OnEditSavePointLeft) EVT_MENU(wxID_UNDO, mainframe::OnEditCommand) EVT_MENU(wxID_REDO, mainframe::OnEditCommand) EVT_MENU(wxID_CUT, mainframe::OnEditCommand) EVT_MENU(wxID_COPY, mainframe::OnEditCommand) EVT_MENU(wxID_PASTE, mainframe::OnEditCommand) EVT_MENU(wxID_SELECTALL, mainframe::OnEditCommand) EVT_UPDATE_UI(wxID_UNDO, mainframe::OnUpdateEditCommand) EVT_UPDATE_UI(wxID_REDO, mainframe::OnUpdateEditCommand) EVT_UPDATE_UI(wxID_CUT, mainframe::OnUpdateEditCommand) EVT_UPDATE_UI(wxID_COPY, mainframe::OnUpdateEditCommand) EVT_UPDATE_UI(wxID_PASTE, mainframe::OnUpdateEditCommand) EVT_UPDATE_UI(wxID_SELECTALL, mainframe::OnUpdateEditCommand) EVT_SPARK_CONTEXT(ID_SPARK_CONTEXT, mainframe::OnSparkContext)END_EVENT_TABLE()using namespace boost;using namespace zeitgeist;using namespace kerosin;using namespace oxygen;mainframe::mainframe(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long /*style*/): wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE), mTimer(this,TI_LOG), mFPSTimer(this,TI_FPS){ mToolBar = 0; // begin wxGlade: mainframe::mainframe mCtrVertSplitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER); mRightPane = new wxPanel(mCtrVertSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL); mCtrHorSplitter = new wxSplitterWindow(mRightPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER); mBottomPane = new wxPanel(mCtrHorSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL); mTopPane = new wxPanel(mCtrHorSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL); mLeftPane = new wxPanel(mCtrVertSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL); window_1 = new wxSplitterWindow(mLeftPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DBORDER|wxSP_BORDER); window_1_pane_2 = new wxPanel(window_1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL); window_1_pane_1 = new wxPanel(window_1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL); MainFrame_menubar = new wxMenuBar(); SetMenuBar(MainFrame_menubar); wxMenu* wxglade_tmp_menu_1 = new wxMenu(); wxglade_tmp_menu_1->Append(ID_FILE_NEW, wxT("&New"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->Append(ID_FILE_OPEN, wxT("&Open\tctrl+o"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->Append(ID_FILE_SAVE, wxT("&Save\tctrl+s"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->Append(ID_FILE_SAVEAS, wxT("Save as..."), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->Append(ID_FILE_RELOAD, wxT("&Reload\tctrl+r"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->AppendSeparator(); wxglade_tmp_menu_1->Append(ID_AGENT_OPEN, wxT("Start &Agent"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_1->Append(wxID_EXIT, wxT("&Exit"), wxEmptyString, wxITEM_NORMAL); MainFrame_menubar->Append(wxglade_tmp_menu_1, wxT("&File")); wxMenu* wxglade_tmp_menu_2 = new wxMenu(); wxglade_tmp_menu_2->Append(wxID_UNDO, wxT("&Undo"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_2->Append(wxID_REDO, wxT("&Redo"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_2->AppendSeparator(); wxglade_tmp_menu_2->Append(wxID_CUT, wxT("Cu&t"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_2->Append(wxID_COPY, wxT("&Copy"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_2->Append(wxID_PASTE, wxT("&Paste"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_2->AppendSeparator(); wxglade_tmp_menu_2->Append(wxID_SELECTALL, wxT("Select &All"), wxEmptyString, wxITEM_NORMAL); MainFrame_menubar->Append(wxglade_tmp_menu_2, wxT("&Edit")); wxMenu* wxglade_tmp_menu_3 = new wxMenu(); wxglade_tmp_menu_3->Append(ID_VIEW_LOG, wxT("message &log"), wxT("Show/Hide message log"), wxITEM_CHECK); wxglade_tmp_menu_3->Append(ID_VIEW_TREE, wxT("object &tree"), wxT("Show/Hide object tree"), wxITEM_CHECK); MainFrame_menubar->Append(wxglade_tmp_menu_3, wxT("&View")); wxMenu* wxglade_tmp_menu_4 = new wxMenu(); wxglade_tmp_menu_4->Append(ID_SIM_STEP, wxT("St&ep"), wxEmptyString, wxITEM_NORMAL); wxglade_tmp_menu_4->Append(ID_SIM_START, wxT("&Start"), wxT("Start simulation"), wxITEM_NORMAL); wxglade_tmp_menu_4->Append(ID_SIM_PAUSE, wxT("&Pause"), wxT("Pause Simulation"), wxITEM_NORMAL); MainFrame_menubar->Append(wxglade_tmp_menu_4, wxT("&Simulation")); wxMenu* wxglade_tmp_menu_5 = new wxMenu(); wxglade_tmp_menu_5->Append(ID_HELP_ABOUT, wxT("&About"), wxEmptyString, wxITEM_NORMAL); MainFrame_menubar->Append(wxglade_tmp_menu_5, wxT("&Help")); MainFrame_statusbar = CreateStatusBar(1, 0); mCtrPropList = new wxListCtrl(window_1_pane_1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSIMPLE_BORDER); mCtrTree = new wxTreeCtrl(window_1_pane_2, 1, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_LINES_AT_ROOT|wxTR_DEFAULT_STYLE|wxSIMPLE_BORDER); mCtrNotebook = new wxFlatNotebook(mTopPane, wxID_ANY); mCtrLog = new wxTextCtrl(mBottomPane, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL|wxNO_BORDER); button_2 = new wxButton(mBottomPane, ID_LOG_CLEAR, wxT("Clear")); button_3 = new wxButton(mBottomPane, ID_LOG_COPY, wxT("Copy")); static_line_1 = new wxStaticLine(mBottomPane, wxID_ANY); label_2 = new wxStaticText(mBottomPane, wxID_ANY, wxT("Log Channels")); mCtrLogChannelDebug = new wxCheckBox(mBottomPane, ID_LOG_CHANNEL_DEBUG, wxT("Debug")); mCtrLogChannelNormal = new wxCheckBox(mBottomPane, ID_LOG_CHANNEL_NORMAL, wxT("Normal")); mCtrLogChannelWarning = new wxCheckBox(mBottomPane, ID_LOG_CHANNEL_WARNING, wxT("Warning")); mCtrLogChannelError = new wxCheckBox(mBottomPane, ID_LOG_CHANNEL_ERROR, wxT("Error")); set_properties(); do_layout(); // end wxGlade mCtrNotebook->SetWindowStyleFlag (mCtrNotebook->GetWindowStyleFlag() | wxFNB_DROPDOWN_TABS_LIST | wxFNB_X_ON_TAB | wxFNB_MOUSE_MIDDLE_CLOSES_TABS | wxFNB_VC8 ); mCanvas = new SparkGLCanvas(mCtrNotebook, wxID_ANY); mCanvas->SetLabel(wxT("simulation window")); mCtrNotebook->AddPage(mCanvas, wxT("Canvas")); SparkEdit::GetInstance().PrepareImageList(mCtrNotebook); mCtrNotebook->SetPageImageIndex(0, SparkEdit::GetInstance().II_SIMSPARK); // create toolbar mToolBar = CreateToolBar( wxTB_FLAT|wxTB_HORIZONTAL, wxID_ANY ); mToolBar->AddTool(ID_FILE_NEW, wxT("New"), wxBitmap(xpm_new)); mToolBar->AddTool(ID_FILE_OPEN, wxT("Open"), wxBitmap(xpm_open)); mToolBar->AddTool(ID_FILE_RELOAD, wxT("Reload"), wxBitmap(xpm_reload)); mToolBar->AddTool(ID_FILE_SAVE, wxT("Save"), wxBitmap(xpm_save)); mToolBar->AddSeparator(); mToolBar->AddTool(ID_AGENT_OPEN, wxT("Start Agent"), wxBitmap(xpm_agent)); mToolBar->AddSeparator(); mToolBar->AddTool(ID_SIM_STEP, wxT("Step"), wxBitmap(xpm_step)); mToolBar->AddTool(ID_SIM_START, wxT("Start"), wxBitmap(xpm_play)); mToolBar->AddTool(ID_SIM_PAUSE, wxT("Pause"), wxBitmap(xpm_pause)); mToolBar->AddSeparator(); mToolBar->AddTool(wxID_CUT, wxT("Cut"), wxBitmap(xpm_cut)); mToolBar->AddTool(wxID_COPY, wxT("Copy"), wxBitmap(xpm_copy)); mToolBar->AddTool(wxID_COPY, wxT("Paste"), wxBitmap(xpm_paste)); mToolBar->AddSeparator(); mToolBar->AddTool(wxID_UNDO, wxT("Undo"), wxBitmap(xpm_undo)); mToolBar->AddTool(wxID_REDO, wxT("Redo"), wxBitmap(xpm_redo)); mToolBar->AddSeparator(); mSimState = new wxTextCtrl( mToolBar, wxID_ANY, _T(""), wxDefaultPosition, wxSize(120, -1), wxTE_READONLY ); mToolBar->AddControl(mSimState); mToolBar->Realize(); SetToolBar(mToolBar); // // init horizontal splitterwindow (glcanvas / logwnd) wxSize szClient = GetClientSize(); mLastHorSashPosition = std::max<int>(1,szClient.y - LOGWND_DEFAULT_HEIGHT); SplitHor(); // init vertical splitterwindow mLastVertSashPosition = std::max<int>(1,TREEWND_DEFAULT_WIDTH); SplitVert(); // // init spark tree mSparkTree.Init(mCtrTree); InitTreeNodeProperties(); // init log wnd timer mTimer.Start(LOGWND_UPDATE_INTERVAL); // init spark context SparkContext::GetInstance().ResetSelection(); SparkContext::GetInstance().SetEventHandler(this, ID_SPARK_CONTEXT); PrintSimState(); UpdateTitle(); UpdateLogChannelState();}mainframe::~mainframe(){}void mainframe::UpdateTitle(){ wxString title(wxT("SimSpark")); if (SparkEdit::GetInstance().GetStartScript() != 0) { title += wxT(" <") + SparkEdit::GetInstance().GetStartScriptFile() + wxT(">"); } SetTitle(title);}void mainframe::SplitHor(){ mCtrHorSplitter->SplitHorizontally(mTopPane, mBottomPane); mCtrHorSplitter->SetSashPosition(mLastHorSashPosition);#if wxCHECK_VERSION(2,5,4) mCtrHorSplitter->SetSashGravity(1.0);#endif}void mainframe::SplitVert(){ mCtrVertSplitter->SplitVertically(mLeftPane, mRightPane); mCtrVertSplitter->SetSashPosition(mLastVertSashPosition);#if wxCHECK_VERSION(2,5,4) // only resize right pane when window is resized mCtrVertSplitter->SetSashGravity(0.0);#endif}void mainframe::set_properties(){ // begin wxGlade: mainframe::set_properties SetTitle(wxT("RsgEdit")); SetSize(wxSize(1076, 786)); int MainFrame_statusbar_widths[] = { 0 }; MainFrame_statusbar->SetStatusWidths(1, MainFrame_statusbar_widths); const wxString MainFrame_statusbar_fields[] = { wxT("Welcome to RsgEdit") }; for(int i = 0; i < MainFrame_statusbar->GetFieldsCount(); ++i) { MainFrame_statusbar->SetStatusText(MainFrame_statusbar_fields[i], i); } // end wxGlade}void mainframe::do_layout(){ // begin wxGlade: mainframe::do_layout wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_2 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_6 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizer_11 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_5 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_7 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_8 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_4 = new wxBoxSizer(wxVERTICAL); sizer_4->Add(mCtrPropList, 1, wxEXPAND, 0); window_1_pane_1->SetSizer(sizer_4); sizer_8->Add(mCtrTree, 1, wxEXPAND, 0); window_1_pane_2->SetSizer(sizer_8); window_1->SplitHorizontally(window_1_pane_1, window_1_pane_2); sizer_7->Add(window_1, 1, wxEXPAND, 0); mLeftPane->SetSizer(sizer_7); sizer_5->Add(mCtrNotebook, 1, wxEXPAND, 0); mTopPane->SetSizer(sizer_5); sizer_6->Add(mCtrLog, 1, wxEXPAND, 0); sizer_11->Add(button_2, 0, wxALL|wxEXPAND, 5); sizer_11->Add(button_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5); sizer_11->Add(static_line_1, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5); sizer_11->Add(label_2, 0, wxALL, 5); sizer_11->Add(mCtrLogChannelDebug, 0, wxLEFT|wxRIGHT|wxBOTTOM, 5); sizer_11->Add(mCtrLogChannelNormal, 0, wxLEFT|wxRIGHT|wxBOTTOM, 5); sizer_11->Add(mCtrLogChannelWarning, 0, wxLEFT|wxRIGHT|wxBOTTOM, 5); sizer_11->Add(mCtrLogChannelError, 0, wxLEFT|wxRIGHT|wxBOTTOM, 5); sizer_6->Add(sizer_11, 0, 0, 0); mBottomPane->SetSizer(sizer_6); mCtrHorSplitter->SplitHorizontally(mTopPane, mBottomPane); sizer_2->Add(mCtrHorSplitter, 1, wxEXPAND, 0); mRightPane->SetSizer(sizer_2); mCtrVertSplitter->SplitVertically(mLeftPane, mRightPane); sizer_1->Add(mCtrVertSplitter, 1, wxEXPAND, 0); SetSizer(sizer_1); Layout(); // end wxGlade}ESimState mainframe::GetSimState() const{ shared_ptr<SimSpark> spark = wxGetApp().GetSpark(); if (spark.get() == 0) { assert(false); return S_PAUSED; } return spark->GetSimState();}bool mainframe::CanClose(){ shared_ptr<SimSpark> spark = wxGetApp().GetSpark(); if ( (spark.get() != 0) && (spark->GetSimState() == S_RUNNING) ) { return false; } return true;}void mainframe::OnClose( wxCloseEvent& event ){ if (! CanClose()) { PauseSimulation(); event.Veto(); return; } int n = mCtrNotebook->GetPageCount(); for (int i=(n-1);i>=0;--i) { wxWindow* page = mCtrNotebook->GetPage(i); if (page == mCanvas) { continue; } if (! mCtrNotebook->RemovePage(i)) { event.Veto(); return; } } // close agentframes wxWindowList& children = GetChildren(); for ( wxWindowList::Node *node = children.GetFirst(); node != 0; node = node->GetNext() ) { agentframe* af = dynamic_cast<agentframe*>(node->GetData()); if (af == 0) { continue; } af->Close(); } event.Skip();}void mainframe::OnExit( wxCommandEvent& WXUNUSED(event) ){ Close();}void mainframe::OnUpdateStartSimulation(wxUpdateUIEvent& event){ event.Enable(GetSimState() == S_PAUSED);}void mainframe::OnStartSimulation(wxCommandEvent& /*event*/){ bool singleStep = false; StartSimulation(singleStep);}void mainframe::OnUpdateStepSimulation(wxUpdateUIEvent& event){ event.Enable(GetSimState() == S_PAUSED);}void mainframe::OnStepSimulation(wxCommandEvent& /*event*/){ bool singleStep = true; StartSimulation(singleStep);}void mainframe::OnUpdatePauseSimulation(wxUpdateUIEvent& event){ event.Enable(GetSimState() == S_RUNNING);}void mainframe::OnPauseSimulation(wxCommandEvent& /*event*/){ PauseSimulation();}void mainframe::OnLogTimer(wxTimerEvent& /*event*/){ UpdateLogWindow();}void mainframe::OnFPSTimer(wxTimerEvent& /*event*/){ shared_ptr<SimSpark> spark = wxGetApp().GetSpark(); if ( (spark.get() == 0) || (spark->GetSimState() != S_PAUSED) ) { return; } shared_ptr<InputControl> inputCtr = spark->GetInputControl(); if (inputCtr.get() == 0) { return; } inputCtr->StartCycle(); shared_ptr<FPSController> fps = inputCtr->GetFPSController(); if ( (fps.get() == 0) || (! fps->NeedStaticUpdate()) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -