align_mark_handler.cpp

来自「ncbi源码」· C++ 代码 · 共 724 行 · 第 1/2 页

CPP
724
字号
        bool bHitStart = false;        SMarkDelta::EExtState StartState, State;        TRowToMarkMap::iterator itM = m_mpRowToMark.find(Row);        if(itM != m_mpRowToMark.end())   {            TRangeColl& Mark = itM->second;            x_HitTest(Row, Mark, X, HitR, bHitStart);        } else { // if Mark does not exist - create it			m_mpRowToMark[Row] = TRangeColl(); 		}                TSeqPos StartPos;        if(HitR.NotEmpty()) {   // hit a border of the marked range            StartState = State = bHitStart ? SMarkDelta::eExtRangeStart : SMarkDelta::eExtRangeEnd;            StartPos = bHitStart ? HitR.GetFrom() : HitR.GetToOpen();                } else {                    StartState = SMarkDelta::eNoExt;            State = SMarkDelta::eExtRangeEnd;                TModelUnit mX = x_MouseToSeqPos(); //###            StartPos = (TSeqPos) floor(mX);            StartPos = pAlnDS->GetSeqPosFromAlnPos(Row, StartPos,                                                   IAlnMultiDataSource::                                                   TSearchDirection::eRight);            HitR.SetFrom(StartPos);            HitR.SetLength(0);        }    	    // initate Map record            m_mpRowToDelta[Row] = SMarkDelta(HitR, TSeqRange(StartPos, StartPos - 1), StartState, State);            }}//returns true if mouse pointer is over selected linebool    CAlignMarkHandler::x_HitSelectedLine(){    const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();    int Y = Fl::event_y();    int Index = x_GetHost()->MHH_GetLineByWindowY(Y);    return Index >=0  &&  pModel->SLM_IsItemSelected(Index); }// returns true if mouse pointer is located over the end of one of the marked segmentsbool    CAlignMarkHandler::x_HitRangeBorder() const{    int X = Fl::event_x();    int Y = Fl::event_y();    int Index = x_GetHost()->MHH_GetLineByWindowY(Y);        if(Index >= 0)  {        const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();               if(pModel->SLM_IsItemSelected(Index))   {             TNumrow Row = x_GetHost()->MHH_GetRowByLine(Index);            TSeqRange HitR;            bool bHitStart = false;            // test the Mark corresponding to the Row            TRowToMarkMap::const_iterator it = m_mpRowToMark.find(Row);            if(it != m_mpRowToMark.end())   {                const TRangeColl& Mark = it->second;                x_HitTest(Row, Mark, X, HitR, bHitStart);                if(HitR.NotEmpty())                    return true;            }        }    }    return false;}// perfroms a hit test of a given position "X" agains given TRangeColl C// if positions hits a range in the C, this range is returned in "Range"// (in "sequence" coordinates), overwise "Range" is set empty. If position // hits the start of a range then "bHitStart" is assigned "true"void    CAlignMarkHandler::x_HitTest(TNumrow Row, const TRangeColl& C, int X, TSeqRange& Range, bool& bHitStart) const{    _ASSERT(m_pPane);            int MinD = -1;    bool bMinStart = false;    TRangeColl::const_iterator itMinRange = C.end();    const IAlnMultiDataSource *pAlnDS = x_GetHost()->MHH_GetAlnDS();    ITERATE(TRangeColl, itR, C)  { // iterating by Ranges in C        TSeqPos From = pAlnDS->GetAlnPosFromSeqPos(Row, itR->GetFrom());        TSeqPos To = pAlnDS->GetAlnPosFromSeqPos(Row, itR->GetTo());        TSeqRange  AlnR(From, To);        int FromX = m_pPane->ProjectX(AlnR.GetFrom());        int ToX = m_pPane->ProjectX(AlnR.GetToOpen());                int D = abs(X - FromX); // distance from the start of the range        if(MinD < 0 || MinD > D)    {            MinD = D;            bMinStart = true;            itMinRange = itR;        }        D = abs(X - ToX); // distance from the stop of the range        if(MinD > D)    {            MinD = D;            bMinStart = false;            itMinRange = itR;        }            }    if(MinD > -1  && MinD <= CAlnMultiSettings::GetDragThreshold()) {        bHitStart = bMinStart;        _ASSERT(itMinRange != C.end());        Range  = *itMinRange;    } else Range.SetLength(0);}TSeqPos CAlignMarkHandler::x_ClipPosByRange(TSeqPos Pos){    TModelRect rcL = m_pPane->GetModelLimitsRect();    Pos = min(Pos, (TSeqPos) rcL.Right() - 1);    Pos = max(Pos, (TSeqPos) rcL.Left());    return Pos;}// updates Ranges being dragged accordingly to the given positionvoid    CAlignMarkHandler::x_UpdateSelection(TSeqPos Pos){    const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS();    NON_CONST_ITERATE(TRowToDeltaMap, it, m_mpRowToDelta)    {        SMarkDelta& Delta = it->second;        TSeqPos SeqPos = pAlnDS->GetSeqPosFromAlnPos(it->first, Pos,                                                     IAlnMultiDataSource::                                                     TSearchDirection::eRight);        x_UpdateDelta(Delta.m_Range, Delta.m_State, SeqPos);    }}// update given range so that the range end specified by "State" becomes equal// to "Pos".void    CAlignMarkHandler::x_UpdateDelta(TSeqRange& R,                                     SMarkDelta::EExtState& State, TSeqPos Pos){    if(State == SMarkDelta::eNoExt  &&  Pos != R.GetFrom())   {        if(Pos > R.GetFrom()) {            R.SetToOpen(Pos);            State = SMarkDelta::eExtRangeEnd;        } else  {            R.SetToOpen(R.GetFrom());            R.SetFrom(Pos);            State = SMarkDelta::eExtRangeStart;        }    } else if(State == SMarkDelta::eExtRangeEnd &&  Pos != R.GetToOpen()) {        if(Pos > R.GetFrom())  {             R.SetToOpen(Pos);        } else { //flip            R.SetToOpen(R.GetFrom());            R.SetFrom(Pos);            State = SMarkDelta::eExtRangeStart;        }    } else if(State == SMarkDelta::eExtRangeStart  &&  Pos != R.GetFrom())    {        if(Pos <= R.GetToOpen())  {             R.SetFrom(Pos);        } else {            R.SetFrom(R.GetToOpen());            R.SetToOpen(Pos);            State = SMarkDelta::eExtRangeEnd;        }    }}void CAlignMarkHandler::x_UpdateMarks(){    ITERATE(TRowToDeltaMap, it, m_mpRowToDelta)    {        TNumrow Row = it->first;        TRowToMarkMap::iterator itMark = m_mpRowToMark.find(Row);        if(itMark == m_mpRowToMark.end())   {            itMark = m_mpRowToMark.insert(                        TRowToMarkMap::value_type(Row, TRangeColl())).first;        }        TRangeColl& C = itMark->second;        const SMarkDelta& Delta = it->second;            const TSeqRange& R = Delta.m_Range;        const TSeqRange& HitR = Delta.m_HitRange;                switch(Delta.m_StartState)  {        case SMarkDelta::eNoExt:    {            if(R.NotEmpty())                C.CombineWith(R);        }; break;        case SMarkDelta::eExtRangeEnd:  {            if(R.GetTo() > HitR.GetTo())  {                C.CombineWith(R);            } else {                TSeqPos P = max(HitR.GetFrom(), R.GetFrom());                C.Subtract(TSeqRange(P, HitR.GetTo()));                if(R.GetFrom() < HitR.GetFrom())                    C.CombineWith(TSeqRange(R.GetFrom(), HitR.GetFrom() - 1));            }        }; break;        case SMarkDelta::eExtRangeStart:  {            if(R.GetFrom() < HitR.GetFrom())  {                C.CombineWith(R);            } else {                TSeqPos P = min(HitR.GetTo(), R.GetTo());                C.Subtract(TSeqRange(HitR.GetFrom(), P));                if(R.GetTo() > HitR.GetTo())                    C.CombineWith(TSeqRange(HitR.GetToOpen(), R.GetTo()));            }        }; break;        };    }    m_mpRowToDelta.clear();}void    CAlignMarkHandler::Render(CGlPane& pane){    TModelRect rcV = pane.GetVisibleRect();        const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS();    const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();             if(! rcV.IsEmpty()  && pAlnDS  && pModel) {        TVPRect rcVP = pane.GetViewport();        pane.OpenOrtho();        TModelUnit offset_x = pane.GetOffsetX();        TModelUnit offset_y = pane.GetOffsetY();                ITERATE(TRowToMarkMap, itM, m_mpRowToMark)  { // for each Mark            TNumrow Row = itM->first;             int Index = x_GetHost()->MHH_GetLineByRowNum(Row);                                        if(Index >= 0)  { // row exists                                                TModelUnit top_y = x_GetHost()->MHH_GetLinePosY(Index);                TModelUnit bottom_y = top_y + x_GetHost()->MHH_GetLineHeight(Index) - 1;                bool bVisible = ! (bottom_y < rcV.Top()  ||  top_y > rcV.Bottom());                                if(bVisible) {                    bool bSelected = pModel->SLM_IsItemSelected(Index);                    const TRangeColl& Mark = itM->second;                    // draw existing mark                    ITERATE(TRangeColl, itR, Mark)  { // for each Range in Mark                        TSeqPos From = pAlnDS->                            GetAlnPosFromSeqPos(Row, itR->GetFrom(),                                                IAlnMultiDataSource::                                                TSearchDirection::eRight);                        TSeqPos To = pAlnDS->                            GetAlnPosFromSeqPos(Row, itR->GetTo(),                                                IAlnMultiDataSource::                                                TSearchDirection::eLeft);                        TSeqRange R(From ,To);                        glColorC(m_FillColor);                        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);                        glRectd(R.GetFrom() - offset_x, bottom_y - offset_y,                                 R.GetToOpen() - offset_x, top_y - offset_y);                                                if(bSelected)   {                                                        glColorC(m_FrameColor);                            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);                            glRectd(R.GetFrom() - offset_x, bottom_y - offset_y,                                     R.GetToOpen() - offset_x, top_y - offset_y);                        }                    }                    // draw Delta - range being edited                    TRowToDeltaMap::const_iterator itD = m_mpRowToDelta.find(Row);                    if(itD != m_mpRowToDelta.end())  {                        const SMarkDelta& Delta = itD->second;                        const TSeqRange& delta_R = Delta.m_Range;                        TSeqPos From = pAlnDS->                            GetAlnPosFromSeqPos(Row, delta_R.GetFrom(),                                                IAlnMultiDataSource::                                                TSearchDirection::eRight);                        TSeqPos To = pAlnDS->                            GetAlnPosFromSeqPos(Row, delta_R.GetTo(),                                                IAlnMultiDataSource::                                                TSearchDirection::eLeft);                        TSeqRange R(From ,To);                        glColor4d(0.25, 0.25, 1.0, 1.0);                        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);                        glRectd(R.GetFrom() - offset_x, bottom_y - offset_y,                                 R.GetToOpen() - offset_x, top_y - offset_y);                    }                }            }        }        pane.Close();    }}END_NCBI_SCOPE/* * =========================================================================== * $Log: align_mark_handler.cpp,v $ * Revision 1000.3  2004/06/01 21:06:57  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17 * * Revision 1.17  2004/05/21 22:27:52  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.16  2004/04/02 17:09:40  yazhuk * Updated function calls to renamed function * * Revision 1.15  2004/03/11 17:50:41  dicuccio * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange * instead of TRange * * Revision 1.14  2003/12/18 21:13:08  yazhuk * Updated code to supported template ISelListModel * * Revision 1.13  2003/12/10 17:11:38  yazhuk * Clean-up. * * Revision 1.12  2003/12/08 15:15:55  yazhuk * Implemented workaround for OpenGL precision problems. * * Revision 1.11  2003/12/05 17:51:57  yazhuk * Disabled traces * * Revision 1.10  2003/12/01 16:43:18  yazhuk * Refactored event handling - introduced CGUIEvent * * Revision 1.9  2003/11/26 16:52:00  johnson * switch IAlnMultiDataSource to use CAlnMap::ESearchDirection instead of it's * own ESearchDirection * * Revision 1.8  2003/10/29 23:23:25  yazhuk * Replaced CAlnMultiDataSource with IAlignMultiDataSource * * Revision 1.7  2003/10/20 15:47:31  yazhuk * Changed keyboard events handling policy. Clean-up. * * Revision 1.6  2003/10/15 21:27:19  yazhuk * Migrated from using CAlnVec to accessing data via "generic" interface in CAlignDataSource. * * Revision 1.5  2003/10/12 16:28:40  ucko * Properly capitalize (and <delimit>, while I'm at it) FLTK headers * * Revision 1.4  2003/09/29 13:45:49  yazhuk * Added GetMarks() * * Revision 1.3  2003/09/25 20:47:10  yazhuk * Fixed problem with displaying marks over inserts * * Revision 1.2  2003/09/24 02:52:54  ucko * Add missing include of <math.h> * * Revision 1.1  2003/09/23 21:18:25  yazhuk * Initial revision * * =========================================================================== */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?