NCBI C++ ToolKit
text_sel_handler.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

00001 /*  $Id: text_sel_handler.cpp 30100 2014-04-08 10:56:52Z bollin $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Authors:  Colleen Bollin (adapted from a file by Andrey Yazhuk)
00027  *
00028  * File Description:
00029  *
00030  */
00031 
00032 #include <ncbi_pch.hpp>
00033 #include <corelib/ncbistd.hpp>
00034 
00035 #include <gui/widgets/seq_text/text_sel_handler.hpp>
00036 #include <gui/opengl/glhelpers.hpp>
00037 #include <gui/opengl/glresmgr.hpp>
00038 #include <gui/opengl/glrender.hpp>
00039 
00040 #include <objmgr/seq_loc_mapper.hpp>
00041 
00042 #include <math.h>
00043 
00044 
00045 BEGIN_NCBI_SCOPE
00046 USING_SCOPE(objects);
00047 
00048 
00049 static int kDragThreshold = 4; // make this configurable
00050 BEGIN_EVENT_TABLE(CTextSelHandler, wxEvtHandler)
00051     EVT_LEFT_DOWN(CTextSelHandler::OnMousePush)
00052     EVT_MOTION(CTextSelHandler::OnMouseDrag)
00053     EVT_LEFT_UP(CTextSelHandler::OnMouseRelease)
00054 #if 0
00055 //    EVT_LEFT_DOWN(CHitMatrixGraph::OnLeftDown)
00056 //    EVT_LEFT_UP(CHitMatrixGraph::OnLeftUp)
00057 //    EVT_MOTION(CHitMatrixGraph::OnMotion)
00058 //    case FL_PUSH: res =  x_OnMousePush(event, pane); break;
00059 //    case FL_DRAG: res =  x_OnMouseDrag(event, pane); break;
00060 //    case FL_RELEASE: res = x_OnMouseRelease(event, pane); break;
00061 //    case FL_MOVE: res = x_OnMouseMove(event, pane); break;
00062 
00063     EVT_KEY_DOWN(CTextSelHandler::OnKeyDown)
00064     EVT_KEY_UP(CTextSelHandler::OnKeyUp)
00065 #endif
00066 END_EVENT_TABLE()
00067 
00068 ////////////////////////////////////////////////////////////////////////////////
00069 /// class CTextSelHandler
00070 
00071 CTextSelHandler::CTextSelHandler()
00072 :   m_ExtState(eNoExt),
00073     m_OpType(eNoOp),
00074     m_bResizeCursor(false),
00075     m_pGeometry(NULL),
00076     m_SelColor(0.5f, 0.5f, 0.5f, 0.25f),
00077     m_BorderColor(0.25f, 0.25f, 0.25f, 0.5f),
00078     m_PassiveSelColor(0.6f, 0.6f, 0.6f, 0.25f),
00079     m_SymbolColor(0.0f, 0.0f, 1.0f, 1.0f),
00080     m_Font(CGlBitmapFont::eHelvetica24),
00081     m_HoverPos (kInvalidSeqPos)
00082 {
00083     m_Selection.clear();
00084 }
00085 
00086 
00087 CTextSelHandler::~CTextSelHandler()
00088 {
00089 }
00090 
00091 
00092 void CTextSelHandler::SetHost(ISeqTextGeometry* pGeometry)
00093 {
00094     m_pGeometry = pGeometry;
00095 }
00096 
00097 
00098 TSeqRange  CTextSelHandler::GetSelectionLimits()    const
00099 {
00100     return m_Selection.GetLimits();
00101 }
00102 
00103 
00104 const   CTextSelHandler::TRangeColl&   CTextSelHandler::GetSelection() const
00105 {
00106     return m_Selection;
00107 }
00108 
00109 
00110 void    CTextSelHandler::SetRangeSelection(const TRangeColl& C, bool b_redraw)
00111 {
00112     m_Selection = C;
00113     if(b_redraw)    {
00114         m_pGeometry->STG_OnChanged();
00115     }
00116 }
00117 
00118 
00119 void CTextSelHandler::ResetObjectSelection(bool b_redraw)
00120 {
00121     CScope& scope = m_pGeometry->STG_GetScope();
00122     m_SelectedObjects.Clear(&scope);
00123 
00124     if (b_redraw) {
00125         m_pGeometry->STG_OnChanged();
00126     }
00127 }
00128 
00129 
00130 void CTextSelHandler::DeSelectObject(const CObject* obj, bool b_redraw)
00131 {
00132     if(obj) {
00133         m_SelectedObjects.Remove(*obj);
00134         if (b_redraw) {
00135             m_pGeometry->STG_OnChanged();
00136         }
00137     }
00138 }
00139 
00140 
00141 void CTextSelHandler::SelectObject(const CObject* obj, bool b_redraw)
00142 {
00143     m_SelectedObjects.Add(NULL, *const_cast<CObject*>(obj));
00144     if (b_redraw) {
00145         m_pGeometry->STG_OnChanged();
00146     }
00147 }
00148 
00149 
00150 void    CTextSelHandler::ResetRangeSelection(bool b_redraw)
00151 {
00152     m_Selection.clear();
00153     if(b_redraw) {
00154         m_pGeometry->STG_OnChanged();
00155     }
00156 }
00157 
00158 void    CTextSelHandler::ResetSelection(bool b_redraw)
00159 {
00160     ResetRangeSelection(b_redraw);
00161     ResetObjectSelection(b_redraw);
00162 }
00163 
00164 void    CTextSelHandler::SetColor(EColorType type, const CRgbaColor& color)
00165 {
00166     switch(type)    {
00167     case eSelection: m_SelColor = color; break;
00168     case ePasssiveSelection: m_PassiveSelColor = color; break;
00169     case eSymbol: m_SymbolColor = color; break;
00170     default: _ASSERT(false);
00171     }
00172 }
00173 
00174 
00175 ////////////////////////////////////////////////////////////////////////////////
00176 // event handlers
00177 
00178 void CTextSelHandler::OnMousePush(wxMouseEvent &event)
00179 {
00180     if (event.ButtonDClick(1)) {
00181         x_OnResetAll();
00182     } else {
00183         x_OnStartSel(event);
00184         x_OnSelectCursor(event);
00185     }
00186 }
00187 
00188 
00189 void CTextSelHandler::OnMouseDrag(wxMouseEvent &event)
00190 {
00191     if (event.Dragging()) {
00192         if (m_OpType != eNoOp) {
00193             x_OnChangeSelRange(event);
00194         }
00195     } else {
00196         TSeqPos pos = x_MouseToSeqPos(event);
00197         x_SetHoverPos (pos);
00198         x_OnSelectCursor(event);
00199     }
00200 }
00201 
00202 
00203 void CTextSelHandler::OnMouseRelease(wxMouseEvent &event)
00204 {
00205     m_OpType = x_GetOpTypeByEvent(event);
00206     x_OnChangeSelRange(event);
00207     x_OnEndSelRange();
00208     x_OnSelectCursor(event);
00209 }
00210 
00211 
00212 void CTextSelHandler::x_SetHoverPos(TSeqPos pos)
00213 {
00214     if (m_pGeometry != NULL) {
00215         m_pGeometry->STG_ReportMouseOverPos(pos);
00216         if (m_HoverPos != pos) {
00217             m_HoverPos = pos;
00218             m_pGeometry->STG_Redraw();
00219         }
00220     }
00221 }
00222 
00223 
00224 #if 0
00225 int CTextSelHandler::x_OnMouseMove(CGUIEvent& event, CGlPane& pane)
00226 {
00227     CGUIEvent::EGUIState state = event.GetGUIState();
00228     x_OnSelectCursor();
00229 
00230     TSeqPos pos = x_MouseToSeqPos();
00231     x_SetHoverPos (pos);
00232 
00233     if(state == CGUIEvent::eSelectState || state == CGUIEvent::eSelectAltState) {
00234            return 1;
00235     } else return 0;
00236 }
00237 
00238 
00239 void CTextSelHandler::OnKeyDown(wxKeyEvent& event)
00240 {
00241     x_OnOpChange(event);
00242     return 0;
00243 }
00244 
00245 
00246 void CTextSelHandler::OnKeyUp(wxKeyEvent& event)
00247 {
00248     x_OnOpChange(event);
00249 
00250 
00251 
00252     return 0;
00253 }
00254 #endif
00255 
00256 ////////////////////////////////////////////////////////////////////////////////
00257 /// Signal handlers
00258 void    CTextSelHandler::x_OnStartSel(wxMouseEvent &event)
00259 {
00260     TSeqRange HitR;
00261     bool b_hit_start = false;
00262     x_HitTest(HitR, b_hit_start, event);
00263 
00264     if(HitR.NotEmpty()) {   // hit a border of the selected range
00265         m_OpType = eChange;
00266         m_ExtState = b_hit_start ? eExtRangeStart : eExtRangeEnd;
00267         m_CurrRange = HitR;
00268 
00269         x_RemoveFromSelection(HitR);
00270     } else {
00271         m_ExtState = eExtRangeEnd;
00272         m_OpType = x_GetOpTypeByEvent(event);
00273 
00274         TSeqPos pos = x_MouseToSeqPos(event);
00275 
00276         m_CurrRange.SetFrom(pos);
00277         m_CurrRange.SetToOpen(pos);
00278     }
00279 
00280     m_pGeometry->STG_Redraw();
00281 }
00282 
00283 
00284 void CTextSelHandler::x_OnChangeSelRange(wxMouseEvent &event)
00285 {
00286     TSeqPos pos = x_MouseToSeqPos(event);
00287     pos = x_ClipPosByRange(pos);
00288     TSeqRange old_r = m_CurrRange;
00289     bool in_right_margin = x_MouseInRightMargin(event);
00290 
00291     if (in_right_margin && m_ExtState == eExtRangeEnd) {
00292         pos++;
00293     }
00294 
00295     if(m_ExtState == eNoExt  &&  pos != m_CurrRange.GetFrom())   {
00296         if(pos > m_CurrRange.GetFrom()) {
00297             m_CurrRange.SetToOpen(pos);
00298             m_ExtState = eExtRangeEnd;
00299         } else  {
00300             m_CurrRange.SetToOpen(m_CurrRange.GetFrom());
00301             m_CurrRange.SetFrom(pos);
00302             m_ExtState = eExtRangeStart;
00303         }
00304     } else if(m_ExtState == eExtRangeEnd &&  pos != m_CurrRange.GetToOpen()) {
00305         if(pos > m_CurrRange.GetFrom())  {
00306             m_CurrRange.SetToOpen(pos);
00307         } else { //flip
00308             m_CurrRange.SetToOpen(m_CurrRange.GetFrom());
00309             m_CurrRange.SetFrom(pos);
00310             m_ExtState = eExtRangeStart;
00311         }
00312     } else if(m_ExtState == eExtRangeStart  &&  pos != m_CurrRange.GetFrom())    {
00313         if(pos <= m_CurrRange.GetToOpen())  {
00314             m_CurrRange.SetFrom(pos);
00315         } else {
00316             m_CurrRange.SetFrom(m_CurrRange.GetToOpen());
00317             m_CurrRange.SetToOpen(pos);
00318             m_ExtState = eExtRangeEnd;
00319         }
00320     };
00321 
00322     //Report end of range
00323     if (pos == m_CurrRange.GetToOpen() && pos > 0) {
00324         x_SetHoverPos (pos - 1);
00325     } else {
00326         x_SetHoverPos (pos);
00327     }
00328 
00329     if(m_CurrRange != old_r) {
00330         m_pGeometry->STG_Redraw();
00331     }
00332 }
00333 
00334 
00335 void    CTextSelHandler::x_OnEndSelRange()
00336 {
00337     if(! m_CurrRange.Empty())   {
00338         switch(m_OpType)   {
00339         case eAdd:
00340         case eChange:   x_AddToSelection(m_CurrRange); break;
00341         case eRemove:   x_RemoveFromSelection(m_CurrRange); break;
00342         case eNoOp: break;
00343         }
00344     }
00345     m_CurrRange.SetLength(0);
00346 
00347     m_ExtState = eNoExt;
00348     m_OpType = eNoOp;
00349 
00350     m_pGeometry->STG_OnChanged();
00351 }
00352 
00353 void    CTextSelHandler::x_OnResetAll()
00354 {
00355     bool b_update = ! m_Selection.empty();
00356     m_Selection.clear();
00357 
00358     m_ExtState = eNoExt;
00359     m_OpType = eNoOp;
00360 
00361     if(b_update) {
00362         m_pGeometry->STG_OnChanged();
00363     }
00364 }
00365 
00366 
00367 void    CTextSelHandler::x_OnOpChange(wxMouseEvent &event)
00368 {
00369    if(m_ExtState != eNoExt)   {
00370         EOpType NewType = x_GetOpTypeByEvent(event);
00371 
00372         if(NewType != m_OpType) {
00373             m_OpType = NewType;
00374             x_OnSelectCursor(event);
00375 
00376             m_pGeometry->STG_Redraw();
00377         }
00378     }
00379 }
00380 
00381 
00382 void    CTextSelHandler::x_OnSelectCursor(wxMouseEvent &event)
00383 {
00384     switch(m_OpType)    {
00385     case eNoOp:   {
00386         TSeqRange HitR;
00387         bool b_hit_start = false;
00388         x_HitTest(HitR, b_hit_start, event);
00389 
00390         m_bResizeCursor = HitR.NotEmpty();
00391     }; break;
00392     case eAdd:
00393     case eRemove:
00394     case eChange:   m_bResizeCursor = true; break;
00395     }
00396     x_SetCursor();
00397 }
00398 
00399 
00400 void    CTextSelHandler::x_SetCursor()
00401 {
00402     if (m_pGeometry) {
00403         if (m_bResizeCursor) {
00404             m_pGeometry->STG_SetResizeCursor();
00405         } else {
00406             m_pGeometry->STG_SetDefaultCursor();
00407         }
00408     }
00409 }
00410 
00411 ////////////////////////////////////////////////////////////////////////////////
00412 /// helper functions
00413 
00414 // translate modificators to operation type
00415 CTextSelHandler::EOpType CTextSelHandler::x_GetOpTypeByEvent(wxKeyEvent& event)    const
00416 {
00417 //    switch(event.GetGUIState())    {
00418 //    case CGUIEvent::eSelectState: return eAdd;
00419 //    case CGUIEvent::eSelectAltState:    return eRemove;
00420 //    default:    return eNoOp;
00421 //    }
00422     return eNoOp;
00423 }
00424 
00425 
00426 CTextSelHandler::EOpType CTextSelHandler::x_GetOpTypeByEvent(wxMouseEvent& event)    const
00427 {
00428 //    switch(event.GetGUIState())    {
00429 //    case CGUIEvent::eSelectState: return eAdd;
00430 //    case CGUIEvent::eSelectAltState:    return eRemove;
00431 //    default:    return eNoOp;
00432 //    }
00433     if (event.AltDown()) {
00434         return eRemove;
00435     } else {
00436         return eAdd;
00437     }
00438 }
00439 
00440 
00441 TSeqPos CTextSelHandler::x_MouseToSeqPos(wxMouseEvent& event)
00442 {
00443     _ASSERT(m_pPane);
00444     wxPoint pt = event.GetPosition();
00445     return m_pGeometry->STG_GetSequenceByWindow(pt.x, pt.y);
00446 }
00447 
00448 
00449 bool CTextSelHandler::x_MouseInRightMargin(wxMouseEvent& event)
00450 {
00451     _ASSERT(m_pPane);
00452     wxPoint pt = event.GetPosition();
00453     return m_pGeometry->STG_IsPointInRightMargin (pt.x, pt.y);
00454 }
00455 
00456 
00457 void    CTextSelHandler::x_HitTest(TSeqRange& range, bool& b_hit_start, wxMouseEvent &event)
00458 {
00459     _ASSERT(m_pPane);
00460     wxPoint pt = event.GetPosition();
00461 
00462     TSeqPos z = m_pGeometry->STG_GetSequenceByWindow(pt.x, pt.y);
00463 
00464     int min_D = -1;
00465     bool b_min_start = false;
00466     const TSeqRange* p_min_range = 0;
00467 
00468     const TRangeColl& C = m_Selection;
00469     ITERATE(TRangeColl, it, C)  {
00470         const TSeqRange& R = *it;
00471 
00472         int D = (int)abs((int)(z - R.GetFrom()));
00473 
00474         if(min_D < 0 || min_D > D)    {
00475             min_D = D;
00476             b_min_start = true;
00477             p_min_range = &R;
00478         }
00479         D = (int)abs((int)(z - R.GetToOpen()));
00480         if(min_D > D)    {
00481             min_D = D;
00482             b_min_start = false;
00483             p_min_range = &R;
00484         }
00485     }
00486 
00487     if(min_D > -1  && min_D <= kDragThreshold) {
00488         b_hit_start = b_min_start;
00489         _ASSERT(p_min_range);
00490         range  = *p_min_range;
00491     } else range.SetLength(0);
00492 }
00493 
00494 
00495 TSeqPos CTextSelHandler::x_ClipPosByRange(TSeqPos pos)
00496 {
00497     _ASSERT (m_pGeometry);
00498 
00499     TSeqPos chars_in_line, lines_in_seq;
00500     m_pGeometry->STG_GetLineInfo(chars_in_line, lines_in_seq);
00501 
00502     pos = max (pos, (TSeqPos) 0);
00503     pos = min (pos, (TSeqPos) (chars_in_line * lines_in_seq));
00504     return pos;
00505 }
00506 
00507 
00508 void    CTextSelHandler::x_AddToSelection(const TSeqRange& range)
00509 {
00510     m_Selection.CombineWith(range);
00511 }
00512 
00513 
00514 void    CTextSelHandler::x_RemoveFromSelection(const TSeqRange& range)
00515 {
00516     m_Selection.Subtract(range);
00517 }
00518 
00519 inline void RenderRect(const TModelRect& rc, TModelUnit offset_x, TModelUnit offset_y,
00520                        CRgbaColor& color, GLenum type)
00521 {
00522     CGlRender& gl = GetGl();
00523 
00524     gl.ColorC(color);
00525     gl.PolygonMode(GL_FRONT_AND_BACK, type);
00526     gl.Rectd(rc.Left() - offset_x, rc.Top() - offset_y,
00527              rc.Right() - offset_x, rc.Bottom() - offset_y);
00528 }
00529 
00530 
00531 void    CTextSelHandler::x_RenderRange (TSeqRange r,
00532                                         CRgbaColor& border_color)
00533 {
00534     CGlRender& gl = GetGl();
00535 
00536     TSeqPos seq_start = min (r.GetFrom(), r.GetTo());
00537     TSeqPos seq_end = max (r.GetFrom(), r.GetTo());
00538 
00539     _ASSERT (m_pGeometry);
00540     TSeqPos vis_start, vis_stop;
00541     m_pGeometry->STG_GetVisibleRange (vis_start, vis_stop);
00542 
00543     if (seq_start > vis_stop || seq_end < vis_start) {
00544         // range is completely offscreen, no need to draw
00545         return;
00546     }
00547 
00548     TSeqPos  chars_in_line, lines_in_seq;
00549     m_pGeometry->STG_GetLineInfo(chars_in_line, lines_in_seq);
00550     seq_start = max ((TSeqPos) 0, seq_start);
00551     seq_end = min (seq_end, lines_in_seq * chars_in_line);
00552 
00553     TModelPoint start_point = m_pGeometry->STG_GetModelPointBySourcePos(seq_start);
00554     TModelPoint end_point = m_pGeometry->STG_GetModelPointBySourcePos(seq_end);
00555     TSeqPos     row_end = ((seq_start / chars_in_line) * chars_in_line) + chars_in_line - 1;
00556     while (row_end < vis_start) {
00557         TSeqPos next_row_start = row_end + 1;
00558         row_end = min (next_row_start + chars_in_line - 1, seq_end);
00559     }
00560     TModelPoint interim_point = m_pGeometry->STG_GetModelPointBySourcePos (row_end);
00561 
00562     if (start_point.m_Y == end_point.m_Y) {
00563         interim_point.m_X = end_point.m_X;
00564     }
00565 
00566     TModelRect rc (start_point.m_X, start_point.m_Y - 0.2,
00567                    interim_point.m_X + 1.0,
00568                    interim_point.m_Y + 0.8);
00569 
00570     gl.LineWidth (0.5);
00571 
00572     RenderRect(rc, .1, 0, m_PassiveSelColor, GL_FILL);
00573     RenderRect(rc, 0, 0, border_color, GL_LINE);
00574 
00575     while (row_end < vis_stop && row_end < seq_end)
00576     {
00577         TSeqPos next_row_start = row_end + 1;
00578         start_point = m_pGeometry->STG_GetModelPointBySourcePos(next_row_start);
00579         row_end = min (next_row_start + chars_in_line - 1, seq_end);
00580         interim_point = m_pGeometry->STG_GetModelPointBySourcePos(row_end);
00581         rc.Init (start_point.m_X, start_point.m_Y - 0.2, interim_point.m_X + 1.0, interim_point.m_Y + 0.8);
00582 
00583         RenderRect(rc, 0, 0, m_PassiveSelColor, GL_FILL);
00584         RenderRect(rc, 0, 0, border_color, GL_LINE);
00585     }
00586 }
00587 
00588 
00589 void    CTextSelHandler::x_RenderOpSymbol (TSeqRange r)
00590 {
00591     TSeqPos seq_start = min (r.GetFrom(), r.GetTo());
00592     TSeqPos seq_end = max (r.GetFrom(), r.GetTo());
00593     int     sym_len = 0;
00594 
00595     // draw Operation symbol in center of range
00596     const char* s = 0;
00597     switch(m_OpType)    {
00598         case eAdd:
00599             s = "+";
00600             sym_len = 1;
00601             break;
00602         case eRemove:
00603             s = "-";
00604             sym_len = 1;
00605             break;
00606         case eChange:
00607             s = "<->";
00608             sym_len = 3;
00609             break;
00610         case eNoOp:
00611             break;
00612     }
00613     if (sym_len < 1) {
00614         return;
00615     }
00616 
00617     _ASSERT (m_pGeometry);
00618     TSeqPos vis_start, vis_stop;
00619     m_pGeometry->STG_GetVisibleRange (vis_start, vis_stop);
00620 
00621     if (seq_start > vis_stop || seq_end < vis_start) {
00622         // range is completely offscreen, no need to draw
00623         return;
00624     }
00625 
00626     seq_start = max (seq_start, vis_start);
00627     seq_end = min (seq_end, vis_stop);
00628 
00629     TModelPoint start_point = m_pGeometry->STG_GetModelPointBySourcePos(seq_start);
00630     TModelPoint end_point = m_pGeometry->STG_GetModelPointBySourcePos(seq_end);
00631     TModelRect  range_rect(min (start_point.m_X, end_point.m_X), min (start_point.m_Y, end_point.m_Y),
00632                            max (start_point.m_X, end_point.m_X), max (start_point.m_Y, end_point.m_Y));
00633 
00634     // if there is enougth space - draw operation symbol
00635     TModelUnit x = range_rect.Left() + range_rect.Width() / 2 - sym_len / 2;
00636     TModelUnit y = range_rect.Bottom() + range_rect.Height() / 2 + .5;
00637     m_Font.TextOut(x, y, s);
00638 }
00639 
00640 
00641 void    CTextSelHandler::x_RenderSelectedFeatures ()
00642 {
00643     TConstObjects objs;
00644     m_SelectedObjects.GetObjects(objs);
00645 
00646     if (objs.size() == 0) {
00647         return;
00648     }
00649 
00650     // need to map locations
00651     CBioseq_Handle top_handle = m_pGeometry->STG_GetScope().GetBioseqHandle(*(m_pGeometry->STG_GetDataSourceLoc()->GetId()));
00652 
00653     CSeq_loc_Mapper mapper(0,
00654                            top_handle,
00655                            CSeq_loc_Mapper::eSeqMap_Up);
00656 
00657     set <CSerialObject*> objsToDraw;
00658     ITERATE(TConstObjects, obj, objs) {
00659         const CSerialObject* cso =
00660             dynamic_cast<const CSerialObject*>(obj->GetPointer());
00661 
00662         if (cso) {
00663             //const CTypeInfo* this_info = cso->GetThisTypeInfo();
00664             if (cso->GetThisTypeInfo() == CSeq_feat::GetTypeInfo()) {
00665                 const CSeq_feat& feat = dynamic_cast<const CSeq_feat&>(*cso);
00666                 CRef<CSeq_loc> feat_loc = mapper.Map(feat.GetLocation());
00667 
00668                 if (m_pGeometry != NULL) {
00669                     m_pGeometry->STG_RenderSelectedFeature(feat, *feat_loc);
00670                 }
00671             }
00672         }
00673     }
00674 }
00675 
00676 
00677 void    CTextSelHandler::Render(CGlPane& pane, ERenderingOption option)
00678 {
00679     CGlAttrGuard AttrGuard(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_HINT_BIT);
00680 
00681     TModelRect rc_vis = pane.GetVisibleRect();
00682 
00683     if(! rc_vis.IsEmpty()) {
00684         pane.OpenOrtho();
00685 
00686         // draw exisiting selection
00687 
00688         const TRangeColl& C = m_Selection;
00689         ITERATE(TRangeColl, it, C)  { // for every segment
00690             const TSeqRange& r = *it;
00691 
00692             x_RenderRange (r, m_BorderColor);
00693         }
00694 
00695         if(m_OpType != eNoOp)   { // draw current range
00696 
00697             x_RenderRange (m_CurrRange, m_SymbolColor);
00698 
00699             if(option == eActiveState)  {
00700                 x_RenderOpSymbol (m_CurrRange);
00701             }
00702         }
00703 
00704         x_RenderSelectedFeatures();
00705 
00706         if (m_pGeometry != NULL) {
00707             vector<CConstRef<CSeq_feat> > feat_list = m_pGeometry->STG_GetFeaturesAtPosition(m_HoverPos);
00708             ITERATE(vector<CConstRef<CSeq_feat> >, feat, feat_list) {
00709                 m_pGeometry->STG_RenderMouseOverFeature(**feat);
00710             }
00711         }
00712         pane.Close();
00713     }
00714 }
00715 
00716 
00717 void CTextSelHandler::STGH_GetSelectedFeatureSubtypes(CSeqTextDefs::TSubtypeVector &subtypes)
00718 {
00719     unsigned int i;
00720     TConstObjects objs;
00721     TSeqPos start_offset, stop_offset;
00722 
00723     subtypes.clear();
00724 
00725     // no point in trying to return feature subtypes without a host
00726     if (m_pGeometry == NULL) {
00727         return;
00728     }
00729 
00730     m_pGeometry->STG_GetVisibleRange(start_offset, stop_offset);
00731 
00732     for (i = 0; i < stop_offset - start_offset + 2; i++) {
00733         subtypes.push_back (CSeqFeatData::eSubtype_bad);
00734     }
00735 
00736     m_SelectedObjects.GetObjects(objs);
00737 
00738     // no selected features, no selected feature subtypes
00739     if (objs.size() == 0) {
00740         return;
00741     }
00742 
00743     // need to map locations
00744     CBioseq_Handle top_handle = m_pGeometry->STG_GetScope().GetBioseqHandle(*(m_pGeometry->STG_GetDataSourceLoc()->GetId()));
00745 
00746     CSeq_loc_Mapper mapper(0,
00747                            top_handle,
00748                            CSeq_loc_Mapper::eSeqMap_Up);
00749 
00750 
00751     set <CSerialObject*> objsToDraw;
00752     ITERATE(TConstObjects, obj, objs) {
00753         const CSerialObject* cso =
00754             dynamic_cast<const CSerialObject*>(obj->GetPointer());
00755 
00756         if (cso) {
00757             //const CTypeInfo* this_info = cso->GetThisTypeInfo();
00758             if (cso->GetThisTypeInfo() == CSeq_feat::GetTypeInfo()) {
00759                 const CSeq_feat& feat = dynamic_cast<const CSeq_feat&>(*cso);
00760                 CRef<CSeq_loc> feat_loc = mapper.Map(feat.GetLocation());
00761 
00762                 m_pGeometry->STG_SetSubtypesForFeature (subtypes, *feat_loc, feat.GetData().GetSubtype(), start_offset, stop_offset);
00763             }
00764         }
00765     }
00766 }
00767 
00768 
00769 void CTextSelHandler::STGH_GetMouseOverFeatureSubtypes(CSeqTextDefs::TSubtypeVector &subtypes)
00770 {
00771     unsigned int i;
00772     TConstObjects objs;
00773     TSeqPos start_offset, stop_offset;
00774 
00775     subtypes.clear();
00776 
00777     // no point in trying to return feature subtypes without a host
00778     if (m_pGeometry == NULL) {
00779         return;
00780     }
00781 
00782     m_pGeometry->STG_GetVisibleRange(start_offset, stop_offset);
00783 
00784     for (i = 0; i < stop_offset - start_offset + 2; i++) {
00785         subtypes.push_back (CSeqFeatData::eSubtype_bad);
00786     }
00787 
00788     vector<CConstRef<CSeq_feat> > feat_list = m_pGeometry->STG_GetFeaturesAtPosition(m_HoverPos);
00789     ITERATE(vector<CConstRef<CSeq_feat> >, feat, feat_list) {
00790         m_pGeometry->STG_SetSubtypesForFeature (subtypes, (*feat)->GetLocation(), (*feat)->GetData().GetSubtype(), start_offset, stop_offset);
00791     }
00792 
00793 }
00794 
00795 
00796 END_NCBI_SCOPE
Modified on Fri Dec 19 11:45:00 2014 by modify_doxy.py rev. 426318