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