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

Go to the SVN repository for this file.

1 /* $Id: seqgraphic_pane.cpp 47479 2023-05-02 13:24:02Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Vlad Lebedev, Liangshou Wu
27  *
28  */
29 
30 
31 #include <ncbi_pch.hpp>
32 
33 #include "seqgraphic_pane.hpp"
34 
35 #include <wx/msgdlg.h>
36 #include <util/xregexp/regexp.hpp>
37 #include <objmgr/util/feature.hpp>
38 #include <objmgr/util/sequence.hpp>
41 #include <corelib/ncbitime.hpp>
42 
43 #include <gui/opengl/glhelpers.hpp>
44 #include <gui/opengl/glresmgr.hpp>
45 #include <gui/objutils/tooltip.hpp>
48 #include <gui/utils/clipboard.hpp>
49 #include <gui/utils/view_event.hpp>
60 #include <gui/utils/track_info.hpp>
61 
62 #include <algorithm>
63 #include <math.h>
64 
66 
67 #include "unaligned_region_dlg.hpp"
68 
71 
72 const static string kCommonTipId = "----";
73 const static string kDefaultMarker = "Default";
74 const static string kDefaultMarkerLabel = "M0";
75 const static string kNamedMarker = "M";
76 
77 BEGIN_EVENT_TABLE(CSeqGraphicPane, CGlWidgetPane)
78  //EVT_SIZE(CSeqGraphicPane::OnSize)
79  EVT_CONTEXT_MENU(CSeqGraphicPane::OnContextMenu)
80  EVT_KEY_UP(CSeqGraphicPane::OnKeyUp)
81  EVT_KEY_DOWN(CSeqGraphicPane::OnKeyDown)
82  EVT_LEFT_DOWN(CSeqGraphicPane::OnLeftDown)
83  EVT_MIDDLE_DOWN(CSeqGraphicPane::OnMiddleDown)
84  EVT_LEFT_UP(CSeqGraphicPane::OnLeftUp)
85  EVT_LEFT_DCLICK(CSeqGraphicPane::OnLeftDblClick)
86  EVT_MOTION(CSeqGraphicPane::OnMotion)
87  EVT_MOUSEWHEEL(CSeqGraphicPane::OnMouseWheel)
88  EVT_MOUSE_CAPTURE_LOST(CSeqGraphicPane::OnMouseCaptureLost)
89 
90  EVT_KILL_FOCUS(CSeqGraphicPane::OnKillFocus)
92 
94 {
95 public:
96  enum EEventType {
97  ePurgeEvent
98  };
99 
100  CSeqGraphicPaneEvent() : CEvent(ePurgeEvent) {}
101 };
102 
106 
107 template <class T>
109 {
110 public:
112  bool operator()(const CObject* arg) const
113  {
114  return (dynamic_cast<const T*>(arg)) != NULL;
115  }
116 };
117 
118 
119 static string s_GetTrackName(const string& tip_id)
120 {
122  if (pos != string::npos) {
123  return tip_id.substr(pos + kCommonTipId.length());
124  }
125 
126  return "";
127 }
128 
129 
131  : CGlWidgetPane(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS)
132  , m_Renderer(new CSeqGraphicRenderer(false))
133  , m_DSContext(new CSGDataSourceContext)
134  , m_BackForwardPos(0)
135  , m_StartPoint(0, 0)
136  , m_DragPoint(0, 0)
137  , m_CurrMouse(0, 0)
138  , m_MouseMode(eMouse_Idle)
139  , m_Flipped(false)
140  , m_Horz(true)
141  , m_MarkerHandlerIndex(0)
142  , m_MarkerId(1)
143  , m_SeqStart(0)
144  , m_Title(false)
145  , m_VectorPane(false)
146 #ifdef ATTRIB_MENU_SUPPORT
147  , m_RenderMs(0.0f)
148 #endif
149 {
150  if (x_GetParent()) {
151  CSeqGraphicWidget* parent_widget = x_GetParent();
152  AddListener(parent_widget, ePool_Parent);
153  //m_MatrixPane = parent->GetPort();
154  }
155 
157  m_Renderer->SetHost(this);
158 
159  // setup Event Handlers
160  m_TrackHandler.SetHost(this);
164 
168 
169  // NOTE: we want to put all sequence markers after tooltip handler and before
170  // selection handler. If there is any other handler needs to be registered
171  // before sequence marker, please increase m_MarkerHandlerIndex to make sure
172  // sequence markers added during run-time will be registered to the right
173  // order.
174  //m_SeqMarkHandler.SetHost(this);
175  //x_RegisterHandler(&m_SeqMarkHandler, fArea_Ruler,
176  // &m_Renderer->GetRulerGlPane(), m_MarkerHandlerIndex);
177 
179  m_SelHandler.SetHost(this);
181 
185 
186 #ifdef ATTRIB_MENU_SUPPORT
187  //CAttribMenu& m = CAttribMenuInstance::GetInstance();
188  //CAttribMenu* m1 = m.AddSubMenuUnique("SeqSubmenu", this);
189  //m1->AddFloat("Pre-popup Move Max", & (m_TooltipManager.GetMoveThreshold()), 6.0f, 0.0f, 20.0f, 0.1f);
190  //m1->AddInt("Post-popup Clear Delay", & (m_TooltipManager.GetClearUnpinnedDelay()), 200, 10, 1000, 10);
191  //m1->AddFloat("Tip Dist", &(m_TooltipManager.GetPopupDistance()), 0.333f, 0.0f, 2.0f, 0.01f);
192  //m1->AddInt("Tip Popup Delay", &(m_TooltipManager.GetTipPopupDelay()), 200, 10, 1000, 10);
193 
195  CAttribMenu* sub_menu = m.AddSubMenuUnique("Seq Render", this);
196  sub_menu->AddFloatReadOnly("Render MS: ", &m_RenderMs);
197  CAttribStringsMenuItem* strings = sub_menu->AddStrings("Renderer", &m_GlRenderer);
198  strings->AddString("GL Default");
199  strings->AddString("Debug");
200  strings->SetValue(0);
201  m_GlRenderer = "GL Default";
202  // support <, > for closing and opening menus
203  m.SetOpenCloseKeys(int('.'), int(','));
204 #endif
205 }
206 
207 
209 {
210  if (m_ConfigSettings) {
212  }
213 
214  //CAttribMenu& m = CAttribMenuInstance::GetInstance();
215  //m.RemoveMenuR("SeqSubmenu", this);
216 
217 #ifdef ATTRIB_MENU_SUPPORT
218  CAttribMenuInstance::GetInstance().RemoveMenuR("Seq Render", this);
219 #endif
220 }
221 
222 
224 {
225  if ( !m_DS ) {
226  InitDataSource(obj);
227  }
228 
231 
232  int w, h;
233  GetClientSize(&w, &h);
234  TVPRect rcVP(0, 0, w, h);
235  m_Renderer->SetHorizontal(m_Horz, m_Flipped, rcVP, true);
236 
238  m_BackForwardHistory.clear();
239  m_BackForwardPos = 0;
241  x_ClearMarkers();
242  //CEvent evt(CEvent::eEvent_Message, CViewEvent::eWidgetDataChanged);
243  //Send(&evt, CEventHandler::eDispatch_Default, ePool_Parent);
244 }
245 
246 
248 {
251  if (nullptr != registry) {
252  registry->AddNonAsnData(data);
253  }
255 }
256 
257 
259 {
260  m_DSContext->ClearCache();
261 
262  CIRef<ISGDataSource> ds = m_DSContext->GetDS(typeid(CSGSequenceDSType).name(), obj);
263  m_DS.Reset(dynamic_cast<CSGSequenceDS*>(ds.GetPointer()));
264 }
265 
266 
268 {
269  return m_DS.GetPointer();
270 }
271 
272 
274 {
275  return m_Renderer->GetFeaturePanel();
276 }
277 
278 
279 void CSeqGraphicPane::OnKeyUp(wxKeyEvent& event)
280 {
281  //if (m_LenseZoom) {
282  // m_Renderer->CancelLensZoom();
283  // m_LenseZoom = false;
284  // Refresh();
285  //}
286 
287  event.Skip();
288 }
289 
290 
291 void CSeqGraphicPane::OnKeyDown(wxKeyEvent& event)
292 {
293  if (!m_DS) {
294  event.Skip();
295  return;
296  }
297 
298  //bool b_ctrl = wxGetKeyState(WXK_CONTROL);
299  bool b_shift = wxGetKeyState(WXK_SHIFT);
300 
301  switch (event.GetKeyCode()) {
302  case 'd':
303  case 'D':
304  {{
305  // Lense Zoom (D key)
306  //m_LenseZoom = true;
307  //m_Renderer->SetLensZoom(m_CurrMouse.x,
308  //MZHH_GetVPPosByY(m_CurrMouse.y));
309  //Refresh();
310  }}
311  break;
312  case 'm':
313  case 'M':
314  {{
315  // set marker
318  SetSeqMarker(TModelPoint(x, y));
319  Refresh();
320  }}
321  break;
322  case '/':
323  // wuliangs: move this to switch point track
325  Refresh();
326  break;
327  case WXK_LEFT:
329  break;
330  case WXK_RIGHT:
332  break;
333  case WXK_TAB:
334  if (b_shift) {
336  } else {
338  }
339  break;
340  case WXK_UP: // Prevent gtk navigation via arrow keys
341  case WXK_DOWN:
342  break;
343  default:
344  event.Skip();
345  break;
346  }
347 }
348 
349 
350 void CSeqGraphicPane::OnLeftUp(wxMouseEvent& event)
351 {
352  if (m_DS && m_MouseMode != eMouse_Idle) {
353  m_CurrMouse = event.GetPosition();
354  int x = m_CurrMouse.x;
355  int y = MZHH_GetVPPosByY(m_CurrMouse.y);
356  CRef<CSeqGlyph> last_hit_glyph = m_Renderer->HitTest(x, y);
357  m_LastHitGlyph.Reset(last_hit_glyph.GetPointer());
358 
362  } else if (m_MouseMode == eMouse_Pan) {
363  x_OnEndPan();
364  } else if (m_MouseMode == eMouse_IncSelect) {
365  const IObjectBasedGlyph* obj =
366  dynamic_cast<const IObjectBasedGlyph*>(last_hit_glyph.GetPointer());
367  if (obj) {
368  CConstRef<CObject> sel_obj =
369  obj->GetObject(m_Renderer->Screen2Seq(x, y));
370  if (m_Renderer->IsObjectSelected(sel_obj)) {
371  DeSelectObject(sel_obj);
372  } else {
373  SelectObject(sel_obj, true);
374  // reset Ruler to selected object
376  TSeqRange range = last_hit_glyph->GetRange();
377  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(
378  last_hit_glyph.GetPointer());
379  if (feat) {
380  bool neg_strand = (sequence::GetStrand(feat->GetLocation())
381  == eNa_strand_minus);
382  // respect strand
383  TSeqPos r_pos = neg_strand ? range.GetTo() : range.GetFrom();
384  SetSeqStart(r_pos);
385  } else {
386  SetSeqStart(range.GetFrom());
387  }
388  }
389  }
390  }
393  GHH_SetCursor(wxCursor(wxCURSOR_ARROW));
395  Refresh();
396  } else if (m_MouseMode == eMouse_Down) {
397  // Select last clicked object if it is selectable
398  SelectOnlyThisObject(last_hit_glyph.GetPointer(), x, y);
400  GHH_SetCursor(wxCursor(wxCURSOR_ARROW));
402  Refresh();
403  }
404  } else {
405  event.Skip();
406  }
407 }
408 
409 
410 void CSeqGraphicPane::OnLeftDown(wxMouseEvent& event)
411 {
413 
414  if (!m_DS) {
415  event.Skip();
416  return;
417  }
418 
420 
421  if (wxGetKeyState(wxKeyCode('Z')) ||
422  wxGetKeyState(wxKeyCode('R')) ||
423  wxGetKeyState(wxKeyCode('P')) )
424  {
425  event.Skip();
426  return;
427  }
428 
429  m_StartPoint = m_DragPoint = event.GetPosition();
430 
431  int x = m_StartPoint.x;
432  int y = MZHH_GetVPPosByY(m_StartPoint.y);
433  int area = x_GetAreaByVPPos(x, y);
434  if (area != fArea_Object) {
435  event.Skip();
436  return;
437  }
438 
439  SetFocus();
440 
441  CRef<CSeqGlyph> last_hit_glyph = m_Renderer->HitTest(x, y);
442  m_LastHitGlyph.Reset(last_hit_glyph.GetPointer());
443 
444  bool rect_select = event.ShiftDown();
445  bool inc_select = event.CmdDown();
446 
447  // do track-specific interactions if it is not extension
448  // selection (shift key down) or incremental selection (ctrl key down)
449  if (last_hit_glyph && !inc_select && !rect_select ) {
450  CLayoutTrack* track =
451  dynamic_cast<CLayoutTrack*>(last_hit_glyph.GetPointer());
452  if (track) {
453  event.Skip();
454  return;
455  }
456  }
457 
458  if (rect_select){
459  if (inc_select) {
461  } else {
463  }
464  } else if (inc_select) {
466  } else {
467  const CGlPane& pane = m_Renderer->GetFeatGlPane();
468  TModelPoint pos = pane.UnProject(x, y);
469  // call glyph-specific left down event handler
470  if (last_hit_glyph && last_hit_glyph->OnLeftDown(pos)) {
471  return;
472  }
473 
475  }
477 }
478 
479 
480 void CSeqGraphicPane::OnMiddleDown(wxMouseEvent& event)
481 {
483 
484  if ( !HasCapture() ) {
485  event.Skip();
486  }
487 }
488 
489 void CSeqGraphicPane::OnMotion(wxMouseEvent& event)
490 {
491  if (!m_DS) {
492  event.Skip();
493  return;
494  }
495 
496  if (wxGetKeyState(wxKeyCode('Z')) ||
497  wxGetKeyState(wxKeyCode('R')) ||
498  wxGetKeyState(wxKeyCode('P')) )
499  {
500  event.Skip();
501  return;
502  }
503 
504  m_CurrMouse = event.GetPosition();
505  CRef<CSeqGlyph> last_hit_glyph =
507  m_LastHitGlyph.Reset(last_hit_glyph.GetPointer());
508 
511  wxPoint pos = event.GetPosition();
512  if (pos.x != m_DragPoint.x || pos.y != m_DragPoint.y) {
513  m_DragPoint = pos;
514  GHH_SetCursor(wxCursor(wxCURSOR_CROSS));
515  Refresh();
516  }
517  } else if (m_MouseMode == eMouse_Pan ||
520  m_CurrMouse = event.GetPosition();
521  x_OnPan();
523  Refresh();
524  } else if (last_hit_glyph && last_hit_glyph->IsClickable()) {
525  GHH_SetCursor(wxCursor(wxCURSOR_HAND));
526  } else {
527  GHH_SetCursor(wxCursor(wxCURSOR_ARROW));
528  }
529 
530  if (m_MouseMode == eMouse_Idle) {
531  event.Skip();
532  }
533 }
534 
535 
536 void CSeqGraphicPane::OnMouseWheel(wxMouseEvent& event)
537 {
539  if (wxGetKeyState(wxKeyCode('Z')) ||
540  wxGetKeyState(wxKeyCode('R')) ||
541  wxGetKeyState(wxKeyCode('P')) )
542  {
543  event.Skip();
544  return;
545  }
546 
547  int shift = event.GetWheelRotation()/4;
548  if (m_Horz) {
549  MZHH_Scroll(0, -shift);
550  } else {
551  MZHH_Scroll(-shift, 0);
552  }
553 }
554 
555 
556 void CSeqGraphicPane::OnLeftDblClick(wxMouseEvent& event)
557 {
559 
560  if (!m_DS) {
561  event.Skip();
562  return;
563  }
564 
565  wxPoint pos = event.GetPosition();
566  pos.y = MZHH_GetVPPosByY(pos.y);
567 
568  int area = x_GetAreaByVPPos(pos.x, pos.y);
569  if (area != fArea_Object) {
570  event.Skip();
571  return;
572  }
573 
574  CRef<CSeqGlyph> obj = m_Renderer->HitTest(pos.x, pos.y);
575  const CGlPane& pane = m_Renderer->GetFeatGlPane();
576  TModelPoint pnt = pane.UnProject(pos.x, pos.y);
577 
578  if (obj && ! obj->OnLeftDblClick(pnt)) {
579  TSeqRange range = obj->GetRange();
580 
581  // TODO: do we need to take care of any special cases?
584  } else if ( !obj ) {
585  if ( m_Renderer->HasSelectedObjects() ) {
588  Refresh();
589  }
590  }
591 }
592 
593 
594 void CSeqGraphicPane::OnMouseCaptureLost(wxMouseCaptureLostEvent& /*event*/)
595 {
596  switch (m_MouseMode) {
597  case eMouse_RectSelect:
600  break;
601  case eMouse_Pan:
602  x_OnEndPan();
603  break;
604  default:
606  break;
607  }
608 }
609 
610 
612 {
616  }
617 
618  x_SelectByRect();
620 
622  GHH_SetCursor(wxCursor(wxCURSOR_ARROW));
624  Refresh();
625 }
626 
627 
629 {
631  x_OnPan();
632  GHH_SetCursor(wxCursor(wxCURSOR_ARROW));
634  Refresh();
636 }
637 
638 
640 {
641  const CGlPane& pane = m_Renderer->GetFeatGlPane();
642  TModelUnit m_x1 = pane.UnProjectX(m_StartPoint.x);
643  TModelUnit m_x2 = pane.UnProjectX(m_CurrMouse.x);
644 
645  int y1 = MZHH_GetVPPosByY(m_StartPoint.y);
646  int y2 = MZHH_GetVPPosByY(m_CurrMouse.y);
647  TModelUnit m_y1 = pane.UnProjectY(y1);
648  TModelUnit m_y2 = pane.UnProjectY(y2);
649 
650  MZHH_Scroll(m_x1 - m_x2, m_y1 - m_y2);
651 }
652 
653 
655 {
656  string tip_id = "";
657  const IObjectBasedGlyph* obj_glyph =
658  dynamic_cast<const IObjectBasedGlyph*>(glyph);
659  if (obj_glyph) {
660  CConstRef<CObject> obj = obj_glyph->GetObject(0);
661  string track_name = "";
662 
663  const CSeqGlyph* p = glyph->GetParent();
664  while (p) {
665  const CLayoutTrack* p_track = dynamic_cast<const CLayoutTrack*>(p);
666  if (p_track) {
667  track_name = p_track->GetFullTitle();
668  break;
669  }
670  p = p->GetParent();
671  }
672 
673  ITERATE (TPinnedTips, iter, m_PinnedTips) {
674  const CCachedTipHandle& handle = *iter->second;
675  if (handle.HasMatches(const_cast<CObject&>(*obj), m_DS->GetScope()) &&
676  handle.GetParentTrackName() == track_name) {
677  return iter->first;
678  }
679  }
680 
681  }
682  return tip_id;
683 }
684 
685 
687 {
688 public:
689  typedef list< CWeakRef<CSeqGlyph> > TSelectedGlyphs;
690 
692  CScope& scope)
693  : m_TipHandle(handle)
694  , m_Scope(&scope)
695  {}
696 
697  /// @name IGlyphVisitor interface implementation
698  /// @{
699  virtual bool Visit(CSeqGlyph* glyph);
700  /// @}
701 
703  {
704  m_Glyphs.clear();
705  glyph->Accept(this);
706  return m_Glyphs;
707  }
708 
709 private:
713 };
714 
715 
717 {
718  bool cont = true;
719  IObjectBasedGlyph* obj_glyph = dynamic_cast<IObjectBasedGlyph*>(glyph);
720  if (obj_glyph) {
721  CConstRef<CObject> glyph_o(obj_glyph->GetObject(0));
722  if (!glyph_o.Empty()) {
723  const CObject& obj = *glyph_o;
724  if (m_TipHandle.HasMatches(obj, *m_Scope)) {
725  string track_name = "";
726  const CSeqGlyph* p = glyph->GetParent();
727  while (p) {
728  const CLayoutTrack* p_track = dynamic_cast<const CLayoutTrack*>(p);
729  if (p_track) {
730  track_name = p_track->GetFullTitle();
731  break;
732  }
733  p = p->GetParent();
734  }
735  if (m_TipHandle.GetParentTrackName() == track_name) {
736  m_Glyphs.push_back(CWeakRef<CSeqGlyph>(glyph));
737  cont = false;
738  }
739  }
740  }
741  }
742  return cont;
743 }
744 
745 
747 {
748  CWeakRef<CSeqGlyph> glyph;
750  if (iter == m_PinnedTips.end()) return glyph;
751 
752  const CCachedTipHandle& handle = *iter->second;
753  CGlyphSearchVisitor glyph_searcher(handle, m_DS->GetScope());
755  glyph_searcher.Search(GetFeaturePanel());
756  if ( !glyphs.empty() ) {
757  glyph = glyphs.front();
758  }
759  return glyph;
760 }
761 
762 
764 {
766  x_GetParent()->GetPort().GetViewport());
767  Refresh();
768 }
769 
770 
771 void CSeqGraphicPane::SetHorizontal(bool b_horz, bool b_flip)
772 {
773  m_Horz = b_horz;
774  m_Flipped = b_flip;
775  m_Renderer->SetHorizontal(b_horz, b_flip,
776  x_GetParent()->GetPort().GetViewport());
777 
778  // Any range-based seqmarkers need to be flipped.
780  if (iter->second->IsRemoved()) continue;
781 
782  iter->second->SetFlipped(m_Flipped);
783  }
784 
785 }
786 
787 
789 {
790  x_GetParent()->ZoomOnRange(TSeqRange(from, to), 0);
791  m_Renderer->ZoomOnRange(TModelRange(from, to));
793 }
794 
795 
797 {
798  TVPRect& vp = x_GetParent()->GetPort().GetViewport();
799  TVPUnit img_height = (TVPUnit)GetHeight();
800  img_height = max(220, img_height);
801  vp.SetTop(img_height);
803  x_GetParent()->GetPort().GetViewport());
804 }
805 
806 
808 {
809  TVPRect& vp = x_GetParent()->GetPort().GetViewport();
811  vp.SetRight(vp_width);
812  rect.SetLeft(from);
813  rect.SetRight(to);
814 }
815 
816 
818 {
819  return m_Renderer->AllJobsFinished();
820 }
821 
823 {
824  return m_Renderer->AllTracksCreated();
825 }
826 
828 {
830 }
831 
832 
833 // Set/Clear selection
835 {
836  if (!obj) {
837  return;
838  }
839 
841  Refresh();
842 }
843 
844 
845 void CSeqGraphicPane::SelectObject(const CObject* obj, bool verified)
846 {
847  if (!obj) {
848  return;
849  }
850 
851  m_Renderer->SelectObject(obj, verified);
852  Refresh();
853 }
854 
855 
856 void CSeqGraphicPane::SelectLastHitObject(int mouse_x, int mouse_y)
857 {
859  if (last_hit_glyph && !last_hit_glyph->IsSelected()) {
860  SelectOnlyThisObject(last_hit_glyph.GetPointer(), mouse_x, mouse_y);
861  }
862 }
863 
864 
866  int mouse_x, int mouse_y)
867 {
868  const IObjectBasedGlyph* obj = dynamic_cast<const IObjectBasedGlyph*>(glyph);
869  if (obj) {
870  // deselect all of the originally selected objects
873  }
874  CConstRef<CObject> sel_obj
875  = obj->GetObject(m_Renderer->Screen2Seq(mouse_x, mouse_y));
876  SelectObject(sel_obj, true);
877 
878  // reset Ruler to selected object
880  TSeqRange range = glyph->GetRange();
881  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(glyph);
882  if (feat) {
883  bool neg_strand = (sequence::GetStrand(feat->GetLocation())
884  == eNa_strand_minus);
885  // respect strand
886  TSeqPos r_pos = neg_strand ? range.GetTo() : range.GetFrom();
887  SetSeqStart(r_pos);
888  } else {
889  SetSeqStart(range.GetFrom());
890  }
891  }
893  }
894 }
895 
896 void CSeqGraphicPane::GetCurrentObject(int mouse_x, int mouse_y, TConstObjects& objs)
897 {
898  CRef<CSeqGlyph> glyph = m_Renderer->HitTest(mouse_x, mouse_y);
899  const IObjectBasedGlyph* obj = dynamic_cast<const IObjectBasedGlyph*>(glyph.GetPointer());
900  if (obj) {
901  CConstRef<CObject> sel_obj = obj->GetObject(m_Renderer->Screen2Seq(mouse_x, mouse_y));
902  objs.push_back(sel_obj);
903  }
904 }
905 
907 {
908  try {
909  TRangeColl r = TRangeColl( loc->GetTotalRange() );
910  m_SelHandler.SetSelection(r, false);
911  Refresh();
912  } catch (CException& e) {
913  LOG_POST(Warning << "CSeqGraphicPane::SelectSeqLoc "
914  << e.GetMsg());
915  }
916 }
917 
918 
920 {
923 }
924 
925 
927 {
929  Refresh();
930 }
931 
932 
934 {
936  Refresh();
937 }
938 
939 
940 // retrieve the selections from our renderer
942 {
944 }
945 
946 
949 {
950  return m_SelHandler.GetSelection();
951 }
952 
953 
955 {
956  m_SelHandler.SetSelection(ranges, true);
957  Refresh();
958 }
959 
960 
962 {
963  // Don't do non-vector rendering from a pane that was created
964  // just to write vector graphics - It can cause problems with the primary
965  // pane user is looking at...
966  if (m_VectorPane) {
967  return;
968  }
969 
970  IRender& gl = GetGl();
971 
972  /// TODO: we clear the frame buffers twice, one here
973  /// and another one in m_Renderer. Do we need this?
974  glClearColor(1, 1, 1, 0);
975  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
976 
977  if (!x_GetParent() || !m_DS)
978  return;
979 
981  GetRenderer( CGlResMgr::Instance().GetApiLevel());
982  if (mgr.IsNull()) {
983  LOG_POST(Error << "IRender object not available.");
984  return;
985  }
986 
988 
989 #ifdef ATTRIB_MENU_SUPPORT
990  if (m_GlRenderer != "GL Default") { // "Debug"
992  CGlRenderDebug* rdebug = NULL;
993  if (mgr.IsNull()) {
994  rdebug = new CGlRenderDebug();
995  mgr.Reset(rdebug);
997  }
998  else {
999  rdebug = dynamic_cast<CGlRenderDebug*>(mgr.GetPointerOrNull());
1000  if (rdebug == NULL) {
1001  LOG_POST(Error << "CGlRenderDebug: unable to cast render manager to CGlRenderDebug");
1002  return;
1003  }
1004  }
1006  }
1007 
1008  CStopWatch t;
1009  t.Start();
1010 #endif
1011 
1012  //m_Renderer->ClearDisplayList();
1014  m_Renderer->ZoomOnRange(mrc);
1015  m_Renderer->SetVertScroll(x_GetParent()->GetPort().GetVisibleRect().Top());
1016  m_Renderer->Render();
1017 
1018  CGlPane& ruler_pane = m_Renderer->GetRulerGlPane();
1019  CGlPane& feat_pane = m_Renderer->GetFeatGlPane();
1020 
1021  m_TrackHandler.Render(feat_pane);
1022 
1023  // ZoomHandler indicator, Linear selection, seqmark (hairpin),
1024  // rectangular selection and bookmarks
1025  gl.Enable(GL_BLEND);
1026  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1027 
1028  // rendering highlighted tooltip
1030 
1031  // Sequence markers (hairpin) on the ruler bar
1033  if (iter->second->IsRemoved()) continue;
1034 
1035  iter->second->Render(ruler_pane, CSeqMarkHandler::eActiveState);
1036  iter->second->Render(feat_pane, CSeqMarkHandler::ePassiveState);
1037  }
1038 
1039  // Zoom
1040  m_MouseZoomHandler.Render(ruler_pane);
1041  m_MouseZoomHandler.Render(feat_pane);
1042 
1043  // draw linear selection
1044  m_SelHandler.Render(ruler_pane);
1046 
1047  x_RenderRectSelHandler(feat_pane);
1048 
1049  gl.Disable(GL_BLEND);
1050 
1052 
1053  CHECK_GLERROR();
1054 
1055 #ifdef ATTRIB_MENU_SUPPORT
1056  t.Stop();
1057  m_RenderMs = t.Elapsed();
1058 
1060 #endif
1061 
1062 }
1063 
1064 
1066 {
1067  return x_GetParent()->GetPort().GetViewport();
1068 }
1069 
1070 
1071 void CSeqGraphicPane::RenderVectorGraphics(int vp_width, int vp_height)
1072 {
1073  if (!x_GetParent() || !m_DS)
1074  return;
1075 
1076  IRender& gl = GetGl();
1077 
1078  // main rendering...
1080 
1081  CGlPane& ruler_pane = m_Renderer->GetRulerGlPane();
1082  CGlPane& feat_pane = m_Renderer->GetFeatGlPane();
1083 
1084  m_TrackHandler.Render(feat_pane);
1085 
1086  // ZoomHandler indicator, Linear selection, seqmark (hairpin),
1087  // rectangular selection and bookmarks
1088  gl.Enable(GL_BLEND);
1089  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1090 
1091  // rendering highlighted tooltip
1092  //x_RenderTooltipConnector();
1093 
1094  // Sequence markers (hairpin) on the ruler bar
1096  if (iter->second->IsRemoved()) continue;
1097 
1098  iter->second->Render(ruler_pane, CSeqMarkHandler::eActiveState);
1099  iter->second->Render(feat_pane, CSeqMarkHandler::ePassiveState);
1100  }
1101 
1102  // draw linear selection
1103 
1104  m_SelHandler.Render(ruler_pane);
1106  x_RenderRectSelHandler(feat_pane);
1107 
1108  gl.Disable(GL_BLEND);
1109 
1110 
1111  ///
1112  /// Draw Title if requested. The dialog should have made room
1113  /// for the title be creating the viewing window (CMedia) to be larger
1114  ///
1115 
1116  if (m_Title) {
1117 
1119  float title_height = font->TextHeight() - font->GetFontDescender();
1120  float vert_offset = title_height + 2.0f;
1121 
1122  string title = m_DS->GetAcc_Best();
1123  if (title.size() > 0)
1124  title += ":";
1125 
1127  title += NStr::NumericToString((unsigned long)range.GetFrom());
1128  title += ".." + NStr::NumericToString((unsigned long)range.GetTo());
1129  title += " " + m_DS->GetTitle();
1130 
1131  gl.Viewport(0, vp_height-vert_offset, vp_width, vert_offset);
1132  gl.MatrixMode(GL_PROJECTION);
1133  gl.LoadIdentity();
1134  gl.Ortho(0, vp_width, 0, vert_offset, -1.0, 1.0);
1135  gl.MatrixMode(GL_MODELVIEW);
1136  gl.LoadIdentity();
1137 
1138  gl.Color3f(0.9f, 0.9f, 0.9f);
1139  gl.Rectf(0.0f, 0.0f, float(vp_width), float(vert_offset));
1140  gl.Color3f(0.0f, 0.0f, 0.0f);
1141  gl.BeginText(font);
1142  TModelUnit yoffset = -font->GetFontDescender();
1143  gl.WriteText(0.0f, yoffset, float(vp_width), float(vert_offset-yoffset), title.c_str(), IGlFont::eAlign_Left);
1144  gl.EndText();
1145  }
1146 }
1147 
1148 
1150 {
1151  if (!x_GetParent() || !m_DS)
1152  return;
1153 
1154  // The layout in PDF model may be different from the one
1155  // regular rendering mode. Update the layout and adjust
1156  // the image size
1159 }
1160 
1161 
1163 {
1164  return x_GetOnlyOneSelectedGlyph();
1165 }
1166 
1167 // wuliangs: move this to Switch Point Track
1169 {
1171 
1172  const CSwitchPointGlyph* sp =
1173  dynamic_cast<const CSwitchPointGlyph*>(sel_glyph.GetPointer());
1174 
1175  if ( !sp ) return;
1176 
1177  if (x_HasDefaultMarker()) {
1178  TSeqPos marker_pos = x_GetDefaultMarker().GetPos();
1179  // marker is on this alignment?
1180  TSeqRange range = sp->GetRange();
1181  if (!range.IntersectingWith(TSeqRange(marker_pos, marker_pos)))
1182  return;
1183 
1185  if (!the_point)
1186  return;
1187 
1188  try {
1189  the_point->ChangeSwitchPoint(marker_pos, 0);
1190  } catch (std::exception&) {
1191  LOG_POST(Error << "x_ChangeSwitchPoint(): error chaning switch point");
1192  }
1193  }
1194 }
1195 
1196 
1198 {
1199  int x1 = m_StartPoint.x;
1200  int y1 = MZHH_GetVPPosByY(m_StartPoint.y);
1201  int x2 = m_DragPoint.x;
1202  int y2 = MZHH_GetVPPosByY(m_DragPoint.y);
1203  TVPRect rc( min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));
1204  if (!rc.IsEmpty()) {
1206  }
1207 }
1208 
1209 
1211 {
1212  if (m_ActivatedTipId.empty() ||
1214  return;
1215  }
1216 
1217  IRender& gl = GetGl();
1218 
1219  // get the glyph for the given tip_id
1221  CWeakRef<CSeqGlyph>::TRefType glyph = glyph_wk.Lock();
1222  // get tooltip frame rect
1223  vector<TipLocation> tip_rects = GetDisplayedTips();
1224  vector<TipLocation>::const_iterator curr_tip = tip_rects.begin();
1225  while (curr_tip != tip_rects.end() && curr_tip->TipID != m_ActivatedTipId) {
1226  ++curr_tip;
1227  }
1228 
1229  if (glyph && curr_tip != tip_rects.end()) {
1230  const CGlRect<float>& tip_rect = curr_tip->TipRect;
1231  const CRenderingContext* ctx = glyph->GetRenderingContext();
1232 
1233  CGlPane& pane = m_Renderer->GetFeatGlPane();
1234 
1235  // calculate tooltip rect in feature pane space
1236  TModelRect tip_rect_m;
1237  tip_rect_m.SetLeft(ctx->GetOffset() + ctx->ScreenToSeq(m_Flipped ? -tip_rect.Right() : tip_rect.Left()));
1238  tip_rect_m.SetRight(ctx->GetOffset() + ctx->ScreenToSeq(m_Flipped ? -tip_rect.Left() : tip_rect.Right()));
1239  tip_rect_m.SetTop(pane.GetOffsetY() - tip_rect.Top());
1240  tip_rect_m.SetBottom(tip_rect_m.Top() + tip_rect.Height());
1241 
1242  // calculate object rect in world corrd.
1243  TModelPoint glyph_pos;
1244  glyph->GetPosInWorld(glyph_pos);
1245  TModelRect glyph_rect;
1246  glyph_rect.SetLeft(glyph_pos.X());
1247  glyph_rect.SetTop(glyph_pos.Y());
1248  glyph_rect.SetRight(glyph_pos.X() + glyph->GetWidth());
1249  glyph_rect.SetBottom(glyph_pos.Y() + glyph->GetHeight());
1250 
1251  CGlPaneGuard GUARD(pane, CGlPane::eOrtho);
1252  gl.PushMatrix();
1253 
1254  // highlight glyph
1255  gl.Translatef(0.0, -pane.GetOffsetY(), 0.0f);
1256  gl.Color4f(1.0f, 0.0f, 0.0f, 0.4f);
1257  TModelUnit band_w = 6.0;
1258  TModelUnit band_w_x = ctx->ScreenToSeq(band_w);
1259  TModelUnit x_left = glyph_rect.Left() - ctx->GetOffset();
1260  TModelUnit x_right = glyph_rect.Right() - ctx->GetOffset();
1261 
1262  CRgbaColor color1(1.0f, 0.0f, 0.0f, 0.5f);
1263  CRgbaColor color2(1.0f, 0.0f, 0.0f, 0.0f);
1264  gl.ShadeModel(GL_SMOOTH);
1265  gl.Begin(GL_QUADS);
1266  gl.ColorC(color1);
1267  gl.Vertex3d(x_left, glyph_rect.Top(), 0.0);
1268  gl.Vertex3d(x_right, glyph_rect.Top(), 0.0);
1269  gl.ColorC(color2);
1270  gl.Vertex3d(x_right, glyph_rect.Top() - band_w, 0.0);
1271  gl.Vertex3d(x_left, glyph_rect.Top() - band_w, 0.0);
1272  gl.ColorC(color1);
1273  gl.Vertex3d(x_right, glyph_rect.Bottom(), 0.0);
1274  gl.Vertex3d(x_left, glyph_rect.Bottom(), 0.0);
1275  gl.ColorC(color2);
1276  gl.Vertex3d(x_left, glyph_rect.Bottom() + band_w, 0.0);
1277  gl.Vertex3d(x_right, glyph_rect.Bottom() + band_w, 0.0);
1278 
1279  gl.ColorC(color1);
1280  gl.Vertex3d(x_left, glyph_rect.Bottom(), 0.0);
1281  gl.Vertex3d(x_left, glyph_rect.Top(), 0.0);
1282  gl.ColorC(color2);
1283  gl.Vertex3d(x_left - band_w_x, glyph_rect.Top(), 0.0);
1284  gl.Vertex3d(x_left - band_w_x, glyph_rect.Bottom(), 0.0);
1285  gl.ColorC(color1);
1286  gl.Vertex3d(x_right, glyph_rect.Bottom(), 0.0);
1287  gl.Vertex3d(x_right, glyph_rect.Top(), 0.0);
1288  gl.ColorC(color2);
1289  gl.Vertex3d(x_right + band_w_x, glyph_rect.Top(), 0.0);
1290  gl.Vertex3d(x_right + band_w_x, glyph_rect.Bottom(), 0.0);
1291 
1292  gl.ColorC(color1);
1293  gl.Vertex3d(x_left, glyph_rect.Top(), 0.0);
1294  gl.ColorC(color2);
1295  gl.Vertex3d(x_left, glyph_rect.Top() - band_w, 0.0);
1296  gl.Vertex3d(x_left - band_w_x, glyph_rect.Top() - band_w, 0.0);
1297  gl.Vertex3d(x_left - band_w_x, glyph_rect.Top(), 0.0);
1298  gl.ColorC(color1);
1299  gl.Vertex3d(x_right, glyph_rect.Top(), 0.0);
1300  gl.ColorC(color2);
1301  gl.Vertex3d(x_right + band_w_x, glyph_rect.Top(), 0.0);
1302  gl.Vertex3d(x_right + band_w_x, glyph_rect.Top() - band_w, 0.0);
1303  gl.Vertex3d(x_right, glyph_rect.Top() - band_w, 0.0);
1304 
1305  gl.ColorC(color1);
1306  gl.Vertex3d(x_left, glyph_rect.Bottom(), 0.0);
1307  gl.ColorC(color2);
1308  gl.Vertex3d(x_left, glyph_rect.Bottom() + band_w, 0.0);
1309  gl.Vertex3d(x_left - band_w_x, glyph_rect.Bottom() + band_w, 0.0);
1310  gl.Vertex3d(x_left - band_w_x, glyph_rect.Bottom(), 0.0);
1311  gl.ColorC(color1);
1312  gl.Vertex3d(x_right, glyph_rect.Bottom(), 0.0);
1313  gl.ColorC(color2);
1314  gl.Vertex3d(x_right + band_w_x, glyph_rect.Bottom(), 0.0);
1315  gl.Vertex3d(x_right + band_w_x, glyph_rect.Bottom() + band_w, 0.0);
1316  gl.Vertex3d(x_right, glyph_rect.Bottom() + band_w, 0.0);
1317 
1318  gl.End();
1319 
1320  gl.ShadeModel(GL_FLAT);
1321 
1322  // draw connector between glyph and tooltip
1323  TModelPoint start_pnt = tip_rect_m.CenterPoint();
1324  TModelPoint end_pnt = glyph_rect.CenterPoint();
1325  TModelRange t_h(tip_rect_m.Left(), tip_rect_m.Right());
1326  TModelRange g_h(glyph_rect.Left(), glyph_rect.Right());
1327  TModelRange t_v(tip_rect_m.Top(), tip_rect_m.Bottom());
1328  TModelRange g_v(glyph_rect.Top(), glyph_rect.Bottom());
1329  TModelRange temp;
1330  bool no_connector = false;
1331  if (tip_rect_m.Bottom() < glyph_rect.Top()) {
1332  // tip obove object
1333  start_pnt.m_Y = t_v.GetTo();
1334  end_pnt.m_Y = g_v.GetFrom();
1335  temp = t_h.IntersectionWith(g_h);
1336  temp.SetTo(temp.GetTo() - 1.0);
1337  if (temp.Empty()) {
1338  start_pnt.m_X = t_h.GetFrom() < g_h.GetFrom() ? t_h.GetTo() : t_h.GetFrom();
1339  end_pnt.m_X = t_h.GetFrom() < g_h.GetFrom() ? g_h.GetFrom() : g_h.GetTo();
1340  } else {
1341  start_pnt.m_X = end_pnt.m_X = temp.GetFrom();
1342  }
1343  } else if (tip_rect_m.Top() > glyph_rect.Bottom()) {
1344  // tip under object
1345  start_pnt.m_Y = t_v.GetFrom();
1346  end_pnt.m_Y = g_v.GetTo();
1347  temp = t_h.IntersectionWith(g_h);
1348  temp.SetTo(temp.GetTo() - 1.0);
1349  if (temp.Empty()) {
1350  start_pnt.m_X = t_h.GetFrom() < g_h.GetFrom() ? t_h.GetTo() : t_h.GetFrom();
1351  end_pnt.m_X = t_h.GetFrom() < g_h.GetFrom() ? g_h.GetFrom() : g_h.GetTo();
1352  } else {
1353  start_pnt.m_X = end_pnt.m_X = temp.GetFrom();
1354  }
1355  } else if (tip_rect_m.Left() > glyph_rect.Right()) {
1356  // tip on the right side
1357  start_pnt.m_X = t_h.GetFrom();
1358  end_pnt.m_X = g_h.GetTo();
1359  temp = t_v.IntersectionWith(g_v);
1360  temp.SetTo(temp.GetTo() - 1.0);
1361  if (temp.Empty()) {
1362  start_pnt.m_Y = t_v.GetFrom() < g_v.GetFrom() ? t_v.GetTo() : t_v.GetFrom();
1363  end_pnt.m_Y = t_v.GetFrom() < g_v.GetFrom() ? g_v.GetFrom() : g_v.GetTo();
1364  } else {
1365  start_pnt.m_Y = end_pnt.m_Y = temp.GetFrom();
1366  }
1367  } else if (tip_rect_m.Right() < glyph_rect.Left()) {
1368  // tip on the left side
1369  start_pnt.m_X = t_h.GetTo();
1370  end_pnt.m_X = g_h.GetFrom();
1371  temp = t_v.IntersectionWith(g_v);
1372  temp.SetTo(temp.GetTo() - 1.0);
1373  if (temp.Empty()) {
1374  start_pnt.m_Y = t_v.GetFrom() < g_v.GetFrom() ? t_v.GetTo() : t_v.GetFrom();
1375  end_pnt.m_Y = t_v.GetFrom() < g_v.GetFrom() ? g_v.GetFrom() : g_v.GetTo();
1376  } else {
1377  start_pnt.m_Y = end_pnt.m_Y = temp.GetFrom();
1378  }
1379  } else {
1380  // overlapping
1381  no_connector = true;
1382  }
1383 
1384  if ( !no_connector ) {
1385  const TModelUnit small_num = 0.000001;
1386  TModelUnit len_pix = min(TModelUnit(40.0), t_v.GetLength());
1387  TModelPoint start_pnt1 = start_pnt;
1388  TModelPoint start_pnt2 = start_pnt;
1389  TModelUnit dx = ctx->SeqToScreen(start_pnt.m_X - end_pnt.m_X);
1390  TModelUnit dy = start_pnt.m_Y - end_pnt.m_Y;
1391  TModelUnit dist = sqrt(dx*dx + dy*dy);
1392  TModelUnit off_x = dist < small_num ? len_pix : dy * len_pix / dist;
1393  TModelUnit off_y = dist < small_num ? 0.0 : dx * len_pix / dist;
1394  if (fabs(off_x) < small_num) {
1395  start_pnt1.m_X = start_pnt2.m_X = start_pnt.m_X;
1396  start_pnt1.m_Y = start_pnt.m_Y - len_pix * 0.5;
1397  start_pnt2.m_Y = start_pnt.m_Y + len_pix * 0.5;
1398  TModelUnit shift = 0.0;
1399  if (start_pnt1.m_Y < t_v.GetFrom()) {
1400  shift = t_v.GetFrom() - start_pnt1.m_Y;
1401  } else if (start_pnt2.m_Y > t_v.GetTo()) {
1402  shift = t_v.GetTo() - start_pnt2.m_Y;
1403  }
1404  start_pnt1.m_Y += shift;
1405  start_pnt2.m_Y += shift;
1406  } else if (fabs(off_y) < small_num) {
1407  start_pnt1.m_Y = start_pnt2.m_Y = start_pnt.m_Y;
1408  start_pnt1.m_X = start_pnt.m_X - ctx->ScreenToSeq(len_pix) * 0.5;
1409  start_pnt2.m_X = start_pnt.m_X + ctx->ScreenToSeq(len_pix) * 0.5;
1410  TModelUnit shift = 0.0;
1411  if (start_pnt1.m_X < t_h.GetFrom()) {
1412  shift = t_h.GetFrom() - start_pnt1.m_X;
1413  } else if (start_pnt2.m_X > t_h.GetTo()) {
1414  shift = t_h.GetTo() - start_pnt2.m_X;
1415  }
1416  start_pnt1.m_X += shift;
1417  start_pnt2.m_X += shift;
1418  } else {
1419  if (dx * dy < 0) {
1420  off_y = -off_y;
1421  off_x = -off_x;
1422  }
1423  start_pnt1.m_X = start_pnt.m_X;
1424  start_pnt2.m_Y = start_pnt.m_Y;
1425  start_pnt1.m_Y = start_pnt.m_Y + off_y;
1426  start_pnt2.m_X = start_pnt.m_X + ctx->ScreenToSeq(off_x);
1427  }
1428 
1429  gl.Color4f(1.0f, 1.0f, 0.65f, 0.4f);
1430  ctx->DrawTriangle(start_pnt1.m_X, start_pnt1.m_Y,
1431  start_pnt2.m_X, start_pnt2.m_Y,
1432  end_pnt.m_X, end_pnt.m_Y);
1433 
1434  CGlAttrGuard LineGuard(GL_LINE_BIT);
1435  gl.Enable(GL_LINE_SMOOTH);
1436 
1437  gl.Color4f(0.0f, 0.0f, 0.0f, 0.9f);
1438  ctx->DrawLine(start_pnt1.m_X, start_pnt1.m_Y, end_pnt.m_X, end_pnt.m_Y);
1439  ctx->DrawLine(start_pnt2.m_X, start_pnt2.m_Y, end_pnt.m_X, end_pnt.m_Y);
1440  }
1441 
1442  gl.PopMatrix();
1443 
1444  }
1445 }
1446 
1447 
1449 {
1450  if (m_MouseMode == eMouse_RectSelect ||
1452 
1453  IRender& gl = GetGl();
1454 
1455  CGlAttrGuard LineGuard(GL_LINE_BIT);
1456  CGlPaneGuard GUARD(pane, CGlPane::ePixels);
1457 
1458  gl.LineWidth(1.0f);
1459  gl.Color4f(0.0f, 0.0f, 0.0f, 1.0f);
1460 
1461  gl.Enable(GL_LINE_STIPPLE);
1462  gl.LineStipple(1, 0x0F0F);
1463 
1464  int x1 = m_StartPoint.x;
1465  int y1 = MZHH_GetVPPosByY(m_StartPoint.y);
1466  int x2 = m_DragPoint.x;
1467  int y2 = MZHH_GetVPPosByY(m_DragPoint.y);
1468 
1469  if (x2 < x1)
1470  swap(x1, x2);
1471  if (y2 < y1)
1472  swap(y1, y2);
1473 
1474  gl.Begin(GL_LINES);
1475  gl.Vertex2d(x1, y2);
1476  gl.Vertex2d(x2, y2);
1477 
1478  gl.Vertex2d(x2, y2);
1479  gl.Vertex2d(x2, y1);
1480 
1481  gl.Vertex2d(x1, y2);
1482  gl.Vertex2d(x1, y1);
1483 
1484  gl.Vertex2d(x1, y1);
1485  gl.Vertex2d(x2, y1);
1486  gl.End();
1487 
1488  gl.Disable(GL_LINE_STIPPLE);
1489  }
1490 }
1491 
1492 
1493 ////////////////////////////////////////////////////////////////////////////
1494 /*int CSeqGraphicPane::x_HandleKeyEvent()
1495 {
1496  IGlEventHandler* pH = NULL; //dummy
1497  int res = x_Handlers_handle(fArea_All, pH, false);
1498 
1499  if (res == 0 && m_Event.GetFLTKEvent() == FL_KEYDOWN) {
1500  CGlPane& ref_pane = m_Renderer->GetFeatGlPane();
1501  TModelPoint ref_point = ref_pane.UnProject(Fl::event_x(),
1502  MZHH_GetVPPosByY(h() - Fl::event_y()));
1503  switch(m_Event.GetGUISignal()) {
1504  case CGUIEvent::eZoomInSignal: ZoomInPoint(ref_point); break;
1505  case CGUIEvent::eZoomOutSignal: ZoomOutPoint(ref_point); break;
1506  case CGUIEvent::eZoomAllSignal: ZoomAll(); break;
1507  case CGUIEvent::eNextItem: NextPrevSplice(eDir_Next); break;
1508  case CGUIEvent::ePrevItem: NextPrevSplice(eDir_Prev); break;
1509  default: break;
1510  }
1511  }
1512  return res;
1513 }*/
1514 
1515 
1516 // Place selected objects into clipboard
1518 {
1519  /*CClipboard::Instance().Clear();
1520 
1521  // retrieve and process selections
1522  CScope& scope = m_DS->GetBioseqHandle().GetScope();
1523 
1524  TConstObjects sel_objs;
1525  GetObjectSelection(sel_objs);
1526 
1527  ITERATE (TConstObjects, it, sel_objs) {
1528  CClipboard::Instance().Add(SConstScopedObject(**it, scope));
1529  }
1530 
1531  IClipboardHandler::x_OnCopy();*/
1532 }
1533 
1534 
1536 {
1537  return m_BackForwardPos > 0;
1538 }
1539 
1540 
1542 {
1543  return m_BackForwardPos < m_BackForwardHistory.size() - 1;
1544 }
1545 
1546 
1548 {
1549  if (CanGoBack()) {
1551  x_GetParent()->ZoomOnRange(range, 0);
1552  }
1553 }
1554 
1555 
1557 {
1558  if (CanGoForward()) {
1560  x_GetParent()->ZoomOnRange(range, 0);
1561  }
1562 }
1563 
1564 
1566 {
1568  TSeqRange r_old = m_BackForwardHistory.empty() ? TSeqRange() :
1570 
1571  if (r_cur != r_old) {
1572  // first, empty history from current and up
1573  if (m_BackForwardPos < m_BackForwardHistory.size()) {
1574  m_BackForwardHistory.erase
1575  (m_BackForwardHistory.begin() + m_BackForwardPos + 1,
1576  m_BackForwardHistory.end());
1577  }
1578 
1579  if ( !m_BackForwardHistory.empty() ) {
1580  // do not save position if it's already there
1581  if (r_cur != m_BackForwardHistory.back()) {
1582  m_BackForwardHistory.push_back(r_cur);
1583  }
1584  } else {
1585  m_BackForwardHistory.push_back(r_cur);
1586  }
1587 
1589  x_GetParent()->SetDirty(true);
1590  }
1591 }
1592 
1593 
1594 void CSeqGraphicPane::OnSearchTip(const string& tip_id, const wxRect& tip_rect)
1595 {
1596  // parse the signature to get range
1597  CSeq_id_Handle idh;
1598  TSeqPos from = 0;
1599  TSeqPos to = 0;
1601  int subtype = 0;
1602  Uint4 fingerprint = 0;
1603  Uint4 ds_fingerprint = 0;
1604  string ds_name;
1605  try {
1606  CObjFingerprint::ParseSignature(tip_id, idh, from, to, type,
1607  subtype, fingerprint, ds_fingerprint, ds_name, &m_DS->GetScope());
1608  } catch (CException&) {
1609  }
1610 
1611  if (idh) {
1612  TSeqRange obj_r(from, to);
1614 
1615  const CGlPane& pane = m_Renderer->GetFeatGlPane();
1616  const TModelRect& vis_rect = pane.GetVisibleRect();
1617  const TVPRect& vp_rect = pane.GetViewport();
1618 
1619  // calculate tooltip rect in feature pane space
1620  wxRect win_rect = GetScreenRect();
1621  TModelRect tip_rect_m;
1622  tip_rect_m.SetLeft(m_Renderer->Screen2Seq(tip_rect.x - win_rect.x, 0));
1623  TModelUnit offset_y = pane.GetOffsetY() - vp_rect.Height();
1624  tip_rect_m.SetTop(tip_rect.y - win_rect.y -
1625  (win_rect.GetHeight() - vp_rect.Height()) + offset_y);
1626  tip_rect_m.SetRight(tip_rect_m.Left() + m_Renderer->Screen2SeqWidth(tip_rect.GetWidth()));
1627  tip_rect_m.SetBottom(tip_rect_m.Top() + tip_rect.GetHeight());
1628 
1629  TSeqPos min_dist = m_Renderer->Screen2SeqWidth(60);
1630  bool need_shift = true;
1631  if (vis_r.IntersectingWith(obj_r)) {
1632  // get the glyph for the given tip_id
1633  CWeakRef<CSeqGlyph> glyph_wk = x_GetGlyphByTipId(tip_id);
1634  CWeakRef<CSeqGlyph>::TRefType glyph = glyph_wk.Lock();
1635 
1636  if (glyph) {
1637  TModelPoint glyph_pos;
1638  glyph->GetPosInWorld(glyph_pos);
1639  TModelRect glyph_rect;
1640  glyph_rect.SetLeft(glyph_pos.X());
1641  glyph_rect.SetTop(glyph_pos.Y());
1642  glyph_rect.SetRight(glyph_pos.X() + glyph->GetWidth());
1643  glyph_rect.SetBottom(glyph_pos.Y() + glyph->GetHeight());
1644  if ( !tip_rect_m.Intersects(glyph_rect) ) {
1645  need_shift = false;
1646  }
1647  } else {
1648  // we know the target object is located in the visible range,
1649  // but it is not showing. There are many possibilities:
1650  // the track gets collapsed or closed, or the object is
1651  // packed into a histogram. We may need to use OnZoomTip
1652  // in order to show the object if it is in packed form.
1653  need_shift = false;
1655  }
1656  }
1657 
1658  if (need_shift) {
1659  // make sure the target object is not completely hidden under
1660  int shift = 0;
1661  if (tip_rect_m.Left() + tip_rect_m.Right() < vis_rect.Left() + vis_rect.Right()) {
1662  TSeqPos target_pos =
1663  TSeqPos(min(vis_rect.Right(), tip_rect_m.Right() + min_dist));
1664  shift = obj_r.GetFrom() - target_pos;
1665  } else {
1666  TSeqPos target_pos = TSeqPos(max(vis_rect.Left(), tip_rect_m.Left() - min_dist));
1667  shift = obj_r.GetTo() - target_pos;
1668  }
1669  from = (TSeqPos)(max(0, (int)vis_r.GetFrom() + shift));
1670  to = (TSeqPos)(max(0, (int)vis_r.GetTo() + shift));
1672  }
1673  }
1674 }
1675 
1676 
1677 void CSeqGraphicPane::OnZoomTip(const string& tip_id, const wxRect& /*tip_rect*/)
1678 {
1679  // parse the signature to get range
1680  CSeq_id_Handle idh;
1681  TSeqPos from = 0;
1682  TSeqPos to = 0;
1684  int subtype = 0;
1685  Uint4 fingerprint = 0;
1686  Uint4 ds_fingerprint = 0;
1687  string ds_name;
1688  try {
1689  CObjFingerprint::ParseSignature(tip_id, idh, from, to, type,
1690  subtype, fingerprint, ds_fingerprint, ds_name, &m_DS->GetScope());
1691  } catch (CException&) {
1692  }
1693 
1694  if (idh) {
1695  // zoom to range with a margin
1696  x_GetParent()->ZoomOnRange(TSeqRange(from, to),
1698  }
1699 }
1700 
1701 
1702 void CSeqGraphicPane::OnInfoTip(const string& /*tip_id*/)
1703 {
1704 }
1705 
1706 
1707 void CSeqGraphicPane::OnTipAdded(const string& tip_id)
1708 {
1710  if (last_hit_glyph) {
1711  const IObjectBasedGlyph* obj_glyph =
1712  dynamic_cast<const IObjectBasedGlyph*>(last_hit_glyph.GetPointer());
1713  if (obj_glyph && m_PinnedTips.count(tip_id) == 0 && obj_glyph->GetObject(0)) {
1714  string track_name = s_GetTrackName(tip_id);
1715  CRef<CCachedTipHandle> tip_handle(new CCachedTipHandle(track_name, m_DS->GetScope()));
1716  tip_handle->Add(const_cast<CObject&>(*obj_glyph->GetObject(0)));
1717  m_PinnedTips[tip_id] = tip_handle;
1718  }
1719  }
1720 }
1721 
1722 
1723 void CSeqGraphicPane::OnTipRemoved(const string& tip_id)
1724 {
1725  m_PinnedTips.erase(tip_id);
1726 }
1727 
1728 
1729 // IMouseZoomHandlerHost implementation
1731 {
1732  const CGlPane& VP = x_GetParent()->GetPort();
1733  switch (type) {
1734  case eCurrent: return VP.GetScaleX();
1735  case eMin: return VP.GetMinScaleX();
1736  case eMax: return VP.GetZoomAllScaleX();
1737  default: _ASSERT(false); return -1;
1738  }
1739 }
1740 
1741 
1743 {
1744  x_GetParent()->SetScaleX(scale, point);
1745 }
1746 
1747 
1749 {
1750  x_GetParent()->ZoomPoint(point, factor);
1751 }
1752 
1753 
1755 {
1756  TModelRect vert_bar(rc);
1758  vert_bar.SetTop(rec.Top());
1759  vert_bar.SetBottom(rec.Bottom());
1760  x_GetParent()->ZoomRect(vert_bar);
1761 }
1762 
1763 
1765 {
1766  x_GetParent()->Scroll(d_x, d_y);
1767 }
1768 
1769 
1771 {
1772  // translate the notification to the standard message
1773  SaveCurrentRange();
1775 }
1776 
1777 
1779 {
1780  return GetClientSize().y - 1 - y;
1781 }
1782 
1783 
1784 //// ISeqMarkHandlerHost implementation
1786 {
1787  return SHH_GetModelByWindow(z, orient);
1788 }
1789 
1790 
1792 {
1793  // We want the marker handler to track and maintain the marker position
1794  // since there may be multiple sequence markers.
1795  return TSeqPos(-1);
1796 }
1797 
1798 
1800 {
1801  // New sequence marker position changed, update other
1802  // widgets if necessary
1803  // max(TSeqPos(0), mark);
1804  // min(mark, m_DS->GetSequenceLength() - 1);
1807 }
1808 
1809 
1810 void CSeqGraphicPane::SMHH_OnReset(const string& id)
1811 {
1812  x_RemoveMarker(id);
1815 }
1816 
1817 
1818 /// ISelHandlerHost implementation
1820 {
1822  Refresh();
1823 }
1824 
1825 
1827 {
1828  switch(orient) {
1829  case eHorz: return m_Renderer->GetRulerGlPane().UnProjectX(z);
1830  case eVert: return m_Renderer->GetRulerGlPane().UnProjectY(GetClientSize().y - z);
1831  default: _ASSERT(false); return -1;
1832  }
1833 }
1834 
1835 
1837 {
1838  switch(orient) {
1839  case eHorz: return m_Renderer->GetRulerGlPane().ProjectX(z);
1840  case eVert: return GetClientSize().y - m_Renderer->GetRulerGlPane().ProjectY(z);
1841  default: _ASSERT(false); return -1;
1842  }
1843 }
1844 
1845 
1847 {
1849  Refresh();
1850 }
1851 
1852 
1854 {
1856 }
1857 
1858 
1860 {
1861  SetPopupMenuDisplayed(true);
1862  PopupMenu(menu);
1863  SetPopupMenuDisplayed(false);
1864 }
1865 
1866 
1867 void CSeqGraphicPane::LTH_ConfigureTracksDlg(const string& category)
1868 {
1870 }
1871 
1873 {
1875 }
1876 
1877 TSeqRange CSeqGraphicPane::FindText(const string &text, bool match_case)
1878 {
1880  if (range.NotEmpty())
1881  return range;
1882 
1883  auto mfo = GetFeaturePanel()->FindText(text, match_case);
1885  {
1887  }
1888  if(mfo.HasMappedFeat()) {
1889  const CSeq_feat& feat = mfo.GetMappedFeat().GetOriginalFeature();
1890 
1891  SelectObject(&feat, true);
1892  } else {
1893  SelectObject(mfo.GetObject(), true);
1894  }
1896  range = mfo.GetRange();
1897  if (range.GetTo() == range.GetFrom())
1898  range.SetTo(range.GetTo() + 1);
1899 
1900  TSeqPos margin = TSeqPos(range.GetLength() * 0.15f);
1901  CSGSequenceDS* pDS = GetDataSource();
1902  if (pDS) {
1903  TSeqPos len = pDS->GetSequenceLength();
1904  range.SetFrom(range.GetFrom() > margin ? range.GetFrom() - margin : 0);
1905  range.SetTo(range.GetTo() < len - margin ? range.GetTo() + margin : len - 1);
1906  }
1907 
1908  return range;
1909 }
1910 
1912 {
1913  PushEventHandler(handler);
1914 }
1915 
1916 
1918 {
1919  PopEventHandler();
1920 }
1921 
1922 
1924 {
1925  // temprorarily disable sticky tooltip popup
1926  SetPopupMenuDisplayed(true);
1927 }
1928 
1929 
1931 {
1932  // enable sticky tooltip popup
1933  SetPopupMenuDisplayed(false);
1934  DlgOverlayFix();
1935 }
1936 
1937 // send to parents an event notifing that selection has changed
1939 {
1941  Send(&evt, ePool_Parent);
1942 }
1943 
1944 
1946 {
1948  Send(&evt, ePool_Parent);
1949 }
1950 
1951 
1953 {
1954  CRef<CLayoutTrack> track;
1956  if (last_hit_glyph) {
1957  track.Reset(dynamic_cast<CLayoutTrack*>(last_hit_glyph.GetPointer()));
1958  }
1959 
1960  return track;
1961 }
1962 
1963 
1965 {
1966  const CGlPane& pane = m_Renderer->GetFeatGlPane();
1967  return pane.UnProject(pt.x, MZHH_GetVPPosByY(pt.y));
1968 }
1969 
1970 
1971 ///////////////////////////////////////////////////////////////////////////////
1972 /// ITooltip Implementation
1973 /// TC_NeedTooltip() and TC_GetTooltip() is evrything needed to show toolitps
1974 //bool CSeqGraphicPane::TC_NeedTooltip(const wxPoint& pt)
1975 //{
1976 // if (!m_DS) return false;
1977 //
1978 // m_TooltipText = "";
1979 // CWeakRef<CSeqGlyph>::TRefType last_hit_glyph = m_LastHitGlyph.Lock();
1980 // if (last_hit_glyph) {
1981 // const CGlPane& pane = m_Renderer->GetFeatGlPane();
1982 // TModelPoint pos = pane.UnProject(pt.x, MZHH_GetVPPosByY(pt.y));
1983 // last_hit_glyph->GetTooltip(pos, m_TooltipText);
1984 // }
1985 //
1986 // return m_TooltipText.length() > 0;
1987 //}
1988 //
1989 //
1990 //string CSeqGraphicPane::TC_GetTooltip(const wxRect&)
1991 //{
1992 // return m_TooltipText;
1993 //}
1994 
1995 
1996 static string s_GetRandomTipID()
1997 {
1998  srand(static_cast<unsigned>(time(NULL)));
1999  return kCommonTipId + NStr::IntToString(rand());
2000 }
2001 
2002 string CSeqGraphicPane::TTHH_NeedTooltip(const wxPoint& pt)
2003 {
2004  m_TooltipInfo.SetTipID("");
2007 
2008  if (m_DS) {
2010  if (last_hit_glyph) {
2011  string title;
2012  const CGlPane& pane = m_Renderer->GetFeatGlPane();
2013  TModelPoint pos = pane.UnProject(pt.x, MZHH_GetVPPosByY(pt.y));
2015  if (last_hit_glyph->NeedTooltip(pos, *tooltip, title)) {
2016  m_TooltipInfo.SetTipText(tooltip->Render());
2017  m_TooltipInfo.SetTitleText(title);
2018 
2019  // check if any cached ids
2020  string tip_id = x_GetCachedTipId(last_hit_glyph.GetPointer());
2021  if (tip_id.empty()) {
2022  tip_id = s_GetRandomTipID();
2024  }
2025  m_TooltipInfo.SetTipID(tip_id);
2026  }
2027  }
2028  }
2029 
2030  return m_TooltipInfo.GetTipID();
2031 }
2032 
2033 
2035 {
2036  if (m_TooltipInfo.GetTipText().empty()) {
2037  CRef<CSeqGlyph> last_hit_glyph(m_LastHitGlyph.Lock());
2038  if (last_hit_glyph) {
2039  const CGlPane& pane = m_Renderer->GetFeatGlPane();
2040  TModelPoint pos = pane.UnProject(rect.x, MZHH_GetVPPosByY(rect.y));
2041 
2042  try {
2043  CSeqGlyph* glyph = last_hit_glyph.GetPointer();
2045  [glyph, pos](ICanceled&)
2046  {
2048  string tip_title;
2050  glyph->GetTooltip(pos, *tooltip, tip_title);
2051  info.SetTipText(tooltip->Render());
2052  info.SetTitleText(tip_title);
2053 
2054  const IObjectBasedGlyph* obj_glyph =
2055  dynamic_cast<const IObjectBasedGlyph*>(glyph);
2056  if (obj_glyph) {
2057  string tip_id = obj_glyph->GetSignature();
2058  // get parent track title
2059  const CSeqGlyph* p = glyph->GetParent();
2060  while (p) {
2061  const CLayoutTrack* p_track = dynamic_cast<const CLayoutTrack*>(p);
2062  if (p_track) {
2063  tip_id += kCommonTipId + p_track->GetFullTitle();
2064  break;
2065  }
2066  p = p->GetParent();
2067  }
2068  info.SetTipID(tip_id);
2069  info.SetToolTipOptions(CTooltipInfo::ePin |
2071  }
2072  else {
2073  info.SetTipID(s_GetRandomTipID());
2074  info.SetToolTipOptions(0);
2075  }
2076 
2077  return info;
2078  },
2079  wxT("Retrieving tooltip..."));
2080  } NCBI_CATCH("Retrieving tooltip.");
2081  }
2082  }
2083  return m_TooltipInfo;
2084 }
2085 
2086 
2087 bool CSeqGraphicPane::TTHH_ProcessURL(const wxString & href)
2088 {
2089  CURLTooltipHandler url_handler(m_DS->GetScope(), *this);
2090  return url_handler.ProcessURL(href.ToStdString());
2091 }
2092 
2093 // ITooltip end
2094 
2095 
2097 {
2098  names.clear();
2099  const CFeatList& feat_list = *CSeqFeatData::GetFeatList();
2100  ITERATE (CFeatList, iter, feat_list) {
2101  names.push_back(iter->GetDescription());
2102  }
2103 }
2104 
2105 
2107 {
2108  return m_ConfigSettings;
2109 }
2110 
2111 
2113 {
2114  Layout();
2115 }
2116 
2117 
2119 {
2120  if ( !m_ConfigSettings ) {
2121  m_ConfigSettings.Reset(new CSeqGraphicConfig(false, 0, "Default"));
2122  } else {
2124  }
2127 
2128  //x_Redraw(true);
2129  //CEvent evt(eCmdConfigChanged);
2130  //Send(&evt, CEventHandler::eDispatch_Default, ePool_Parent);
2131 }
2132 
2133 
2135 {
2136  const TVPRect& rect = GetViewportRect();
2137  return TVPPoint(rect.Width(), rect.Height());
2138 }
2139 
2140 
2142 {
2143  TModelUnit pos = IsHorizontal() ? point.X() : point.Y();
2144  x_GetDefaultMarker().SetPos(pos);
2147 }
2148 
2149 
2150 void CSeqGraphicPane::RemoveMarker(const string& marker_id)
2151 {
2152  x_RemoveMarker(marker_id);
2155 }
2156 
2157 
2158 void CSeqGraphicPane::AddPointMarker(const string& name,
2159  TSeqPos pos,
2160  const CRgbaColor color)
2161 {
2162  CRef<CMarker> marker;
2163  marker.Reset(new CMarker);
2165  marker->SetPos((TModelUnit)pos);
2166 
2167  x_AddNewMarker(marker, name, color);
2170 }
2171 
2173 {
2174  CRef<CMarker> marker;
2175  marker.Reset(new CMarker);
2177  marker->SetPos((TModelUnit)range.GetFrom());
2178  marker->SetExtendedPos((TModelUnit)range.GetTo());
2179 
2180  x_AddNewMarker(marker, name, color);
2183 }
2184 
2186 {
2187  x_ClearMarkers();
2190 }
2191 
2192 
2194 {
2195  size_t num = 0;
2196  ITERATE (TSeqMarkers, iter, m_SeqMarkers) {
2197  if ( !iter->second->IsRemoved() ) {
2198  ++num;
2199  }
2200  }
2201  return num;
2202 }
2203 
2204 
2206 {
2208 }
2209 
2210 
2211 void CSeqGraphicPane::RenameMarker(const string& id, const string& label)
2212 {
2214  if (iter != m_SeqMarkers.end() && !iter->second->IsRemoved()) {
2215  CRef<CMarker> marker = iter->second;
2216 
2217  // Reset new label
2218  marker->SetLabel(label);
2219  if (id == kDefaultMarker && label != kDefaultMarkerLabel) {
2220  // Label change on the default marker will make it a non-default marker
2221  // First remove from the list
2222  m_SeqMarkers.erase(iter);
2223 
2224  // Set new id
2225  string marker_id = kNamedMarker + NStr::NumericToString(m_MarkerId++);
2226  marker->m_Handler.SetId(marker_id);
2227 
2228  // Add it back with new id
2229  m_SeqMarkers.insert(TSeqMarkers::value_type(marker_id, marker));
2230  }
2233  }
2234 }
2235 
2236 
2237 void CSeqGraphicPane::ModifyMarker(const string& id, const string& label,
2238  TSeqPos pos, const CRgbaColor color)
2239 {
2240  CRef<CMarker> marker;
2241  if (x_ModifyMarker(marker, id, label, color)) {
2242  marker->SetLabel(label);
2243  marker->SetPos(pos);
2245 
2248  }
2249 }
2250 
2251 void CSeqGraphicPane::ModifyMarker(const string& id, const string& label,
2253 {
2254  CRef<CMarker> marker;
2255  if (x_ModifyMarker(marker, id, label, color)) {
2256  marker->SetRange(range);
2258 
2261  }
2262 }
2263 
2265  const string& id,
2266  const string& label,
2267  const CRgbaColor color)
2268 {
2270  if (iter != m_SeqMarkers.end() && !iter->second->IsRemoved()) {
2271  marker = iter->second;
2272  marker->SetLabel(label);
2273  marker->SetColor(color);
2274  if (id == kDefaultMarker && label != kDefaultMarkerLabel) {
2275  // Label change on the default marker will make it a non-default marker
2276  // First remove from the list
2277  m_SeqMarkers.erase(iter);
2278 
2279  // Set the id
2280  string marker_id = kNamedMarker + NStr::NumericToString(m_MarkerId++);
2281  marker->m_Handler.SetId(marker_id);
2282 
2283  // Add it back with the new id
2284  m_SeqMarkers.insert(TSeqMarkers::value_type(marker_id, marker));
2285  }
2286  return true;
2287  }
2288  return false;
2289 }
2290 
2291 
2293 {
2294  TModelUnit pos = IsHorizontal() ? point.X() : point.Y();
2295  SetSeqStart(TSeqPos(pos));
2296 }
2297 
2298 
2300 {
2301  m_SeqStart = pos;
2303 }
2304 
2305 
2307 {
2308  CConstRef<CMarker> marker = GetMarker(id);
2309  if (marker) {
2310  TSeqPos pos = marker->GetPos();
2311  SetSeqStart(pos);
2312  }
2313 }
2314 
2315 
2317 {
2318  SetSeqStart(0);
2319 }
2320 
2321 
2322 // wuliangs: move this to switch point track
2324 {
2326 }
2327 
2328 
2330 {
2331  ITERATE(TSeqMarkers, iter, m_SeqMarkers) {
2332  if (iter->second->IsRemoved()) continue;
2333 
2334  if (iter->second->m_Handler.HitMe()) {
2335  return iter->first;
2336  }
2337  }
2338  return kEmptyStr;
2339 }
2340 
2341 
2343 {
2344  CConstRef<CMarker> marker;
2346  if (iter != m_SeqMarkers.end() && !iter->second->IsRemoved()) {
2347  marker.Reset(iter->second.GetPointer());
2348  }
2349  return marker;
2350 }
2351 
2352 
2354 {
2355  return ! m_SelHandler.GetSelection().empty();
2356 }
2357 
2358 
2360 {
2362  if (sel_glyph) {
2363  x_GetParent()->ZoomOnRange(sel_glyph->GetRange(),
2365  }
2366 }
2367 
2368 
2370 {
2372  const IObjectBasedGlyph* obj =
2373  dynamic_cast<const IObjectBasedGlyph*>(sel_glyph.GetPointer());
2374 
2375  if ( !obj ) {
2376  return;
2377  }
2378 
2379  const IObjectBasedGlyph::TIntervals& intervals = obj->GetIntervals();
2380  if (intervals.size() == 0)
2381  return;
2382 
2383  // Get the default marker
2384  CSeqMarkHandler& seq_marker = x_GetDefaultMarker();
2385  TSeqPos marker_pos = seq_marker.GetPos();
2386 
2387  // (for a minus strand object, next is to the left, not to the right)
2388  bool neg_strand = sequence::GetStrand(obj->GetLocation()) == eNa_strand_minus;
2389  bool reverse = neg_strand ^ m_Flipped;
2390  bool is_next = dir == eDir_Next ||
2391  (dir == eDir_Left && reverse) || (dir == eDir_Right && !reverse);
2392 
2393  // first, find the nearest interval end following the direction.
2394  TSeqPos pre = INT_MAX;
2395  TSeqPos next = 0;
2396  TSeqPos near_dist = INT_MAX;
2397  TSeqPos near_val = 0;
2398  ITERATE (IObjectBasedGlyph::TIntervals, iter, intervals) {
2399  TSeqPos f = iter->GetFrom();
2400  TSeqPos t = iter->GetTo();
2401  TSeqPos t_dist = marker_pos > t ? marker_pos - t : t - marker_pos;
2402  if (near_dist > t_dist) {
2403  near_val = t;
2404  near_dist = t_dist;
2405  }
2406  TSeqPos f_dist = marker_pos > f ? marker_pos - f : f - marker_pos;
2407  if (near_dist > f_dist) {
2408  near_val = f;
2409  near_dist = f_dist;
2410  }
2411 
2412  if (marker_pos >= f && marker_pos <= t) {
2413  pre = f;
2414  next = t;
2415  break;
2416  }
2417 
2418  if (marker_pos < f) {
2419  next = f;
2420  if (!neg_strand) break;
2421  }
2422 
2423  if (marker_pos > t) {
2424  pre = t;
2425  if (neg_strand) break;
2426  }
2427  }
2428  if (pre == INT_MAX) pre = near_val;
2429  if (next == 0) next = near_val;
2430 
2431  // now do the next/prev thing
2432  if (marker_pos == near_val) { // already at the interval end
2433  ITERATE (IObjectBasedGlyph::TIntervals, iter, intervals) {
2434  TSeqPos f = iter->GetFrom();
2435  TSeqPos t = iter->GetTo();
2436  bool have_next = (iter + 1) != intervals.end();
2437  bool have_prev = iter != intervals.begin();
2438 
2439  if (is_next) { // Next exon
2440  if (marker_pos == f && f == t && have_next) {
2441  marker_pos = (iter + 1)->GetFrom();
2442  break;
2443  } else if (marker_pos == f) {
2444  if (!neg_strand) {
2445  marker_pos = t;
2446  } else if (have_next) {
2447  marker_pos = (iter + 1)->GetTo();
2448  }
2449  break;
2450  } else if (marker_pos == t) {
2451  if (neg_strand) {
2452  marker_pos = f;
2453  } else if (have_next) {
2454  marker_pos = (iter + 1)->GetFrom();
2455  }
2456  break;
2457  }
2458  } else {// Prev. exon
2459  if (marker_pos == t && f == t && have_prev) {
2460  marker_pos = (iter - 1)->GetTo();
2461  } else if (marker_pos == t) {
2462  if (!neg_strand) {
2463  marker_pos = f;
2464  } else if (have_prev) {
2465  marker_pos = (iter - 1)->GetFrom();
2466  }
2467  break;
2468  } else if (marker_pos == f) {
2469  if (neg_strand) {
2470  marker_pos = t;
2471  } else if (have_prev) {
2472  marker_pos = (iter - 1)->GetTo();
2473  }
2474  break;
2475  }
2476  }
2477  } // ITERATE
2478  } else { // go to interval end
2479  if (is_next) {
2480  if (neg_strand) marker_pos = pre;
2481  else marker_pos = next;
2482  } else {
2483  if (neg_strand) marker_pos = next;
2484  else marker_pos = pre;
2485  }
2486  }
2487 
2488  // Move the visible center only when the current marker is outside the visible range
2490  if (vis_r.GetFrom() > marker_pos || vis_r.GetTo() < marker_pos) {
2491  TSeqPos center_x = (TSeqPos)((vis_r.GetTo() + vis_r.GetFrom()) * 0.5f);
2492  TSeqRange range(vis_r.GetFrom() + (marker_pos - center_x),
2493  vis_r.GetTo() + (marker_pos - center_x));
2495  }
2496 
2497  seq_marker.SetPos((TModelUnit)marker_pos);
2498 
2501  Refresh();
2502 }
2503 
2504 
2506 {
2507  int x = pos.x;
2508  int y = MZHH_GetVPPosByY(pos.y);
2509 
2510  int area = x_GetAreaByVPPos(x, y);
2511 
2512  // do we have context menu specific to feaature or alignment?
2513  /*
2514  if (area == fArea_Object) {
2515  CConstRef<CSeqGlyph> glyph = x_GetOnlyOneSelectedGlyph();
2516  if (glyph) {
2517  if (dynamic_cast<const CAlignGlyph*>(glyph.GetPointer())) {
2518  area = fArea_Alignment;
2519  } else if (dynamic_cast<const CFeatGlyph*>(glyph.GetPointer())) {
2520  area = fArea_Feature;
2521  }
2522  }
2523  }
2524  */
2525 
2526  return area;
2527 }
2528 
2529 
2531 {
2533  const CSwitchPointGlyph* sp =
2534  dynamic_cast<const CSwitchPointGlyph*>(sel_glyph.GetPointer());
2535  if ( !sp || !x_HasDefaultMarker()) return false;
2536 
2537  TSeqPos marker_pos = x_GetDefaultMarker().GetPos();
2538  TSeqRange range = sp->GetLocation().GetTotalRange();
2539  return ( marker_pos >= range.GetFrom() && marker_pos <= range.GetTo() );
2540 }
2541 
2542 
2543 static string s_EscapeCommaAndPipe(const string& str)
2544 {
2545  string out = kEmptyStr;
2546  const size_t str_l = str.size();
2547  out.reserve(str_l + 2);
2548  for (size_t i = 0; i < str_l; ++i) {
2549  const char& curr_char = str[i];
2550  if (curr_char == ',' || curr_char == '|') {
2551  out += "\\";
2552  }
2553  out.append(1, curr_char);
2554  }
2555  return out;
2556 }
2557 
2558 
2560 {
2561  string str;
2562  bool first = true;
2563  ITERATE(TSeqMarkers, iter, m_SeqMarkers) {
2564  if (iter->second->IsRemoved()) continue;
2565  if ( !first ) {
2566  str += ",";
2567  } else {
2568  first = false;
2569  }
2570  const CSeqMarkHandler& marker = iter->second->m_Handler;
2571  str += NStr::NumericToString(marker.GetPos());
2572  if (marker.GetMarkerType() == CSeqMarkHandler::eRange) {
2573  str += ":" + NStr::NumericToString(marker.GetExtendedPos());
2574  }
2575  str += "|";
2576  str += s_EscapeCommaAndPipe(marker.GetLabel() == "" ? " " : marker.GetLabel()) + "|";
2577  str += marker.GetColor().ToString(false);
2578  }
2579  return str;
2580 }
2581 
2582 
2583 void CSeqGraphicPane::SetMarkers(const string& markers)
2584 {
2585  typedef vector<string> TTokens;
2586  TTokens m_tokens;
2587  CTrackUtils::TokenizeWithEscape(markers, ",", m_tokens, true);
2588  ITERATE(TTokens, m_iter, m_tokens) {
2589  TTokens e_tokens;
2590  CTrackUtils::TokenizeWithEscape(*m_iter, "|", e_tokens, true);
2591  size_t e_size = e_tokens.size();
2592  if (e_size == 3) {
2593  try {
2594  CRgbaColor color(e_tokens[2]);
2595 
2596  // Could be a point marker (single number) or range (#:#)
2597  vector<string> arr;
2598  NStr::Split(e_tokens[0], ":", arr);
2599  if (arr.size() == 1) {
2600  TSeqPos pos = NStr::StringToNumeric<TSeqPos>(arr[0]);
2601  AddPointMarker(NStr::TruncateSpaces(e_tokens[1]), pos, color);
2602  }
2603  else if (arr.size() == 2) {
2604  TSeqRange range(NStr::StringToNumeric<TSeqPos>(arr[0]),
2605  NStr::StringToNumeric<TSeqPos>(arr[1]));
2607  }
2608  } catch (CException&) {
2609  // invalid marker position, ignore it
2610  }
2611  }
2612  }
2615 }
2616 
2617 
2619 {
2621  while (iter != m_SeqMarkers.end()) {
2622  if (iter->second->IsRemoved()) {
2623  x_UnregisterHandler(&iter->second->m_Handler);
2624  m_SeqMarkers.erase(iter++);
2625  }
2626  else {
2627  ++iter;
2628  }
2629  }
2630 }
2631 
2632 
2633 int CSeqGraphicPane::x_GetAreaByVPPos(int vp_x, int vp_y)
2634 {
2635  const TVPRect& rc_feat = m_Renderer->GetFeatGlPane().GetViewport();
2636  const TVPRect& rc_ruler = m_Renderer->GetRulerGlPane().GetViewport();
2637 
2638  // Deside where the mouse is:
2639  if (rc_ruler.PtInRect(vp_x, vp_y)) {
2640  return fArea_Ruler;
2641  } else if (rc_feat.PtInRect(vp_x, vp_y)) {
2642  return fArea_Object;
2643  }
2644 
2645  return fArea_Other;
2646 }
2647 
2648 
2650 {
2651  CConstRef<CSeqGlyph> glyph;
2652  const CSeqGlyph::TConstObjects& sel_glyphs =
2654 
2655  if (sel_glyphs.size() == 1) {
2656  glyph = sel_glyphs.front();
2657  }
2658 
2659  return glyph;
2660 }
2661 
2662 
2664 {
2666  if (iter == m_SeqMarkers.end()) {
2667  CRef<CMarker> marker(new CMarker);
2669  marker->m_Handler.SetHost(this);
2670  marker->m_Handler.SetId(kDefaultMarker);
2674  } else if (iter->second->IsRemoved()) {
2675  iter->second->SetPos(0);
2676  iter->second->SetRemoved(false);
2677  x_RegisterHandler(&iter->second->m_Handler, fArea_Ruler,
2679  }
2680  return iter->second->m_Handler;
2681 }
2682 
2684  const string& label,
2685  const CRgbaColor& color)
2686 {
2687  //x_PurgeMarkers();
2688  marker->m_Handler.SetHost(this);
2689  marker->SetColor(color);
2690  marker->SetLabel(label);
2691  marker->SetFlipped(m_Flipped);
2692  string marker_id;
2694  marker_id = kDefaultMarker;
2695  } else {
2697  m_MarkerId++;
2698  }
2699  marker->m_Handler.SetId(marker_id);
2700  m_SeqMarkers.insert(TSeqMarkers::value_type(marker_id, marker));
2703 }
2704 
2705 void CSeqGraphicPane::x_RemoveMarker(const string& id)
2706 {
2708  if (iter != m_SeqMarkers.end()) {
2709  // maker is marked as removed, but not ready to be removed
2710  // from the m_SeqMarkers list yet
2711  iter->second->SetRemoved(true);
2713  }
2714 }
2715 
2716 
2718 {
2720  return iter != m_SeqMarkers.end() && !iter->second->IsRemoved();
2721 }
2722 
2723 
2725 {
2727  x_UnregisterHandler(&iter->second->m_Handler);
2728  }
2729  m_SeqMarkers.clear();
2730 }
2731 
2732 void CSeqGraphicPane::OnContextMenu(wxContextMenuEvent& event)
2733 {
2735 
2736  while (true) {
2737  if (!m_DS)
2738  break;
2739  wxPoint pos = ScreenToClient(event.GetPosition());
2740  pos.y = MZHH_GetVPPosByY(pos.y);
2741  int area = x_GetAreaByVPPos(pos.x, pos.y);
2742  if (area != fArea_Object)
2743  break;
2744  CRef<CSeqGlyph> obj = m_Renderer->HitTest(pos.x, pos.y);
2745  if (!obj)
2746  break;
2747  if (!obj->OnContextMenu(event))
2748  break;
2749  return;
2750  }
2751  event.Skip();
2752  return;
2753 
2754 }
2755 
2756 void CSeqGraphicPane::OnKillFocus(wxFocusEvent& event)
2757 {
2758  CFeaturePanel* featurePanel = GetFeaturePanel();
2759  if (featurePanel)
2760  featurePanel->SaveTrackConfig();
2761 }
2762 
std::invoke_result< _Fty, ICanceled & >::type GUI_AsyncExec(_Fty &&_Fnarg, const wxString &msg=wxT("Accessing network..."))
Definition: async_call.hpp:130
static CAttribMenu & GetInstance()
Return a static instance of CAttribMenu.
Definition: attrib_menu.cpp:50
class CAttribMenuItem
CAttribStringsMenuItem * AddStrings(const std::string &name, std::string *user_value=NULL)
void DrawMenu()
void SetOpenCloseKeys(int open_key, int close_key)
Opening and closing menu will always work with numpad +/-.
CAttribMenu * AddSubMenuUnique(const std::string &name, void *user_value=NULL)
Convienance function to add a submenu to this menu.
CAttribFloatMenuItem * AddFloatReadOnly(const std::string &name, float *user_value)
Add entries to the menu which display the users value but do not update it.
bool RemoveMenuR(const std::string &name, void *user_value=NULL)
Search the menu(s) recursively for menu 'name' with the specified user data 'user_value'.
class CAttribStringsMenuItem
void Add(CObject &obj)
const string & GetParentTrackName() const
bool HasMatches(const CObject &object, objects::CScope &scope) const
CEventHandler.
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
CConfigurableItems - a static list of items that can be configured.
void SaveTrackConfig()
CMappedFeatOrObject FindText(const string &text, bool match_case)
void ShowConfigureTracksDlg(const string &category)
virtual void ResetSearch()
CGlAttrGuard - guard class for restoring OpenGL attributes.
Definition: glutils.hpp:130
class CGlPane
Definition: glpane.hpp:62
CGlRenderDebug.
Definition: glrender.hpp:324
virtual void Scroll(TModelUnit d_x, TModelUnit d_y)
virtual void NotifyVisibleRangeChanged()
virtual void ZoomRect(const TModelRect &rc)
virtual void ZoomPoint(const TModelPoint &point, TModelUnit factor, CGlPane::EZoomOptions=CGlPane::fZoomXY)
CGlWidgetPane represent a window component residing in CGlWidgetBase client area.
virtual void GHH_ReleaseMouse()
releases captured mouse
void SetPopupMenuDisplayed(bool b)
bool x_UnregisterHandler(IGlEventHandler *handler)
bool x_RegisterHandler(IGlEventHandler *handler, int area, CGlPane *pane, int index=-1)
void CheckOverlayTimer()
virtual void GHH_CaptureMouse()
captures mouse events in the hosting window for D&D
virtual void GHH_SetCursor(const wxCursor &cursor)
changes the cursor in the hosting window
TSelectedGlyphs m_Glyphs
const CCachedTipHandle & m_TipHandle
CGlyphSearchVisitor(const CCachedTipHandle &handle, CScope &scope)
TSelectedGlyphs Search(CSeqGlyph *glyph)
CRef< CScope > m_Scope
virtual bool Visit(CSeqGlyph *glyph)
list< CWeakRef< CSeqGlyph > > TSelectedGlyphs
void Render(CGlPane &pane)
void SetHost(ITrackHandlerHost *host)
CLayoutTrackHandler inline methods.
virtual void SetPane(CGlPane *pane)
File Description:
virtual string GetFullTitle() const
get a more meaningful title.
void Render(CGlPane &Pane, ERenderingOption option=eActiveState)
void SetSelection(const TRangeColl &C, bool bRedraw)
void ResetSelection(bool bRedraw)
const TRangeColl & GetSelection() const
void SetHost(ISelHandlerHost *host)
void SetOrientation(EOrientation orient)
Help class to manage markers.
void SetColor(const CRgbaColor &color)
void SetMarkerType(CSeqMarkHandler::EMarkerType t)
void SetFlipped(bool f)
void SetExtendedPos(TModelUnit pos)
void SetRange(TSeqRange range)
CSeqMarkHandler m_Handler
void SetPos(TModelUnit pos)
void SetLabel(const string &label)
virtual void SetHost(IMouseZoomHandlerHost *pHost)
virtual void SetMode(EMode mode)
virtual void Render(CGlPane &Pane)
static void ParseSignature(const string &sig, objects::CSeq_id_Handle &sih, TSeqPos &from, TSeqPos &to, EObjectType &type, int &subtype, Uint4 &fingerprint, Uint4 &ds_fingerprint, string &ds_name, objects::CScope *scope)
parse signature with data source info.
bool operator()(const CObject *arg) const
CObject –.
Definition: ncbiobj.hpp:180
bool empty() const
Definition: range_coll.hpp:102
CRenderingContext offers the basic context and utility methods for rendering layout objects in featur...
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
objects::CScope & GetScope(void) const
Get the scope from the handle.
TSeqPos GetSequenceLength() const
string GetTitle() const
string GetAcc_Best() const
this is more suitable for display purposes since the returned string will not always be good to recon...
CScope –.
Definition: scope.hpp:92
static const CFeatList * GetFeatList()
class CSeqGlyph defines an interface that wraps a rectilinear abstract object.
Definition: seq_glyph.hpp:82
virtual bool IsClickable() const
Query if this glyph is clickable.
Definition: seq_glyph.hpp:195
virtual void GetTooltip(const TModelPoint &, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
Definition: seq_glyph.cpp:136
virtual bool OnLeftDblClick(const TModelPoint &)
Definition: seq_glyph.cpp:76
virtual TSeqRange GetRange(void) const
get the total range of this object.
Definition: seq_glyph.hpp:513
virtual bool OnLeftDown(const TModelPoint &)
Definition: seq_glyph.cpp:64
virtual bool Accept(IGlyphVisitor *visitor)
Interface for accepting an IGlyphVisitor.
Definition: seq_glyph.hpp:519
const CSeqGlyph * GetParent(void) const
Definition: seq_glyph.hpp:622
list< CRef< CSeqGlyph > > TObjects
Definition: seq_glyph.hpp:85
virtual bool OnContextMenu(wxContextMenuEvent &event)
Definition: seq_glyph.cpp:81
list< CConstRef< CSeqGlyph > > TConstObjects
Definition: seq_glyph.hpp:86
bool IsAjdustRulerToSelection() const
CRef< CGlTextureFont > GetTitleFont() const
void LoadSettings()
update the cached settings.
void SaveSettings(bool clear_themes=false)
class CSeqGraphicPane
CConstRef< CSeqGlyph > x_GetOnlyOneSelectedGlyph()
virtual void SMHH_SetSeqMark(TSeqPos mark) override
The derived class may choose do something differently when marker position is changed.
void OnTipRemoved(const string &tip_id)
string GetMarkers() const
get/set markers stored as a string.
void OnTipAdded(const string &tip_id)
void x_RemoveMarker(const string &id)
virtual TModelUnit SMHH_GetModelByWindow(int z, EOrientation orient) override
CSeqMarkHandler & x_GetDefaultMarker()
CConstRef< CSeqGlyph > GetSelectedLayoutObj()
void OnMiddleDown(wxMouseEvent &event)
void NextPrevSplice(EDirection dir)
CRef< CSeqGraphicConfig > m_ConfigSettings
TSeqMarkers m_SeqMarkers
CSeqGraphicWidget * x_GetParent()
virtual void LTH_OnLayoutChanged() override
provides mouse coords in OpenGL viewport coord system
virtual void MZHH_SetScale(TModelUnit scale, const TModelPoint &point) override
@ eMouse_Idle
no button down
@ eMouse_RectSelect
with SHIFT key down
@ eMouse_IncRectSelect
with SHIFT and CTRL key down
@ eMouse_IncSelect
with CTRL key down
@ eMouse_Pan
left click and drag
@ eMouse_Down
left button down, not sure what to do yet
const TRangeColl & GetRangeSelection(void) const
virtual void UpdateVectorLayout() override
CConstRef< CMarker > GetMarker(const string &id)
TModelUnit GetHeight()
class CSeqGraphicPane
virtual ~CSeqGraphicPane()
virtual TModelPoint THH_GetModelByWindow(const wxPoint &pt) override
void SetRangeSelection(const TRangeColl &ranges)
void x_NotifyWidgetRangeChanged()
CTooltipInfo m_TooltipInfo
bool CanGoBack(void) const
virtual void MZHH_ZoomRect(const TModelRect &rc) override
virtual void PostDialogShow() override
Post-processing after showing a dialog.
CSeqGraphicPane(CSeqGraphicWidget *parent)
void SelectOnlyThisObject(const CSeqGlyph *glyph, int mouse_x, int mouse_y)
virtual const TVPRect & GetViewportRect() const override
virtual TVPUnit MZHH_GetVPPosByY(int y) const override
converts window coord to Viewport coord
void OnMouseCaptureLost(wxMouseCaptureLostEvent &)
void RemoveMarker(const string &marker_id)
void InitDataSource(SConstScopedObject &obj)
void SetViewportWidth(TSeqPos from, TSeqPos to, TVPUnit vp_width)
void SelectSeqLoc(const objects::CSeq_loc *loc)
TSeqRange FindText(const string &text, bool match_case)
bool CanGoForward(void) const
bool AllJobsFinished() const
virtual void SMHH_OnReset(const string &id) override
The derived class may need to do something differently when a marker gets reset, such as remove the m...
void AddPointMarker(const string &name, TSeqPos pos, const CRgbaColor color)
void GetFeatureNames(vector< string > &names)
void AdjustViewPort()
Potential actions include loading data and generating layouts.
void GetObjectSelection(TConstObjects &objs) const
retrieve the selections from our renderer.
CRef< CSeqGraphicConfig > GetConfig()
virtual void LTH_ZoomOnRange(const TSeqRange &range) override
notifies the host we need to zoom on to a range.
string GetHitMarker() const
CWeakRef< CSeqGlyph > x_GetGlyphByTipId(const string &tip_id)
void SetSeqStart(TSeqPos pos)
void SetInputObject(SConstScopedObject &obj)
void SetSeqStartMarker(const string &id)
bool IsHorizontal() const
void SetSeqStartPoint(TModelPoint point)
virtual void LTH_PopupMenu(wxMenu *menu) override
show track-specific context menu.
void x_RenderRectSelHandler(CGlPane &pane)
Rectangular selection.
virtual void PreDialogShow() override
Prepare for showing a dialog.
bool m_VectorPane
If true pane is only for creating vector graphics - ignore other draw events.
CWeakRef< CSeqGlyph > m_LastHitGlyph
last hit glyph.
virtual void x_Render() override
Draw the GL window.
CRef< CSGSequenceDS > m_DS
void OnMouseWheel(wxMouseEvent &event)
EMouseMode m_MouseMode
int m_MarkerHandlerIndex
Marker handler index among all registered handlers.
void SetHorizontal(bool b_horz, bool b_flip)
virtual void ResetSearch() override
TRangeVec m_BackForwardHistory
void OnLeftDblClick(wxMouseEvent &event)
void UpdateConfig()
the config object just changed. Do what is necessary.
bool AllTracksCreated() const
virtual TModelUnit MZHH_GetScale(EScaleType type) override
CMouseZoomHandler m_MouseZoomHandler
virtual void Update(void) override
void GetCurrentObject(int mouse_x, int mouse_y, TConstObjects &objs)
void SelectObject(const CObject *obj, bool verified)
virtual void MZHH_ZoomPoint(const TModelPoint &point, TModelUnit factor) override
CRef< CSeqGraphicRenderer > m_Renderer
virtual void LTH_PushEventHandler(wxEvtHandler *handler) override
CStickyTooltipHandler m_TooltipManager
void AdjustViewPortHeightToImage()
bool m_Title
When rendering vector image, add a title.
virtual CTooltipInfo TTHH_GetTooltip(const wxRect &rect) override
Return the contents to be displayed in the tool tip.
void x_OnPurgeMarkers(CEvent *)
CFeaturePanel * GetFeaturePanel()
TPinnedTips m_PinnedTips
void SetExternalGlyphs(const CSeqGlyph::TObjects &objs)
CSGSequenceDS * GetDataSource(void)
virtual int x_GetAreaByVPPos(int vp_x, int vp_y) override
virtual void LTH_ConfigureTracksDlg(const string &category) override
void OnKeyUp(wxKeyEvent &event)
void SaveCurrentRange()
For Back or Forward operations.
void OnLeftUp(wxMouseEvent &event)
bool x_HasDefaultMarker() const
void ModifyMarker(const string &id, const string &label, TSeqPos pos, const CRgbaColor color)
virtual void MZHH_EndOp() override
size_t GetMarkerNum() const
virtual void MZHH_Scroll(TModelUnit d_x, TModelUnit d_y) override
virtual TModelUnit SHH_GetModelByWindow(int z, EOrientation orient) override
virtual TVPPoint GetPortSize(void) override
Get GL view port size.
virtual TSeqPos SMHH_GetSeqMark() const override
If the host needs to dictate/store the marker position, then it needs to return a non (TSeqPos)-1 val...
virtual void SHH_OnChanged() override
ISelHandlerHost implementation.
size_t m_BackForwardPos
position in m_BackForwardHistory
CIRef< ISGDataSourceContext > m_DSContext
bool x_ModifyMarker(CRef< CMarker > &marker, const string &id, const string &label, const CRgbaColor color)
CLinearSelHandler::TRangeColl TRangeColl
virtual CRef< CLayoutTrack > THH_GetLayoutTrack() override
Get the layout track under the current mouse position.
virtual bool TTHH_ProcessURL(const wxString &href) override
Return true if the specified URL has been processed. Used for custom commands.
void DeSelectObject(const CObject *obj)
void SelectLastHitObject(int mouse_x, int mouse_y)
virtual string TTHH_NeedTooltip(const wxPoint &pt) override
Return id of the underlying element to dispaly a tooltip, otherwise "".
CLayoutTrackHandler m_TrackHandler
void OnSearchTip(const string &tip_id, const wxRect &tip_rect)
void OnLeftDown(wxMouseEvent &event)
int GetPopupArea(wxPoint pos)
void OnZoomTip(const string &tip_id, const wxRect &)
void OnKeyDown(wxKeyEvent &event)
virtual void RenderVectorGraphics(int vp_width, int vp_height) override
Render for vector output.
void SetMarkers(const string &markers)
virtual void LTH_PopEventHandler() override
string x_GetCachedTipId(const CSeqGlyph *glyph) const
bool CanZoomSelection(void)
void SetSeqMarker(TModelPoint point)
CLinearSelHandler m_SelHandler
void OnKillFocus(wxFocusEvent &event)
void SetNonAsnInput(const INonAsnTrackData &data)
void OnInfoTip(const string &)
void RenameMarker(const string &id, const string &label)
void x_AddNewMarker(CRef< CMarker > marker, const string &label, const CRgbaColor &color)
void OnMotion(wxMouseEvent &event)
void AddRangeMarker(const string &name, TSeqRange range, const CRgbaColor color)
void OnContextMenu(wxContextMenuEvent &event)
virtual TVPUnit SHH_GetWindowByModel(TModelUnit z, EOrientation orient) override
void UpdateData(TSeqPos from, TSeqPos to)
bool IsObjectSelected(const CObject *obj)
CRef< CSeqGlyph > HitTest(int x, int y)
void SetVertScroll(TModelUnit val)
bool HasSelectedObjects() const
void DeSelectObject(const CObject *obj)
void GetObjectSelection(ncbi::TConstObjects &objs) const
CFeaturePanel * GetFeaturePanel()
void SelectObjByRect(const TVPRect &rc)
void SetNonAsnInput(const INonAsnTrackData &data)
void SetExternalGlyphs(const CSeqGlyph::TObjects &objs)
void SetDSContext(ISGDataSourceContext *ds_ctx)
CSeqGraphicRenderer inline methods.
void SetHost(ILayoutTrackHost *host)
void UpdateConfig(CRef< CSeqGraphicConfig > config)
void SetHorizontal(bool b_horz, bool b_flip, const TVPRect &rc, bool reset_model_limit=false)
void SetInputObject(SConstScopedObject &obj)
const CSeqGlyph::TConstObjects & GetSelectedLayoutObjects()
TSeqPos Screen2Seq(TVPUnit x, TVPUnit y)
pixels to sequence translation.
TSeqPos Screen2SeqWidth(TVPUnit vp)
CGlPane & GetFeatGlPane()
Expose a few GlPanes.
void SelectObject(const CObject *obj, bool verified)
TModelUnit GetLayoutHeight() const
retrieve the expected height of this widget.
void SetRulerSeqStart(TSeqPos pos)
Ruler Mark.
TSeqRange GetVisibleRange() const
void ZoomOnRange(const TModelRange &range, bool round_to_base=false)
zoom to the given range.
void UpdateHeight(TModelUnit height)
TSeqRange GetVisibleSeqRange() const
TModelRange GetVisibleRange(void) const
returns the visible sequence range
void SetDirty(bool flag)
virtual CGlPane & GetPort() override
implement these 2 functions in derived classes
void SetScaleX(TModelUnit scale, const TModelPoint &point)
void ZoomOnRange(TSeqRange range, TZoomFlag flag)
Class CSeqMarkHandler represents in GUI a single "hairpin" on a sequence bar.
const CRgbaColor & GetColor() const
const string & GetLabel() const
void SetId(const string &id)
TSeqPos GetExtendedPos() const
EMarkerType GetMarkerType() const
void SetLabel(const string &label)
TSeqPos GetPos() const
void SetPos(TModelUnit pos)
void SetHost(ISeqMarkHandlerHost *pHost)
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
virtual void SetHost(IStickyTooltipHandlerHost *host)
CStopWatch –.
Definition: ncbitime.hpp:1938
Contents of a single tool tip including display text and an ID that will indicate which underlying vi...
void SetToolTipOptions(int opt)
Set/get options that determine which buttons are displayed.
void SetTitleText(const std::string &title_text)
Set/get display text.
std::string GetTipText() const
std::string GetTipID() const
void SetTipText(const std::string &tip_text)
Set/get display text.
void SetTipID(std::string id)
Set/get id that identifies the underlying element.
bool ProcessURL(const string &href)
@ eWidgetSelectionChanged
a view has been destroyed
Definition: view_event.hpp:55
@ eWidgetDataChanged
notification from child to parent that the underlying data has changed
Definition: view_event.hpp:61
@ eWidgetRangeChanged
notification from child to parent that the visible range has changed
Definition: view_event.hpp:58
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:51
Visitor interface for applying any potential actions or algorithms.
Definition: seq_glyph.hpp:384
File Description:
virtual const TIntervals & GetIntervals(void) const =0
access sub-intervals (if any).
virtual CConstRef< CObject > GetObject(TSeqPos pos) const =0
access our core component - we wrap an object(s) of some sort.
virtual const objects::CSeq_loc & GetLocation(void) const =0
access the position of this object.
virtual string GetSignature() const =0
return signature for this glyph.
vector< TSeqRange > TIntervals
std::vector< TipLocation > GetDisplayedTips()
Return id and position information for currently displayed tips.
void erase(iterator pos)
Definition: map.hpp:167
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
#define T(s)
Definition: common.h:230
std::ofstream out("events_result.xml")
main entry point for tests
CS_CONTEXT * ctx
Definition: t0006.c:12
static const struct name_t names[]
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
static const char * str(char *buf, int n)
Definition: stats.c:84
static const char *const strings[]
Definition: utf8.c:21
char data[12]
Definition: iconv.c:80
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_CATCH(message)
Catch CExceptions as well This macro is deprecated - use *_X or *_XX variant instead of it.
Definition: ncbiexpt.hpp:580
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
CRef< objects::CSeqMapSwitchPoint > GetSwitchPoints() const
const objects::CSeq_loc & GetLocation(void) const
Access the alignments's remapped location.
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetRight(T right)
Definition: glrect.hpp:114
static CGlResMgr & Instance()
Definition: glresmgr.cpp:59
T X() const
Definition: glpoint.hpp:59
virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)=0
T Height() const
Definition: glrect.hpp:90
virtual void Translatef(GLfloat x, GLfloat y, GLfloat z)=0
virtual void Enable(GLenum glstate)=0
virtual void LineStipple(GLint factor, GLushort pattern)=0
Set line stipple pattern: glLineStipple(). Deprecated in gl 3.2+.
CIRef< IRender > GetRenderer(ERenderTarget target)
Returns first renderer in m_Renderers that renders to 'target'.
Definition: glresmgr.cpp:269
virtual void Begin(GLenum mode)=0
Start rendering.
CGlPoint< TVPUnit > TVPPoint
Definition: gltypes.hpp:50
void SetBottom(T bottom)
Definition: glrect.hpp:113
T Top() const
Definition: glrect.hpp:84
virtual void BlendFunc(GLenum sfactor, GLenum dfactor)=0
Options to be used when GL_BLEND is enabled.
void Color3f(GLfloat r, GLfloat g, GLfloat b)
Definition: irender.hpp:95
T Bottom() const
Definition: glrect.hpp:82
TModelPoint UnProject(TVPUnit m_x, TVPUnit m_y) const
Definition: glpane.cpp:738
T Width() const
Definition: glrect.hpp:86
virtual void MatrixMode(GLenum mode)=0
TVPUnit ProjectX(TModelUnit m_x) const
Definition: glpane.cpp:661
bool IsEmpty() const
Definition: glrect.hpp:150
IRender & GetGl()
convenience function for getting current render manager
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
T Right() const
Definition: glrect.hpp:83
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
virtual void BeginText(const CGlTextureFont *font, const CRgbaColor &color)=0
Text is drawn is pixel coordinates.
TModelUnit GetOffsetY() const
Definition: glpane.hpp:415
virtual TModelUnit GetFontDescender() const
virtual void LoadIdentity()=0
TVPUnit ProjectY(TModelUnit m_y) const
Definition: glpane.cpp:676
virtual void EndText()=0
Pops matrices and attributes after writing text.
TModelUnit UnProjectX(TVPUnit m_x) const
Definition: glpane.cpp:706
virtual void PopMatrix()=0
CGlPoint< T > CenterPoint() const
Definition: glrect.hpp:94
virtual void ShadeModel(GLenum mode)=0
Set shade model for default lighting: glShadeModel(GL_FLAT or GL_SMOOTH)
void AddRenderer(CIRef< IRender > rm)
Get/Set Renderer.
Definition: glresmgr.cpp:243
T Left() const
Definition: glrect.hpp:81
T Y() const
Definition: glpoint.hpp:60
bool PtInRect(T x, T y) const
Definition: glrect.hpp:154
virtual void End()=0
Finish rendering (create buffer and send to renderer)
#define CHECK_GLERROR()
Same as CGlUtils::CheckGlError except the log message will include the name of the function logging t...
Definition: glutils.hpp:102
TModelUnit UnProjectY(TVPUnit m_y) const
Definition: glpane.cpp:722
int TVPUnit
Definition: gltypes.hpp:47
CRange< TModelUnit > TModelRange
Definition: gltypes.hpp:56
TModelUnit GetZoomAllScaleX(void) const
Definition: glpane.cpp:133
void SetCurrentRenderer(CIRef< IRender > rm)
Set current renderer (rm must already be in m_Renderers)
Definition: glresmgr.cpp:281
void Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
Definition: irender.hpp:97
virtual void WriteText(TModelUnit x, TModelUnit y, const char *text, TModelUnit rotate_degrees=0.0)=0
Write text at specified model coords.
void SetLeft(T left)
Definition: glrect.hpp:112
virtual TModelUnit TextHeight(void) const
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
void Vertex3d(GLdouble x, GLdouble y, GLdouble z)
Definition: irender.hpp:187
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)=0
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
TModelUnit GetMinScaleX(void) const
Definition: glpane.hpp:452
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
CGlPoint< TModelUnit > TModelPoint
Definition: gltypes.hpp:51
virtual void Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)=0
Rect() functions also do Begin() and End() (as in OpenGL)
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
bool Intersects(const CGlRect &R) const
Definition: glrect.hpp:163
void SetTop(T top)
Definition: glrect.hpp:115
virtual void PushMatrix()=0
EOrientation
Definition: gltypes.hpp:58
@ eAlign_Left
Definition: glfont.hpp:102
@ ePixels
Definition: glpane.hpp:67
@ eOrtho
Definition: glpane.hpp:66
@ eRenderDebug
Definition: glstate.hpp:61
@ eHorz
Definition: gltypes.hpp:59
@ eVert
Definition: gltypes.hpp:60
string ToString(bool printAlpha=true, bool uchars=true) const
Return a string representation of the current color.
Definition: rgba_color.cpp:309
vector< CConstRef< CObject > > TConstObjects
Definition: objects.hpp:64
static CIRef< ITooltipFormatter > CreateTooltipFormatter(ETooltipFormatters)
factory for requested tooltip formatter creation
Definition: tooltip.cpp:40
void Post(CRef< CEvent > evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Handles an event asynchronously (process and/or dispatch).
#define ON_EVENT(type, id, handler)
static void TokenizeWithEscape(const string &str, const string &delim, vector< string > &tokens, bool remove_escape=false)
Tokenize a string using the delim.
Definition: track_info.cpp:352
#define END_EVENT_MAP()
Ends definition of Command Map.
#define BEGIN_EVENT_MAP(thisClass, baseClass)
Begins definition of Command Map for CEventHandler-derived class.
virtual void AddListener(CEventHandler *listener, int pool_name=ePool_Default)
Add a listener.
virtual bool Send(CEvent *evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Sends an event synchronously.
@ eTooltipFormatter_Html
generated table is HTML attributes (no CSS) based, generate NCBI URLs are absolute (recommended for G...
Definition: tooltip.hpp:60
@ eEvent_Message
message from one class to another
Definition: event.hpp:99
@ eDispatch_Default
dispatch until handled at least by one handler
TRange GetTotalRange(void) const
Definition: Seq_loc.hpp:913
ENa_strand GetStrand(const CSeq_loc &loc, CScope *scope=0)
Returns eNa_strand_unknown if multiple Bioseqs in loc Returns eNa_strand_other if multiple strands in...
bool Empty(void) const THROWS_NONE
Check if CConstRef is empty – not pointing to any object which means having a null value.
Definition: ncbiobj.hpp:1385
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
TRefType Lock(void) const
Lock the object and return reference to it.
Definition: ncbiobj.hpp:2713
void Reset(void)
Reset the containing pointer to null.
Definition: ncbiobj.hpp:2722
bool IsNull(void) const THROWS_NONE
Check if pointer is null – same effect as Empty().
Definition: ncbiobj.hpp:735
TObjectType * GetPointerOrNull(void) THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:986
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
position_type GetLength(void) const
Definition: range.hpp:158
bool IntersectingWith(const TThisType &r) const
Definition: range.hpp:331
TThisType IntersectionWith(const TThisType &r) const
Definition: range.hpp:312
bool Empty(void) const
Definition: range.hpp:148
CRange< TSeqPos > TSeqRange
typedefs for sequence ranges
Definition: range.hpp:419
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2891
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string.
Definition: ncbistr.cpp:3186
@ eReverseSearch
Search in a backward direction.
Definition: ncbistr.hpp:1947
@ eCase
Case sensitive compare.
Definition: ncbistr.hpp:1205
unsigned short GetPort() const
Get the listening port number back.
static const char label[]
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
void SetTo(TTo value)
Assign a value to To data member.
Definition: Range_.hpp:278
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
n background color
END_EVENT_TABLE()
int i
int len
static void text(MDB_val *v)
Definition: mdb_dump.c:62
static MDB_envinfo info
Definition: mdb_load.c:37
#define wxT(x)
Definition: muParser.cpp:41
TSeqRange SplitPosOrRange(const string &text)
range(_Ty, _Ty) -> range< _Ty >
#define fabs(v)
Definition: ncbi_dispd.c:46
EIPRangeType t
Definition: ncbi_localip.c:101
Defines: CTimeFormat - storage class for time format.
T max(T x_, T y_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static string s_EscapeCommaAndPipe(const string &str)
USING_SCOPE(objects)
static string s_GetRandomTipID()
ITooltip Implementation TC_NeedTooltip() and TC_GetTooltip() is evrything needed to show toolitps.
static string s_GetTrackName(const string &tip_id)
static const string kDefaultMarker
static const string kNamedMarker
static const string kCommonTipId
static const string kDefaultMarkerLabel
static static static wxID_ANY
Definition: type.c:6
#define _ASSERT
void SetFocus(CRef< objects::CSeq_entry > entry)
C++ wrappers for the Perl-compatible regular expression (PCRE) library.
wxRect GetScreenRect(const wxWindow &win)
Definition: wx_utils.cpp:783
list< STokenInfo > TTokens
Definition: xgbparint.cpp:88
Modified on Tue Apr 23 07:37:01 2024 by modify_doxy.py rev. 669887