📄 structure_window.cpp
字号:
menu->Append(MID_EDIT_CDD_REFERENCES, "Edit PubMed &References");// menu->Enable(MID_EDIT_CDD_REFERENCES, !readOnly); menu->Append(MID_EDIT_CDD_BOOK_REFERENCES, "Edit &Book References");// menu->Enable(MID_EDIT_CDD_BOOK_REFERENCES, !readOnly); menu->Append(MID_ANNOT_CDD, "Edit &Annotations"); menu->Enable(MID_ANNOT_CDD, !readOnly); menu->AppendSeparator(); menu->Append(MID_CDD_REJECT_SEQ, "Re&ject Sequence"); menu->Enable(MID_CDD_REJECT_SEQ, !readOnly); menu->Append(MID_CDD_SHOW_REJECTS, "&Show Rejects"); menuBar->Append(menu, "&CDD"); // Help menu menu = new wxMenu; menu->Append(MID_HELP_COMMANDS, "&Commands"); menu->Append(MID_ONLINE_HELP, "Online &Help..."); menu->Append(MID_ABOUT, "&About"); menuBar->Append(menu, "&Help"); // accelerators for special keys wxAcceleratorEntry entries[12]; entries[0].Set(wxACCEL_NORMAL, WXK_RIGHT, MID_NEXT_FRAME); entries[1].Set(wxACCEL_NORMAL, WXK_LEFT, MID_PREV_FRAME); entries[2].Set(wxACCEL_NORMAL, WXK_DOWN, MID_FIRST_FRAME); entries[3].Set(wxACCEL_NORMAL, WXK_UP, MID_LAST_FRAME); entries[4].Set(wxACCEL_NORMAL, 'z', MID_ZOOM_IN); entries[5].Set(wxACCEL_NORMAL, 'x', MID_ZOOM_OUT); entries[6].Set(wxACCEL_NORMAL, 'a', MID_ALL_FRAMES); entries[7].Set(wxACCEL_NORMAL, 'p', MID_PLAY); entries[8].Set(wxACCEL_NORMAL, 'n', MID_SPIN); entries[9].Set(wxACCEL_NORMAL, 's', MID_STOP); entries[10].Set(wxACCEL_NORMAL, 'e', MID_SHOW_ALL); entries[11].Set(wxACCEL_NORMAL, 'd', MID_SHOW_DOMAINS); wxAcceleratorTable accel(12, entries); SetAcceleratorTable(accel); // set menu bar and initial states SetMenuBar(menuBar); menuBar->EnableTop(menuBar->FindMenu("CDD"), false); menuBar->Check(MID_STEREO, false); // Make a GLCanvas#if defined(__WXMSW__) int *attribList = NULL;#elif defined(__WXGTK__) int *attribList = NULL;#elif defined(__WXMAC__) int *attribList = NULL;#endif glCanvas = new Cn3DGLCanvas(this, attribList); // set initial font Show(true); // on X, need to establish gl context first, which requires visible window glCanvas->SetCurrent(); glCanvas->SetGLFontFromRegistry();}StructureWindow::~StructureWindow(void){ delete commandProcessor;}void StructureWindow::OnCloseWindow(wxCloseEvent& event){ animationTimer.Stop(); fileMessagingTimer.Stop(); Command(MID_EXIT);}void StructureWindow::OnExit(wxCommandEvent& event){ animationTimer.Stop(); fileMessagingTimer.Stop(); GlobalMessenger()->RemoveStructureWindow(this); // don't bother with any redraws since we're exiting GlobalMessenger()->SequenceWindowsSave(true); // save any edited alignment and updates first SaveDialog(true, false); // give structure window a chance to save data SaveFavorites(); if (IsFileMessengerActive()) SendCommand(messageTargetApp, "Cn3DTerminated", ""); // remove help window if present if (helpController) { if (helpController->GetFrame()) helpController->GetFrame()->Close(true); wxConfig::Set(NULL); delete helpConfig; // saves data delete helpController; } DestroyNonModalDialogs(); Destroy();}void StructureWindow::SetupFileMessenger(const std::string& messageFilename, const std::string& messageApp, bool readOnly){ if (fileMessenger) return; // create messenger fileMessenger = fileMessagingManager.CreateNewFileMessenger(messageFilename, this, readOnly); fileMessagingTimer.SetOwner(this, MID_MESSAGING); fileMessagingTimer.Start(200, false); // add menu item for file messaging selection messageTargetApp = messageApp; windowMenu->AppendSeparator(); windowMenu->Append(MID_SEND_SELECTION, (string("Sen&d Selection to ") + messageTargetApp).c_str());}void StructureWindow::OnFileMessagingTimer(wxTimerEvent& event){ // poll message files fileMessagingManager.PollMessageFiles();}void StructureWindow::ReceivedCommand(const std::string& fromApp, unsigned long id, const std::string& command, const std::string& data){ INFOMSG("received command " << id << " from " << fromApp << ": " << command); // default reply - should be changed by CommandProcessor MessageResponder::ReplyStatus replyStatus = MessageResponder::REPLY_ERROR; string replyData = "failed to process\n"; // actually perform the command functions commandProcessor->ProcessCommand(command, data, &replyStatus, &replyData); // reply INFOMSG("reply: " << ((replyStatus == MessageResponder::REPLY_OKAY) ? "OKAY" : "ERROR")); if (replyData.size() > 0) TRACEMSG("data:\n" << replyData.substr(0, replyData.size() - 1)); else TRACEMSG("data: (none)"); fileMessenger->SendReply(fromApp, id, replyStatus, replyData);}void StructureWindow::ReceivedReply(const std::string& fromApp, unsigned long id, MessageResponder::ReplyStatus status, const std::string& data){ // just post a message for now; eventually may pass on to CommandProcessor if (status == MessageResponder::REPLY_OKAY) INFOMSG(fromApp << ": got OKAY from " << fromApp << " (command " << id << "), data: " << data); else ERRORMSG(fromApp << ": got ERROR from " << fromApp << " (command " << id << "), data: " << data);}void StructureWindow::SendCommand(const std::string& toApp, const std::string& command, const std::string& data){ if (!IsFileMessengerActive()) { ERRORMSG("SendCommand: no message file active!"); return; } // for now, just assign command id's in numerical order static unsigned long nextCommandID = 1; INFOMSG("sending command " << nextCommandID << " to " << toApp << ": " << command); fileMessenger->SendCommand(toApp, ++nextCommandID, command, data);}void StructureWindow::OnSendSelection(wxCommandEvent& event){ if (!fileMessenger) { ERRORMSG("Can't send messages when return messaging is off"); return; } string data; if (GlobalMessenger()->GetHighlightsForSelectionMessage(&data)) SendCommand(messageTargetApp, "Select", data);}void StructureWindow::SetWindowTitle(void){ SetTitle(wxString(GetWorkingTitle().c_str()) + " - Cn3D " + CN3D_VERSION_STRING);}void StructureWindow::OnHelp(wxCommandEvent& event){ if (event.GetId() == MID_HELP_COMMANDS) { if (!helpController) { wxString path = wxString(GetPrefsDir().c_str()) + "help_cache"; if (!wxDirExists(path)) { INFOMSG("trying to create help cache folder " << path.c_str()); wxMkdir(path); } helpController = new wxHtmlHelpController(wxHF_DEFAULTSTYLE); helpController->SetTempDir(path); path = path + wxFILE_SEP_PATH + "Config"; INFOMSG("saving help config in " << path.c_str()); helpConfig = new wxFileConfig("Cn3D", "NCBI", path); wxConfig::Set(helpConfig); helpController->UseConfig(wxConfig::Get());#ifdef __WXMAC__ path = wxString(GetProgramDir().c_str()) + "../Resources/cn3d_commands.htb";#else path = wxString(GetProgramDir().c_str()) + "cn3d_commands.htb";#endif if (!helpController->AddBook(path)) ERRORMSG("Can't load help book at " << path.c_str()); } if (event.GetId() == MID_HELP_COMMANDS) helpController->Display("Cn3D Commands"); } else if (event.GetId() == MID_ONLINE_HELP) { LaunchWebPage("http://www.ncbi.nlm.nih.gov/Structure/CN3D/cn3d.shtml"); } else if (event.GetId() == MID_ABOUT) { wxString message( "Cn3D version " CN3D_VERSION_STRING "\n\n" "Produced by the National Center for Biotechnology Information\n" " http://www.ncbi.nlm.nih.gov\n\n" "Please direct all questions and comments to:\n" " info@ncbi.nlm.nih.gov" ); wxMessageBox(message, "About Cn3D", wxOK | wxICON_INFORMATION, this); }}void StructureWindow::OnDistanceSelect(wxCommandEvent& event){ if (!glCanvas->structureSet) return; static double latestCutoff = 5.0; GetFloatingPointDialog dialog(this, "Enter a distance cutoff (in Angstroms):", "Distance?", 0.0, 1000.0, 0.5, latestCutoff); if (dialog.ShowModal() == wxOK) { latestCutoff = dialog.GetValue(); glCanvas->structureSet->SelectByDistance(latestCutoff, (event.GetId() == MID_DIST_SELECT_RESIDUES || event.GetId() == MID_DIST_SELECT_OTHER_RESIDUES), (event.GetId() == MID_DIST_SELECT_OTHER_RESIDUES || event.GetId() == MID_DIST_SELECT_OTHER_ALL)); }}void StructureWindow::OnPNG(wxCommandEvent& event){ ExportPNG(glCanvas);}void StructureWindow::OnAnimate(wxCommandEvent& event){ if (event.GetId() != MID_ANIM_CONTROLS) { menuBar->Check(MID_PLAY, false); menuBar->Check(MID_SPIN, false); menuBar->Check(MID_STOP, true); } if (!glCanvas->structureSet) return; // play frames if (event.GetId() == MID_PLAY) { if (glCanvas->structureSet->frameMap.size() > 1) { int delay; if (!RegistryGetInteger(REG_ANIMATION_SECTION, REG_FRAME_DELAY, &delay)) return; animationTimer.Start(delay, false); animationMode = ANIM_FRAMES; menuBar->Check(MID_PLAY, true); menuBar->Check(MID_STOP, false); } } // spin if (event.GetId() == MID_SPIN) { int delay; if (!RegistryGetInteger(REG_ANIMATION_SECTION, REG_SPIN_DELAY, &delay) || !RegistryGetDouble(REG_ANIMATION_SECTION, REG_SPIN_INCREMENT, &spinIncrement)) return; animationTimer.Start(delay, false); animationMode = ANIM_SPIN; menuBar->Check(MID_SPIN, true); menuBar->Check(MID_STOP, false); } // stop else if (event.GetId() == MID_STOP) { animationTimer.Stop(); } // controls else if (event.GetId() == MID_ANIM_CONTROLS) { AnimationControls dialog(this); dialog.ShowModal(); // restart timer to pick up new settings if (animationTimer.IsRunning()) { animationTimer.Stop(); Command((animationMode == ANIM_SPIN) ? MID_SPIN : MID_PLAY); } }}void StructureWindow::OnAnimationTimer(wxTimerEvent& event){ if (animationMode == ANIM_FRAMES) { // simply pretend the user selected "next frame" Command(MID_NEXT_FRAME); } else if (animationMode == ANIM_SPIN) { // pretend the user dragged the mouse to the right glCanvas->renderer->ChangeView(OpenGLRenderer::eXYRotateHV, spinIncrement/glCanvas->renderer->GetRotateSpeed(), 0); glCanvas->Refresh(false); }}void StructureWindow::OnSetFont(wxCommandEvent& event){ string section, faceName; if (event.GetId() == MID_OPENGL_FONT) section = REG_OPENGL_FONT_SECTION; else if (event.GetId() == MID_SEQUENCE_FONT) section = REG_SEQUENCE_FONT_SECTION; else return; // get initial font info from registry, and create wxFont string nativeFont; RegistryGetString(section, REG_FONT_NATIVE_FONT_INFO, &nativeFont); auto_ptr<wxFont> initialFont(wxFont::New(wxString(nativeFont.c_str()))); if (!initialFont.get() || !initialFont->Ok()) { ERRORMSG("StructureWindow::OnSetFont() - error setting up initial font"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -