align_mark_handler.cpp
来自「ncbi源码」· C++ 代码 · 共 724 行 · 第 1/2 页
CPP
724 行
/* * =========================================================================== * PRODUCTION $Log: align_mark_handler.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 21:06:57 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17 * PRODUCTION * =========================================================================== *//* $Id: align_mark_handler.cpp,v 1000.3 2004/06/01 21:06:57 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Andrey Yazhuk * * File Description: * CAlignMarkHandler - class implementing support for Marks in alignments. * IAlignMarkHandlerHost - context in which CAlignMarkHandler operates. */#include <ncbi_pch.hpp>#include <FL/Fl.H>#include <FL/Enumerations.H>#include <gui/widgets/aln_multiple/align_mark_handler.hpp>#include <gui/widgets/aln_multiple/alnmulti_settings.hpp>#include <math.h>BEGIN_NCBI_SCOPEUSING_SCOPE(objects);CAlignMarkHandler::CAlignMarkHandler(): m_pHost(NULL), m_pPane(NULL), m_bHitResizable(false), m_State(eIdle), m_Cursor(FL_CURSOR_DEFAULT), m_PrevPos((TSeqPos)-1), m_FillColor(0.5f, 0.5f, 1.0f, 0.5f), m_FrameColor(0.25f, 0.25f, 0.5f, 1.0f) { }void CAlignMarkHandler::SetHost(IAlignMarkHandlerHost* pHost){ m_pHost = pHost;}//FLTK-like event handlerint CAlignMarkHandler::handle(CGUIEvent& event, CGlPane& pane){ m_pPane = &pane; int res = 0; switch(event.GetFLTKEvent()) { case FL_PUSH: res = x_OnMousePush(event); break; case FL_DRAG: res = x_OnMouseDrag(event); break; case FL_RELEASE: res = x_OnMouseRelease(event); break; case FL_MOVE: res = x_OnMouseMove(event); break; case FL_KEYDOWN: res = x_OnKeyDown(event); break; case FL_KEYUP: res = x_OnKeyUp(event); break; } m_pPane = 0; return res;}////////////////////////////////////////////////////////////////////////////////// opeartions with Markvoid CAlignMarkHandler::MarkSelectedRows(const TRangeColl& C, bool bMark){ const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel(); TSelListModel::TIndexVector vSel; pModel->SLM_GetSelectedIndices(vSel); const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS(); ITERATE(TSelListModel::TIndexVector, it, vSel) { // for each Mark TNumrow Row = pModel->SLM_GetItem(*it); TRowToMarkMap::iterator itM = m_mpRowToMark.find(Row); if(itM == m_mpRowToMark.end()) itM = m_mpRowToMark.insert(TRowToMarkMap::value_type(Row, TRangeColl())).first; TRangeColl& Mark = itM->second; ITERATE(TRangeColl, itR, C) { // for each Range in C // translate Range to sequence coordinates TSeqPos From = pAlnDS->GetSeqPosFromAlnPos(Row, itR->GetFrom(), IAlnMultiDataSource:: TSearchDirection::eRight); TSeqPos To = pAlnDS->GetSeqPosFromAlnPos(Row, itR->GetTo(), IAlnMultiDataSource:: TSearchDirection::eRight); TSeqRange R(From, To); // modify Mark if(bMark) Mark += R; else Mark -= R; } }}void CAlignMarkHandler::UnMarkAll(){ m_mpRowToMark.clear();}void CAlignMarkHandler::UnMarkSelected(){ // get selected lines const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel(); TSelListModel::TIndexVector vIndices; pModel->SLM_GetSelectedIndices(vIndices); // for each selected Line ITERATE(TSelListModel::TIndexVector, it, vIndices) { TNumrow Row = x_GetHost()->MHH_GetRowByLine(*it); m_mpRowToMark.erase(Row); }}const CAlignMarkHandler::TRowToMarkMap& CAlignMarkHandler::GetMarks() const{ return m_mpRowToMark;}////////////////////////////////////////////////////////////////////////////////// event handlersint CAlignMarkHandler::x_OnMousePush(CGUIEvent& event){ if(event.GetGUIState() == CGUIEvent::eMarkState && event.GetGUISignal() == CGUIEvent::ePush) { if(Fl::event_clicks() == 0) { x_OnStartSel(); x_OnSelectCursor(); } return 1; } return 0;}int CAlignMarkHandler::x_OnMouseDrag(CGUIEvent& event){ if(m_State == eResize && event.GetGUIState() == CGUIEvent::eMarkState) { x_OnChangeSelRange(); } return 1; // always handle drags}int CAlignMarkHandler::x_OnMouseRelease(CGUIEvent& event){ if(m_State != eIdle) { if(event.GetGUISignal() == CGUIEvent::eRelease) { if(m_State == eResize) { bool b_mark = (event.GetGUIState() == CGUIEvent::eMarkState); EState new_state = b_mark ? eReady : eIdle; x_OnEndSelRange(new_state); } return 1; } } return 0;}int CAlignMarkHandler::x_OnMouseMove(CGUIEvent& event){ //if(x_OpKeyPressed()) { if(event.GetGUIState() == CGUIEvent::eMarkState) { x_OnSelectCursor(); return 1; } else return 0;}int CAlignMarkHandler::x_OnKeyDown(CGUIEvent& event){ if(event.GetGUIState() == CGUIEvent::eMarkState) { int k = Fl::event_key(); if(k == FL_Delete) { UnMarkSelected(); x_GetHost()->MHH_Redraw(); return 1; } x_UpdateState(true); } return 0;}int CAlignMarkHandler::x_OnKeyUp(CGUIEvent& event){ //int k = Fl::event_key(); //if(k == FL_Control_L || k == FL_Control_R) { //Control is released if(m_State == eResize) { if(event.GetGUIState() != CGUIEvent::eMarkState) { EState new_state = (event.GetGUIState() == CGUIEvent::eMarkState) ? eReady : eIdle; x_OnEndSelRange(new_state); } else x_UpdateState(true); } return 0;}/////////////////////////////////////////////////////////////////////////////////// Signal handlersvoid CAlignMarkHandler::x_OnStartSel(){ if(x_HitSelectedLine()) { m_PrevPos = (TSeqPos) -1; x_InitDeltaMap(); m_State = eResize; m_pHost->MHH_Redraw(); }}void CAlignMarkHandler::x_OnChangeSelRange(){ TModelUnit mX = x_MouseToSeqPos(); TSeqPos Pos = (TSeqPos) floor(mX); Pos = x_ClipPosByRange(Pos); if(Pos != m_PrevPos) { x_UpdateSelection(Pos); m_pHost->MHH_Redraw(); } m_PrevPos = Pos;}void CAlignMarkHandler::x_OnEndSelRange(EState new_state){ x_OnChangeSelRange(); x_UpdateMarks(); //m_State = x_OpKeyPressed() ? eReady : eIdle; m_State = new_state; x_OnSelectCursor(); m_pHost->MHH_Redraw(); }void CAlignMarkHandler::x_OnResetAll(){ m_mpRowToMark.clear(); m_mpRowToDelta.clear(); m_State = eIdle; m_PrevPos = (TSeqPos) -1; m_pHost->MHH_Redraw();}void CAlignMarkHandler::x_UpdateState(bool b_key){ //bool b_key = x_OpKeyPressed(); bool bHit = x_HitSelectedLine(); EState NewState = m_State; switch(m_State) { case eIdle: case eReady: NewState = (b_key && bHit) ? eReady : eIdle; break; case eResize: NewState = b_key ? eResize : eIdle; break; } if(NewState != m_State) { m_State = NewState; x_OnSelectCursor(); m_pHost->MHH_Redraw(); } }// Select cursor depending on the current state and mouse positionvoid CAlignMarkHandler::x_OnSelectCursor(){ switch(m_State) { case eIdle: m_Cursor = FL_CURSOR_DEFAULT; break; case eReady: { if(x_HitSelectedLine()) { m_Cursor = x_HitRangeBorder() ? FL_CURSOR_WE : FL_CURSOR_INSERT; } else m_Cursor = FL_CURSOR_DEFAULT; }; break; case eResize: m_Cursor = FL_CURSOR_WE; break; default: break; } fl_cursor(m_Cursor, FL_BLACK, FL_WHITE);}/////////////////////////////////////////////////////////////////////////////////// helper functions// returns true if modifier Key assigned to the operations with Mark is pressedbool CAlignMarkHandler::x_OpKeyPressed() const{ int ModState = Fl::event_state() & (FL_SHIFT | FL_ALT | FL_CTRL); return ModState == FL_CTRL;}//returns true if no conflicting modifier keys are pressedbool CAlignMarkHandler::x_ModifiersOk() const{ int State = Fl::event_state() & (FL_SHIFT | FL_ALT); return State == 0;}// converts mouse X position to the position in AlignmentTModelUnit CAlignMarkHandler::x_MouseToSeqPos(){ _ASSERT(m_pPane); int x = Fl::event_x(); return m_pHost->MHH_GetSeqPosByX(x) + 0.5;}// functions creates a "Delta" map for ranges that will be resizedvoid CAlignMarkHandler::x_InitDeltaMap(){ m_mpRowToDelta.clear(); int X = Fl::event_x(); // get selected lines const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel(); TSelListModel::TIndexVector vIndices; pModel->SLM_GetSelectedIndices(vIndices); const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS(); // for each selected Line ITERATE(TSelListModel::TIndexVector, it, vIndices) { TNumrow Row = x_GetHost()->MHH_GetRowByLine(*it); TSeqRange HitR; // hit testing Mark corresponding to the Row (if it exists)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?