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 + -
显示快捷键?