align_mark_handler.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:24k
- /*
- * ===========================================================================
- * 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_SCOPE
- USING_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 handler
- int 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 Mark
- void 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 handlers
- int 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 handlers
- void 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 position
- void 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 pressed
- bool 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 pressed
- bool CAlignMarkHandler::x_ModifiersOk() const
- {
- int State = Fl::event_state() & (FL_SHIFT | FL_ALT);
- return State == 0;
- }
- // converts mouse X position to the position in Alignment
- TModelUnit 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 resized
- void 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)
- 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 line
- bool 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 segments
- bool 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 position
- void 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
- *
- * ===========================================================================
- */