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

Go to the SVN repository for this file.

1 /* $Id: gene_model_group.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: Liangshou Wu
27 *
28 */
29 
30 #include <ncbi_pch.hpp>
31 #include <gui/gui.hpp>
35 #include <gui/opengl/irender.hpp>
36 #include <gui/objutils/tooltip.hpp>
42 #include <objmgr/util/sequence.hpp>
43 #include <corelib/ncbi_limits.hpp>
44 
45 
48 
49 static const int kVertSpace = 2;
50 static const int kLabelSpace = 5;
51 
52 
53 // #define DEBUG_INFO_ON_SCREEN 1
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 /// CGeneGroup implementations
57 ///////////////////////////////////////////////////////////////////////////////
58 
59 void CGeneGroup::Update(bool layout_only)
60 {
61  if (m_ShowGene == eGene_Shown) {
62  CLayoutGroup::Update(layout_only);
63  } else {
64  TModelUnit min_l = DBL_MAX;
65  TModelUnit max_w = 0.0;
66  TObjectList::iterator iter = SetChildren().begin();
67  CFeatGlyph* gene = dynamic_cast<CFeatGlyph*>(iter->GetPointer());
68 
69  // skip the gene feature
70  ++iter;
71  while (iter != SetChildren().end()) {
72  (*iter)->Update(layout_only);
73  min_l = min(min_l, (*iter)->GetLeft());
74  max_w = max(max_w, (*iter)->GetWidth());
75  ++iter;
76  }
77 
78  // make sure the horizontal space reserved for gene feature
79  // won't exceed the group space
80  gene->SetLeft(min_l);
81  gene->SetWidth(max_w);
82  switch (m_ShowGene) {
83  case eGene_Shown:
84  gene->SetHeight(gene->GetConfig()->m_BarHeight);
85  break;
87  if (x_ShowGeneLabel())
88  gene->SetHeight(gene->GetConfig()->m_BarHeight);
89  else
90  gene->SetHeight(0.0);
91  break;
92  case eGene_Hidden:
93  gene->SetHeight(0.0);
94  break;
95  }
97  }
98 }
99 
100 
102 {
103  return GetLocation().GetTotalRange();
104 }
105 
106 
108 {
109  bool cont = visitor->Visit(this);
110  TObjectList::iterator iter = SetChildren().begin();
111  ++iter;
112 
113  while (cont && iter != SetChildren().end()) {
114  cont = (*iter)->Accept(visitor);
115  ++iter;
116  }
117  return cont;
118 
119 }
120 
122 {
123  if ((m_ShowGene == eGene_ShowLabelOnly) && (2 == GetChildren().size())) {
124  CConstRef<CSeqGlyph> child1 = GetChild(1);
125  const CLinkedFeatsGroup* linked_feats = dynamic_cast<const CLinkedFeatsGroup*>(child1.GetPointer());
126  const CLayoutGroup* group = dynamic_cast<const CLayoutGroup*>(child1.GetPointer());
127  if (!linked_feats && !group && !child1->IsSelected()) {
128  if (x_isDrawn()) {
129  try {
130  // Override the active areas to include the gene tooltip along with the merged feature tooltip
131  if (x_ShowGeneLabel())
132  GetChild(0)->GetHTMLActiveAreas(p_areas); // Gene's label
133  GetChild(0)->GetHTMLActiveAreas(p_areas); // Gene and
134  child1->GetHTMLActiveAreas(p_areas); // merged feature
135  // Correct the coordinates of the second gene's active area to match the cooridinates of the merged feature
136  TAreaVector::reverse_iterator it_gene = p_areas->rbegin();
137  ++it_gene;
138  it_gene->m_Bounds = p_areas->back().m_Bounds;
139  }
140  catch (CException& e) {
142  << "CGeneGroup::GetHTMLActiveAreas() failure on getting HTML active areas, error: "
143  << e.GetMsg());
144  }
145  return;
146  }
147  }
148  }
149 
151 }
152 
154 {
155  return x_GetFirstFeat()->GetObject(pos);
156 }
157 
158 
159 void CGeneGroup::GetObjects(vector<CConstRef<CObject> >& objs) const
160 {
161  x_GetFirstFeat()->GetObjects(objs);
162 }
163 
164 
166 {
167  const CFeatGlyph* gene = x_GetFirstFeat();
168  if (gene->HasObject(obj)) {
169  return true;
170  }
171 
172  return false;
173 }
174 
175 
176 const objects::CSeq_loc& CGeneGroup::GetLocation() const
177 {
178  // delegate gene feature
179  const CFeatGlyph* gene = x_GetFirstFeat();
180  return gene->GetLocation();
181 }
182 
183 
185 {
186  const CFeatGlyph* gene = x_GetFirstFeat();
187  return gene->GetSignature();
188 }
189 
190 
192 {
193  // delegate the gene feature
194  // use gene feature's intervals
195  const CFeatGlyph* gene = x_GetFirstFeat();
196  return gene->GetIntervals();
197 }
198 
199 
200 void CGeneGroup::SetShowGene(bool shown)
201 {
202  if ( !shown ) {
204 
205  HideMaster(false);
206  // if there is only one children other than gene itself, and
207  // the child is rna and cds group, and the child group has more
208  // than 2 children, we also hide the label.
209  if (GetChildrenNum() == 2) {
210  CRef<CSeqGlyph> child1 = GetChild(1);
211  const CLinkedFeatsGroup* group =
212  dynamic_cast<const CLinkedFeatsGroup*>(child1.GetPointer());
213  if (group && group->GetChildren().size() > 2) {
215  SetAsMaster(GetChild(0));
216  HideMaster();
217  }
218  } else if (GetChildrenNum() == 1) {
220  }
221  } else {
223  HideMaster(false);
224  }
225 }
226 
227 
228 void CGeneGroup::x_Draw() const
229 {
230  if ((GetLeft() >= 0) && m_Context->IntersectVisible(GetRange()).Empty())
231  return;
232 
233  IRender& gl = GetGl();
234 
235  gl.PushMatrix();
236  gl.Translated(0.0, GetTop(), 0.0f);
237  if (!m_Context->IsSkipFrames())
238  x_DrawBoundary();
239 #ifdef DEBUG_INFO_ON_SCREEN
240  {
241  CGlTextureFont font;
242  gl.ColorC(CRgbaColor());
243  font.SetFontFace(CGlTextureFont::FaceFromString("Helvetica"));
244  font.SetFontSize(10);
245  string sDebugInfo("CGeneGroup<" + NStr::NumericToString(GetLevel()) + ">/" + NStr::IntToString(x_isDrawn()) + "/[" + NStr::IntToString(GetChildrenNum()) + "]");
246  m_Context->TextOut(&font, sDebugInfo.c_str(), GetLeft() - 30 > 0 ? GetLeft() - 30 : 10, GetTop(), true, true);
247  }
248 #endif
249  TObjectList::const_iterator iter = GetChildren().begin();
250  bool gene_highlighted = false;
251  if (m_ShowGene != eGene_Shown) {
252  const CFeatGlyph* gene =
253  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
254 
255  if (gene) {
257  CConstRef<CFeatureParams> conf = gene->GetConfig();
258  string gene_label;
259  gene->GetLabel(gene_label, CLabel::eContent);
260 
261  // truncate the label if it exceeds the group width
263  const CGlTextureFont& font = conf->m_LabelFont;
264  if (gl.TextWidth(&font, gene_label.c_str()) > width) {
265  gene_label = font.Truncate(gene_label.c_str(), width);
266  }
267 
269  TModelUnit x = GetLeft() + GetWidth() * 0.5;
270  gl.ColorC(conf->m_LabelColor);
271  m_Context->TextOut(&font, gene_label.c_str(), x, y, true);
272  }
273 
274  // If the gene is a pseudo gene, draw background to indicate
275  // this is a pseudo gene group.
276  if (gene->GetFeature().IsSetPseudo() &&
277  gene->GetFeature().GetPseudo()) {
278 
279  CRgbaColor color = gene->GetConfig()->m_fgColor;
280  color.SetAlpha(0.1f);
281  CRgbaColor dcolor = color;
282  dcolor.Darken(0.7f);
283  CRgbaColor lcolor = color;
284  lcolor.Lighten(0.5f);
285 
287  TModelUnit left = visible_range.GetFrom();
288  TModelUnit right = visible_range.GetTo();
289 
290  m_Context->DrawPseudoBar(left, 0.0, right, GetHeight() - 1.0, lcolor, dcolor);
291  color.SetAlpha(0.18f);
292  gl.ColorC(color);
293  m_Context->DrawQuad(left, 0.0, right, GetHeight() - 1.0);
294  }
295 
296  gene_highlighted = gene->IsHighlighted();
297  }
298 
299  // skip the gene feature
300  ++iter;
301  }
302  while (iter != GetChildren().end()) {
303  (*iter)->Draw();
304  ++iter;
305  }
306  gl.PopMatrix();
307 
308  if (gene_highlighted) {
309  // If gene feature is not shown and its is highlighted,
310  // we need to highlight the whole group
312  }
313 }
314 
316 {
317  const CFeatGlyph* gene = dynamic_cast<const CFeatGlyph*>(GetChildren().begin()->GetPointer());
318 
319  CConstRef<CFeatureParams> conf = gene->GetConfig();
320  string gene_label;
321  gene->GetLabel(gene_label, CLabel::eContent);
322 
323  IRender& gl = GetGl();
324 
325  // truncate the label if it exceeds the group width
326  TModelUnit width = m_Context->SeqToScreen(gene->GetWidth());
327  const CGlTextureFont& font = conf->m_LabelFont;
328  if (gl.TextWidth(&font, gene_label.c_str()) > width) {
329  gene_label = font.Truncate(gene_label.c_str(), width);
330  if (gene_label == "...")
331  return false;
332  }
333  return true;
334 }
335 
337 {
338  const CFeatGlyph* gene = dynamic_cast<const CFeatGlyph*>(GetChildren().begin()->GetPointer());
339  _ASSERT(gene);
340  return GetGl().TextHeight(&(gene->GetConfig()->m_LabelFont)) + 2.0;
341 }
342 
344 {
345  const CFeatGlyph* feat = NULL;
347  feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
348  if (feat) break;
349  }
350  _ASSERT(feat);
351  return feat;
352 }
353 
354 
355 ///////////////////////////////////////////////////////////////////////////////
356 /// CLinkedFeatsGroup implementations
357 ///////////////////////////////////////////////////////////////////////////////
358 
360  : m_LabelType(fLabel_ParentLabel)
361  , m_FirstIsParent(false)
362 {
363  m_Group.SetParent(this);
364 
365  m_Location.Reset(new CSeq_loc());
366  m_Location->SetInt().SetFrom(0);
367  m_Location->SetInt().SetTo (INT_MAX);
368 }
369 
370 
371 void CLinkedFeatsGroup::Update(bool layout_only)
372 {
373  if (IsSelected() || IsHighlighted()) {
374  m_Group.Update(layout_only);
375  }
377 }
378 
379 
381 {
382  CRef<CSeqGlyph> glyph;
383  if (IsIn(p)) {
384  if ( !IsSelected()) {
385  glyph.Reset(this);
386  } else {
387  TModelPoint pp(p);
388  x_Parent2Local(pp);
389  glyph = m_Group.HitTest(pp);
390  if ( !glyph ) {
391  glyph.Reset(this);
392  }
393  }
394  }
395  return glyph;
396 }
397 
398 
400  TConstObjects& objs) const
401 {
402  if (rect.Intersects(GetModelRect())) {
403  objs.push_back(CConstRef<CSeqGlyph>(this));
404  return true;
405  }
406  return false;
407 }
408 
409 
410 bool CLinkedFeatsGroup::NeedTooltip(const TModelPoint& /*p*/, ITooltipFormatter& /*tt*/, string& /*t_title*/) const
411 {
412  return true;
413 }
414 
415 
416 void CLinkedFeatsGroup::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
417 {
418  int child_num = (int)GetChildren().size();
419  if (m_FirstIsParent) {
420  --child_num;
421  }
422  const CFeatGlyph* parent_feat = m_FirstIsParent ? x_GetFirstFeat() : m_ParentFeat;
423  if (nullptr == parent_feat) {
424  return;
425  }
426  string value;
427  if (child_num > 2) {
428  parent_feat->GetTooltip(p, tt, t_title);
429  value = NStr::LongToString(child_num);
430  tt.AddRow("Merged features:", value);
431  } else {
432  TSeqPos at_p = (TSeqPos)-1;
433  if (p.X() >= 0) {
434  at_p = (TSeqPos)p.X();
435  }
436  CCreateParamsSeqFeatGroup feat_group_params;
437  bool first_feat = true;
439  if (m_FirstIsParent && first_feat)
440  continue;
441 
442  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
443  const CMappedFeat& mapped_feat = feat->GetMappedFeature();
444  feat_group_params.Add(CConstRef<CSeq_feat>(&(mapped_feat.GetMappedFeature())), feat->GetMappingInfo());
445  }
446  SConstScopedObject scoped_obj(&(parent_feat->GetMappedFeature().GetMappedFeature()), &(parent_feat->GetMappedFeature().GetScope()));
447  CIRef<IGuiObjectInfo> gui_info(CreateObjectInterface<IGuiObjectInfo>(scoped_obj, &feat_group_params));
448  if (!gui_info)
449  return;
450  gui_info->GetToolTip(tt, t_title, at_p);
451  gui_info->GetLinks(tt, false);
452  }
453 
454  if ( !IsSelected()) {
455  tt.AddRow();
456  tt.AddRow("Click to show individual features.");
457  }
458 }
459 
461 {
462  bool RmtBased{false};
463  if (m_FirstIsParent) {
464  const CFeatGlyph* feat = x_GetFirstFeat();
465  _ASSERT(feat);
466  RmtBased = feat->isRmtBased();
467  } else if (m_ParentFeat) {
468  RmtBased = m_ParentFeat->isRmtBased();
469  }
470  return RmtBased;
471 }
472 
473 
474 
476 {
477  if (IsSelected() || IsHighlighted()) {
478  // add HTML active area for the parent feature
479  const CFeatGlyph* feat = m_ParentFeat;
480  if (m_FirstIsParent && feat) {
481  feat = x_GetFirstFeat();
482  }
483 
484  if (feat) {
485  x_AddFeatHTMLActiveArea(p_areas, feat);
486  // only use the merged feature bar height
487  TVPRect& bound = p_areas->back().m_Bounds;
488  TVPUnit merged_feature_height = (TVPUnit)m_Config->m_BarHeight;
489  if (x_LabelFirst()) {
490  merged_feature_height += (TVPUnit)x_GetLabelHeight();
491  }
492  // margin
493  merged_feature_height += 2.0;
494  bound.SetBottom(bound.Top() + merged_feature_height);
495  }
496 
497  // add HTML active areas for all child features
498  m_Group.GetHTMLActiveAreas(p_areas);
499  } else {
500  bool count_set = false;
501  size_t count_limit = 3; // report the areas for up to 3 features (including the parent)
502  // add HTML active area for parent feature if it is not included
503  if (!m_FirstIsParent && m_ParentFeat) {
504  x_AddFeatHTMLActiveArea(p_areas, m_ParentFeat, static_cast<unsigned>(GetChildren().size()));
505  count_limit = 2;
506  count_set = true;
507  }
508  if (GetChildren().size() > count_limit) {
509  if (m_FirstIsParent) {
510  x_AddFeatHTMLActiveArea(p_areas, x_GetFirstFeat(), static_cast<unsigned>(GetChildren().size() - 1));
511  }
513  }
514  else {
515  // report signatures for all the child features.
517  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
518  if (m_FirstIsParent && !count_set) {
519  x_AddFeatHTMLActiveArea(p_areas, feat, static_cast<unsigned>(GetChildren().size()));
520  count_set = true;
521  }
522  else {
523  x_AddFeatHTMLActiveArea(p_areas, feat);
524  }
525  }
526  }
527  }
528 }
529 
530 
532 {
535  range.CombineWith(*it);
536  }
537  return range;
538 }
539 
540 
542 {
543  if (f != IsSelected()) {
545  m_Group.Update(true);
547  }
548  return false;
549 }
550 
551 
553 {
554  bool cont = visitor->Visit(this);
555  return cont;
556 }
557 
558 
560 {
561  return true;
562 }
563 
564 
565 const objects::CSeq_loc& CLinkedFeatsGroup::GetLocation() const
566 {
567  return *m_Location;
568 }
569 
570 
572 {
573  // Use the first child feature to represent this group.
574  const CFeatGlyph* feat = x_GetFirstFeat();
575  return feat->GetObject(pos);
576 }
577 
578 
580 {
582  const CFeatGlyph* feat =
583  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
584  if (feat) {
585  feat->GetObjects(objs);
586  } else {
587  LOG_POST("Something is woring about linked feature group!");
588  }
589  }
590 }
591 
592 
593 
595 {
597  const CFeatGlyph* feat =
598  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
599  if ( feat->HasObject(obj) ) {
600  return true;
601  }
602  }
603  return false;
604 }
605 
606 
608 {
609  // Use the last child feature to represent this group.
610  return x_GetLastFeat()->GetSignature();
611 }
612 
613 
615 {
616  return m_Intervals;
617 }
618 
619 
621 {
622  if ((GetLeft() >= 0) && m_Context->IntersectVisible(GetRange()).Empty())
623  return;
624 
625  IRender& gl = GetGl();
626 
627  /// the merged feature bar
628  TModelUnit base = GetTop();
629 
630  for (const auto& seq_glyph : GetChildren()) {
631  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(seq_glyph.GetPointer());
632  if (nullptr == feat)
633  continue;
634 
635  if (CSeqUtils::IsException(feat->GetFeature())) {
636  x_DrawException();
637  break;
638  }
639  }
640 
641  bool label_first = x_LabelFirst();
642  bool draw_above = label_first || (m_Config->m_LabelPos == CFeatureParams::ePos_Above);
643 
644  if (draw_above && (m_Config->m_LabelPos != CFeatureParams::ePos_NoLabel) ) {
645  // If we draw above we don't draw on the right - when labels are be drawn above in
646  // the center (ePos_Above) this would not happen anyway. When space constraints
647  // force us to draw above on the left, we still want to center the label with the
648  // bar on the right
649  x_DrawLabels(base, true, false);
650  }
651 
652  TModelUnit bar_height = m_Config->GetBarHeight(false);
653  base += bar_height * 0.5; // bar center
654  if (m_FirstIsParent) {
656  } else {
657  x_DrawFeatureBar(base);
658  }
659 
661  if (!label_first)
662  x_DrawLabels(base);
663  else
664  x_DrawLabels(base, false, true); // Left label was above so just right label on line
665  }
666 
667  if (IsSelected() || IsHighlighted()) {
668  gl.PushMatrix();
669  gl.Translatef(0.0f, GetTop(), 0.0f);
670  // expand and draw the children
671  m_Group.Draw();
672  gl.PopMatrix();
673  // draw bounding box
674  if (IsSelected()) {
676  TModelUnit left = r.Left();
677  TModelUnit right = r.Right();
678  TModelRange visible_range = m_Context->IntersectVisible(TModelRange(left, right));
679  r.SetLeft(visible_range.GetFrom());
680  r.SetRight(visible_range.GetTo());
682  }
683  }
684 }
685 
686 
688 {
689  IRender& gl = GetGl();
690 
691  size_t num = GetChildren().size();
692  //ASSERT(num > 1);
693  if (m_Intervals.empty()) {
694  x_CalcIntervals();
695  }
697  SetLeft(m_Intervals.front().GetFrom());
698  SetWidth(m_Intervals.back().GetToOpen() - GetLeft());
701  bool neg_strand =
704 
705  if (x_ShowLabel()) {
707  if (num > 0 && num <= 2 && m_LabelType != fLabel_FeatNum) {
708  // we show feature labels at both ends
709  // show the label from the first feature on the left end
710  // if the features are in positive strand. Otherwise, the
711  // show the label from the second feature on the left
712  int curr_idx = num > 1 && neg_strand ? 1 : 0;
713  CRef<CSeqGlyph> curr_child = m_Group.GetChild(curr_idx);
714  const CFeatGlyph* feat =
715  dynamic_cast<const CFeatGlyph*>(curr_child.GetPointer());
716  string label;
718  TModelUnit text_w = min(
719  gl.TextWidth(&(m_Config->m_LabelFont), label.c_str()),
721  text_w = m_Context->ScreenToSeq(text_w + kLabelSpace);
722  SetWidth(GetWidth() + text_w);
723  SetLeft(GetLeft() - text_w);
724 
725  if (x_LabelFirst()) {
727  }
728  if (num > 1) {
729  // show the label from the other feature on the right end
730  curr_idx = 1 - curr_idx;
731  curr_child = m_Group.GetChild(curr_idx);
732  feat = dynamic_cast<const CFeatGlyph*>(curr_child.GetPointer());
733  label.clear();
735  text_w = min(gl.TextWidth(&(m_Config->m_LabelFont), label.c_str()),
737  text_w = m_Context->ScreenToSeq(text_w + kLabelSpace);
738  SetWidth(GetWidth() + text_w);
739  }
740  } else {
741  // there are more than 2 features, the label depends on setting
742  string label;
744  TModelUnit text_w = min(
745  gl.TextWidth(&(m_Config->m_LabelFont), label.c_str()),
747  text_w = m_Context->ScreenToSeq(text_w + kLabelSpace);
748  SetWidth(GetWidth() + text_w);
749  if ( !neg_strand ) SetLeft(GetLeft() - text_w);
750  }
751  } else if (m_Context->WillLabelFit(range)) {
753  }
754  }
755 
756  if (IsSelected() || IsHighlighted()) {
757  // add padding
758  SetHeight(GetHeight() + 2.0);
761  TModelUnit right = max(GetRight(), m_Group.GetRight());
763  SetWidth(right - GetLeft());
764  }
765 }
766 
767 
769 {
772 }
773 
775 {
776  bool first = true;
778  first = false;
782  if (GetRight() > seq_ds->GetSequenceLength()) {
783  first = true;
784  }
785  } else if (GetLeft() < 0) {
786  first = true;
787  }
788  }
789  }
790  return first;
791 }
792 
793 
794 
795 void CLinkedFeatsGroup::x_DrawLabels(TModelUnit& base, bool draw_left, bool draw_right) const
796 {
797  if ( !x_ShowLabel() ) return;
798 
799  IRender& gl = GetGl();
800 
801  TModelRange vis_r = m_Context->IntersectVisible(this);
802  const CGlTextureFont& font = m_Config->m_LabelFont;
803  TModelUnit font_h = gl.TextHeight(&font);
804  TModelUnit height = std::max<TModelUnit>(m_Config->m_BarHeight, font_h);
805  bool label_first = x_LabelFirst();
806 
807  bool neg_strand =
809 
811  string label_l = kEmptyStr;
812  string label_r = kEmptyStr;
813  auto num = GetChildren().size();
814  if (num <= 2 && m_LabelType != fLabel_FeatNum) {
815  int curr_idx = num > 1 && neg_strand ? 1 : 0;
816  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(
817  m_Group.GetChild(curr_idx).GetPointer());
818  feat->GetLabel(label_l, CLabel::eContent);
819  if (num > 1) {
820  curr_idx = 1 - curr_idx;
821  feat = dynamic_cast<const CFeatGlyph*>(m_Group.GetChild(curr_idx).GetPointer());
822  feat->GetLabel(label_r, CLabel::eContent);
823  }
824  } else {
825  // there are more than 2 features, the label depends on setting
826  if (neg_strand) {
827  x_GetUniqueLabel(label_r);
828  } else {
829  x_GetUniqueLabel(label_l);
830  }
831  }
832 
833  TModelUnit max_w = m_Context->GetMaxLabelWidth(font);
834  TModelUnit label_offset = m_Context->ScreenToSeq(1.0);
835 
836  // draw side label
837  if ( !label_l.empty() && draw_left ) {
838  TModelUnit label_w_l = gl.TextWidth(&font, label_l.c_str());
839  if (label_w_l > max_w) {
840  label_w_l = max_w;
841  label_l = font.Truncate(label_l.c_str(), label_w_l);
842  }
843  label_w_l = m_Context->ScreenToSeq(label_w_l + kLabelSpace);
844  bool label_visible = m_Intervals.back().GetTo() - vis_r.GetFrom() > label_w_l;
845  if (x_GetFirstFeat()->GetFeature().GetData().Which() == CSeqFeatData::e_Variation) {
846  bool inside_only = m_Config->m_LabelPos == CFeatureParams::ePos_Inside;
847  CSeqGlyph::x_DrawInnerLabels(base, label_l, m_Config->m_fgColor.ContrastingColor(), m_Config->m_LabelFont, label_visible, inside_only);
848  }
849  if (label_visible) {
850  // Background rect is larger of font size or bar height (since it has
851  // to overwrite the bar in some cases)
852  //if (vis_r.GetFrom() + label_w_l > GetLeft()) {
853  // label_w_l = GetLeft()-vis_r.GetFrom();
854  // TModelUnit pix_label_w_l = m_Context->SeqToScreen(label_w_l);
855  // label_l = font.Truncate(label_l, pix_label_w_l);
856  //}
857  TModelRect rect(vis_r.GetFrom() + label_offset, base + height * 0.5,
858  vis_r.GetFrom() + label_w_l, base - height * 0.5);
859 
861  m_Context->DrawBackground(rect, 0);
862 
864  if (!label_first)
865  m_Context->TextOut(&font, label_l.c_str(), rect.Left(), base + font_h * 0.5, false, true);
866  else
867  m_Context->TextOut(&font, label_l.c_str(), rect.Left(), base + font_h, false, true);
868  }
869  }
870 
871  if ( !label_r.empty() && draw_right ) {
872  // draw right side label
873  TModelUnit label_w_r = gl.TextWidth(&font, label_r.c_str());
874  if (label_w_r > max_w) {
875  label_w_r = max_w;
876  label_r = font.Truncate(label_r.c_str(), label_w_r);
877  }
878  label_w_r = m_Context->ScreenToSeq(label_w_r);
879  bool label_visible = vis_r.GetToOpen() - m_Intervals.front().GetFrom() > label_w_r;
880  if (x_GetFirstFeat()->GetFeature().GetData().Which() == CSeqFeatData::e_Variation) {
881  bool inside_only = m_Config->m_LabelPos == CFeatureParams::ePos_Inside;
882  CSeqGlyph::x_DrawInnerLabels(base, label_r, m_Config->m_fgColor.ContrastingColor(), m_Config->m_LabelFont, label_visible, inside_only);
883  }
884  if (label_visible) {
885  // Background rect is 1 pixel bigger (top and bottom) because it has to sometimes
886  // overwrite glyph as well
887  TModelRect rect(vis_r.GetToOpen() - label_w_r - label_offset, base + height * 0.5,
888  vis_r.GetToOpen(), base - height * 0.5);
889  if (vis_r.GetToOpen() <= GetRight()) {
891  m_Context->DrawBackground(rect, 0);
892  }
894  m_Context->TextOut(&font, label_r.c_str(), rect.Left(), base + font_h * 0.5, false, true);
895  }
896  }
897 
898  // If label was forced to the top, add to the base to put glyph below label
899  if (m_Config->m_LabelPos == CFeatureParams::ePos_Above || label_first) {
900  base += x_GetLabelHeight();
901  }
902 
903  } else if (m_Context->WillLabelFit(vis_r)) {
904  string label;
905  if ( !m_FirstIsParent && m_ParentFeat) {
907  }
909  label += (label.empty() ? "" : "/");
910  const CFeatGlyph* feat =
911  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
912  if (CSeqFeatData::eSubtype_cdregion != feat->GetFeature().GetData().GetSubtype())
914  else
916  }
917 
918  if (IsSelected())
919  label += " [-]";
920  else if (!IsHighlighted()) {
921  label += " [+";
923  label += ']';
924  }
925 
926  TModelUnit label_w =
927  m_Context->ScreenToSeq(gl.TextWidth(&font, label.c_str()));
928 
929  if (label_w > vis_r.GetLength()) {
930  label = font.Truncate(label.c_str(),
931  m_Context->SeqToScreen(vis_r.GetLength()));
932  }
933 
934  if (IsSelected()) {
938  } else {
940  }
941 
942  TModelUnit xM = vis_r.GetFrom() + vis_r.GetLength() * 0.5;
943  TModelUnit yM = base;
944  if (m_Config->m_LabelPos == CFeatureParams::ePos_Above || label_first) {
945  base += gl.TextHeight(&font);
946  yM = base;
947  } else {
948  yM += gl.TextHeight(&font) * 0.5;
949  }
950 
951  m_Context->TextOut(&font, label.c_str(), xM, yM, true, true);
952  }
953 }
954 
955 
957 {
958  TModelUnit bar_height = m_Config->m_BarHeight;
959  TModelUnit line_ym = base;
960  TModelUnit line_y1 = line_ym - bar_height * 0.5f;
961  TModelUnit line_y2 = line_ym + bar_height * 0.5f;
962 
963  const CFeatGlyph* first_feat = x_GetFirstFeat();
964  TModelUnit pix_size = m_Context->ScreenToSeq(1.0);
965  CRgbaColor fg_color = first_feat->GetConfig()->m_fgColor;
966  bool show_strand_indicator =
968  first_feat->GetConfig()->m_ShowStrandIndicator &&
970 
971  bool is_parent = true;
972  if (first_feat->GetRange().GetLength() > pix_size) { // At least 1 pixel
974  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
975  _ASSERT(feat);
976 
977  TSeqPos f = feat->GetRange().GetFrom();
978  TSeqPos t = feat->GetRange().GetTo();
979 
980  CRgbaColor curr_color = fg_color;
981  if ( !is_parent ) {
982  // render the children using different color
983  if ( !feat->GetCustomColor(curr_color) ) {
984  curr_color = curr_color.ContrastingColor(false);
985  curr_color.SetGreen(0.3f);
986  curr_color.SetBlue(0.3f);
987  }
988  curr_color.SetAlpha(0.7f);
989  }
990  // draw the features in 3D
991  m_Context->Draw3DQuad(f, line_y1, t, line_y2, curr_color);
992 
993  if (show_strand_indicator) {
994  auto strand = sequence::GetStrand(feat->GetLocation());
995  if (strand != eNa_strand_both && strand != eNa_strand_both_rev) {
996  // distance among strand indicators
997  TModelUnit apart = 100.0 * pix_size; // 100 pixels on screen
999  t - f, apart, bar_height, curr_color.ContrastingColor(), strand == eNa_strand_minus);
1000  }
1001  }
1002  is_parent = false;
1003  }
1004  } else {
1005  // use the top-most feature's color
1006  const CFeatGlyph* feat =
1007  dynamic_cast<const CFeatGlyph*>(GetChildren().back().GetPointer());
1008  _ASSERT(feat);
1009  CRgbaColor curr_color;
1010  if ( !feat->GetCustomColor(curr_color) ) {
1011  curr_color = feat->GetConfig()->m_fgColor;
1012  }
1013  // bar is less then 1 pixel. Do not draw intervals
1014  TModelUnit from = first_feat->GetRange().GetFrom();
1015  m_Context->Draw3DQuad(from, line_y1, from + pix_size, line_y2, curr_color, true);
1016  }
1017 }
1018 
1019 
1021 {
1022  if (m_Intervals.empty()) return;
1023 
1024  IRender& gl = GetGl();
1025 
1026  TModelUnit bar_height = m_Config->m_BarHeight;
1027  TModelUnit line_ym = base;
1028  TModelUnit line_y1 = line_ym - bar_height * 0.5f;
1029  TModelUnit line_y2 = line_ym + bar_height * 0.5f;
1030 
1031  const CFeatGlyph* feat = x_GetFirstFeat();
1032 
1033  auto strand = sequence::GetStrand(feat->GetLocation());
1034  bool neg_strand = (strand == eNa_strand_minus);
1035 
1036  CRgbaColor color;
1037  if ( !feat->GetCustomColor(color) ) {
1039  }
1040 
1041  // For dbVar features (ssv), there may be two types of features
1042  // with two differnt colors. We render the merged bar with two
1043  // colors for the top part and bottom part.
1044  CRgbaColor color2 = color;
1045  bool two_colors = false;
1046  if (CFeatGlyph::IsDbVar(feat->GetFeature())) {
1047  size_t idx1 = CFeatGlyph::GetCustomColorIdx(feat->GetFeature());
1049  const CFeatGlyph* tmp_feat =
1050  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
1051  size_t idx2 =
1053  if (idx2 != idx1) {
1054  tmp_feat->GetCustomColor(idx2, color2);
1055  two_colors = true;
1056  break;
1057  }
1058  }
1059  }
1060 
1061  TModelUnit pix_size = m_Context->ScreenToSeq(1.0);
1062 
1063  TSeqRange range(m_Intervals.front().GetFrom(), m_Intervals.back().GetTo());
1064  // Draw feature bar
1065  if (range.GetLength() > pix_size) { // At least 1 pixel
1066  // distance among strand indicators
1067  TModelUnit apart = 100.0 * pix_size; // 100 pixels on screen
1068  bool show_strand_indicator =
1071 
1072  float max_c = 0;
1073  // We know the minimal count is 1, and we want to set the minimum to 0.
1074  // So substract 1 from each count
1075  ITERATE (TCounts, iter, m_IntCounts) {
1076  max_c = max<float>(max_c, *iter - 1);
1077  }
1078 
1079  if (max_c == 0.0f) {
1080  max_c = 1.0f;
1081  }
1082  max_c = 1.0f / max_c;
1083  CRgbaColor color_lite(color);
1084  color_lite.Lighten(0.6f);
1085  CRgbaColor intron_c(color);
1086  intron_c.Lighten(0.2f);
1087  CRgbaColor color_lite2(color_lite);
1088  if (two_colors) {
1089  color_lite2 = color2;
1090  color_lite2.Lighten(0.6f);
1091  }
1092 
1093  bool first_pass = true;
1094  TModelUnit pre_to = 0;
1095  // draw exons and introns
1096  for (size_t i = 0; i < m_IntCounts.size(); ++i) {
1097  const TSeqRange& curr = m_Intervals[i];
1098  TModelUnit f = curr.GetFrom();
1099  TModelUnit t = curr.GetTo() + 1;
1100 
1101  TModelRange visible_range = m_Context->IntersectVisible(curr);
1102  bool is_bar_visible = visible_range.NotEmpty();
1103  if (is_bar_visible) {
1104  f = visible_range.GetFrom();
1105  t = visible_range.GetTo() + 1;
1106  }
1107 
1108  // draw introns first
1109  if (!first_pass && pre_to < f) {
1110  glPushAttrib(GL_LINE_BIT);
1111  switch (m_Config->m_LineStyle) {
1113  gl.LineStipple(1, 0x0F0F);
1114  gl.Enable(GL_LINE_STIPPLE);
1115  break;
1117  gl.LineStipple(1, 0x0202);
1118  gl.Enable(GL_LINE_STIPPLE);
1119  break;
1121  gl.LineStipple(1, 0x1C47);
1122  gl.Enable(GL_LINE_STIPPLE);
1123  break;
1124  case CFeatureParams::eLine_ShortDashed: //Repeating pairs: -- -- --
1125  gl.LineStipple(2, 0xAAAA);
1126  gl.Enable(GL_LINE_STIPPLE);
1127  break;
1129  gl.Disable(GL_LINE_STIPPLE);
1130  break;
1131  } // m_Config->m_LineStyle
1132 
1133  gl.LineWidth((float)(m_Config->m_LineWidth));
1134  gl.ColorC(intron_c);
1135 
1136  visible_range = m_Context->IntersectVisible(TModelRange(pre_to, f));
1137  bool is_intron_visible = visible_range.NotEmpty();
1138  if (is_intron_visible) {
1139  pre_to = visible_range.GetFrom();
1140  f = visible_range.GetTo();
1141 
1142  switch (m_Config->m_Connections) {
1144  { {
1145  TModelUnit middle_x =
1146  pre_to + (f - pre_to) * 0.5;
1147  m_Context->DrawLine(pre_to, line_ym, middle_x, line_y1);
1148  m_Context->DrawLine(middle_x, line_y1, f, line_ym);
1149  }}
1150  break;
1151  case CFeatureParams::eBox:
1152  { {
1153  // if short, may look like we are drawing on one side or not at all
1154  if (m_Context->SeqToScreen(fabs(pre_to - f)) < TModelUnit(6.0))
1155  gl.Disable(GL_LINE_STIPPLE);
1156 
1157  m_Context->DrawLine(f, line_y1, pre_to, line_y1);
1158  m_Context->DrawLine(f, line_y2, pre_to, line_y2);
1159  }}
1160  break;
1162  m_Context->DrawLine(pre_to, line_ym, f, line_ym);
1163  break;
1165  gl.Disable(GL_LINE_STIPPLE);
1166  gl.ColorC(color_lite);
1167  m_Context->DrawQuad(pre_to, line_y1, f, line_y2);
1168  break;
1169  } // m_Config->m_Connections
1170  }
1171  gl.Disable(GL_LINE_STIPPLE);
1172  gl.LineWidth(1.0f);
1173  glPopAttrib();
1174 
1175  if (show_strand_indicator && strand != eNa_strand_both && strand != eNa_strand_both_rev && is_intron_visible) {
1176  m_Context->DrawStrandIndicators(TModelPoint(pre_to, line_y1),
1177  f - pre_to, apart, bar_height,
1178  CRgbaColor(0.7f, 0.7f, 0.7f), neg_strand);
1179  }
1180  } // connection lines (introns)
1181 
1182  // next - draw exons as quads
1183  if (is_bar_visible) {
1184  float score = (m_IntCounts[i] - 1) * max_c;
1185  CRgbaColor c(CRgbaColor::Interpolate(color, color_lite, score));
1186  gl.ColorC(c);
1187  if (two_colors) {
1188  m_Context->DrawQuad(f, line_y1, t, line_ym);
1189  c = CRgbaColor::Interpolate(color2, color_lite2, score);
1190  gl.ColorC(c);
1191  m_Context->DrawQuad(f, line_ym, t, line_y2);
1192  }
1193  else {
1194  m_Context->DrawQuad(f, line_y1, t, line_y2);
1195  }
1196 
1197  if (show_strand_indicator && strand != eNa_strand_both && strand != eNa_strand_both_rev) {
1199  t - f, apart, bar_height, c.ContrastingColor(), neg_strand);
1200  }
1201  }
1202 
1203  pre_to = t;
1204  first_pass = false;
1205  }
1206  } else {
1207  // bar is less then 1 pixel. Do not draw intervals
1208  TModelUnit from = range.GetFrom();
1209  m_Context->Draw3DQuad(from, line_y1, from + pix_size, line_y2, color, true);
1210  }
1211 }
1212 
1213 
1215 {
1216  m_Intervals.clear();
1217  m_IntCounts.clear();
1218  typedef map<TSeqPos, int> TIntervalCounts;
1219  TIntervalCounts int_counts;
1220 
1221  // brute force approach
1222  /*
1223  ITERATE (CLayoutGroup::TObjectList, iter, GetChildren()) {
1224  const CFeatGlyph* feat =
1225  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
1226  const TIntervals& intervals = feat->GetIntervals();
1227  ITERATE (TIntervals, i_iter, intervals) {
1228  TSeqPos f = i_iter->GetFrom();
1229  TSeqPos t = i_iter->GetToOpen();
1230  _ASSERT(f < t);
1231  TIntervalCounts::iterator up_iter = int_counts.upper_bound(f);
1232  if (up_iter == int_counts.end()) {
1233  int_counts[f] = 1;
1234  int_counts[t] = 0;
1235  } else {
1236  TIntervalCounts::iterator low_iter = up_iter;
1237  if (--low_iter == int_counts.end() || low_iter->first < f) {
1238  int cnt = 0;
1239  if (low_iter != int_counts.end()) {
1240  cnt = low_iter->second;
1241  }
1242  low_iter = up_iter = int_counts.insert(up_iter,
1243  TIntervalCounts::value_type(f, cnt));
1244  ++up_iter;
1245  }
1246  while (up_iter != int_counts.end() && up_iter->first < t) {
1247  low_iter->second += 1;
1248  low_iter = up_iter;
1249  ++up_iter;
1250  }
1251  low_iter->second += 1;
1252  if (up_iter == int_counts.end()) {
1253  int_counts[t] = 0;
1254  } else if (t < up_iter->first) {
1255  int_counts[t] = low_iter->second - 1;
1256  }
1257  }
1258  }
1259  }
1260 
1261  // now extract the intervals with count > 0
1262  TIntervalCounts::const_iterator c_iter = int_counts.begin();
1263  while (c_iter != int_counts.end()) {
1264  TIntervalCounts::const_iterator curr = c_iter;
1265  ++c_iter;
1266  if (curr->second > 0) {
1267  m_IntCounts.push_back(curr->second);
1268  m_Intervals.push_back(TSeqRange(curr->first, c_iter->first - 1));
1269  }
1270  }
1271  */
1272 
1274  const CFeatGlyph* feat =
1275  dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
1276  const TIntervals& intervals = feat->GetIntervals();
1277  ITERATE (TIntervals, i_iter, intervals) {
1278  TSeqPos f = i_iter->GetFrom();
1279  TSeqPos t = i_iter->GetToOpen();
1280  _ASSERT(f < t);
1281  TIntervalCounts::iterator at_iter = int_counts.find(f);
1282  if (at_iter != int_counts.end()) {
1283  at_iter->second += 1;
1284  } else {
1285  int_counts[f] = 1;
1286  }
1287  at_iter = int_counts.find(t);
1288  if (at_iter != int_counts.end()) {
1289  at_iter->second -= 1;
1290  } else {
1291  int_counts[t] = -1;
1292  }
1293  }
1294  }
1295 
1296  // now extract the intervals
1297  _ASSERT(int_counts.size() > 1);
1298  TIntervalCounts::const_iterator s_iter = int_counts.begin();
1299  TIntervalCounts::const_iterator e_iter = s_iter;
1300  ++e_iter;
1301  int cnt = s_iter->second;
1302  while (e_iter != int_counts.end()) {
1303  if (cnt > 0) { // interval
1304  m_IntCounts.push_back(cnt);
1305  m_Intervals.push_back(TSeqRange(s_iter->first, e_iter->first - 1));
1306  }
1307  s_iter = e_iter;
1308  ++e_iter;
1309  cnt += s_iter->second;
1310  }
1311 
1312 }
1313 
1314 
1316 {
1317  label = kEmptyStr;
1319  if (m_ParentFeat) {
1321  } else if (m_FirstIsParent) {
1323  }
1324  }
1325  if (m_LabelType & fLabel_FeatNum) {
1326  if ( !label.empty() ) label += "/";
1327  label += NStr::SizetToString(m_Group.GetChildrenNum()) + " features";
1328  }
1329  else {
1330  if (IsSelected())
1331  label += " [-]";
1332  else if (!IsHighlighted()) {
1333  label += " [+";
1335  label += ']';
1336  }
1337  }
1338 }
1339 
1340 
1342 {
1343  const CFeatGlyph* feat = NULL;
1345  feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
1346  if (feat) break;
1347  }
1348  _ASSERT(feat);
1349  return feat;
1350 }
1351 
1352 
1354 {
1355  const CFeatGlyph* feat = NULL;
1356  for (CLayoutGroup::TObjectList::const_reverse_iterator iter = GetChildren().rbegin();
1357  iter != GetChildren().rend(); ++iter) {
1358  feat = dynamic_cast<const CFeatGlyph*>(iter->GetPointer());
1359  if (feat) break;
1360  }
1361  _ASSERT(feat);
1362  return feat;
1363 }
1364 
1365 
1367 {
1368  return GetGl().TextHeight(&(m_Config->m_LabelFont)) + 2.0;
1369 }
1370 
1371 
1372 void CLinkedFeatsGroup::x_AddFeatHTMLActiveArea(TAreaVector* p_areas, const CFeatGlyph* feat, unsigned merged_feats_count) const
1373 {
1374  if (!feat)
1375  return;
1376  CHTMLActiveArea area;
1378  area.m_DB_Name = "";
1379 
1380  area.m_Signature = feat->GetSignature();
1382 
1383  if (merged_feats_count) {
1384  area.m_MergedFeatsCount = merged_feats_count;
1385  }
1386  if (!feat->GetMappingInfo().empty()) {
1388  }
1389 
1390  // a tooltip should be generated for features created by a remote file pipeline to avoid an additional roundtrip
1391  if(isRmtBased()) {
1392  string s;
1393  string title;
1395  tooltip->SetTrustedData(false);
1396  GetTooltip(TModelPoint(-1, -1), *tooltip, title);
1397  s = tooltip->Render();
1398  string text = NStr::Replace(s, "\n", "<br/>");
1399  area.m_Descr = text;
1400  }
1401 
1402  p_areas->push_back(area);
1403 }
1404 
1405 
1407 {
1408  const ILayoutPolicy::TObjectList& children = GetChildren();
1409  if (children.size() <= 1)
1410  return true;
1411 
1412  CLayoutGroup::TObjectList::const_iterator feat_it = children.begin();
1413 
1414  const CFeatGlyph* first_feat = dynamic_cast<const CFeatGlyph*>(feat_it->GetPointer());
1415  _ASSERT(first_feat);
1416  bool neg_strand = (sequence::GetStrand(first_feat->GetLocation()) == eNa_strand_minus);
1417 
1418  while (++feat_it != children.end()) {
1419  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(feat_it->GetPointer());
1420  _ASSERT(feat);
1421  if (neg_strand != (sequence::GetStrand(feat->GetLocation()) == eNa_strand_minus))
1422  return false;
1423  }
1424  return true;
1425 }
1426 
#define false
Definition: bool.h:36
CConstRef –.
Definition: ncbiobj.hpp:1266
void Add(const CConstRef< objects::CSeq_feat > &feat, const CSeqUtils::TMappingInfo &mapping_info=CSeqUtils::TMappingInfo())
bool IsLabelHided() const
bool GetCustomColor(CRgbaColor &color) const
Get the customized color for a given feature.
virtual string GetSignature() const
return signature for this glyph.
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
const TMappingInfo & GetMappingInfo() const
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
bool isRmtBased() const
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
Retrieve the feature as an object.
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
CConstRef< CFeatureParams > GetConfig() const
static bool IsDbVar(const objects::CSeq_feat &feat)
Utility to check if a feature is a structural variation.
const objects::CMappedFeat & GetMappedFeature(void) const
Access a new, fully remapped feature.
virtual TSeqRange GetRange(void) const
get the total range of this object.
virtual const TIntervals & GetIntervals(void) const
access sub-intervals (if any).
const objects::CSeq_feat & GetFeature(void) const
Access the original feature.
static size_t GetCustomColorIdx(const objects::CSeq_feat &feat)
Get the customized color idx for a given feature.
void GetLabel(string &label, CLabel::ELabelType type) const
retrieve feature label for a given type
ELineStyle m_LineStyle
EConnection m_Connections
TModelUnit m_LineWidth
absolute value (in pixel)
CRgbaColor m_LabelColor
CRgbaColor m_bgColor
CRgbaColor m_fgColor
CGlTextureFont m_LabelFont
TModelUnit GetBarHeight(bool overview) const
ELabelPosition m_LabelPos
TModelUnit m_BarHeight
absolute size (in pixel)
@ ePos_NoLabel
no label
@ ePos_Side
always on 5' side
@ ePos_Inside
inside the rendered bar
@ ePos_Above
above the rendered bar
bool m_ShowStrandIndicator
virtual string GetSignature() const
return signature for this glyph.
bool x_ShowGeneLabel() const
virtual const TIntervals & GetIntervals() const
access sub-intervals (if any).
@ eGene_Shown
show gene bar
@ eGene_ShowLabelOnly
hide gene bar, but show label with bar space
@ eGene_Hidden
hide gene bar and gene label completely
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
access our core component - we wrap an object(s) of some sort.
virtual bool Accept(IGlyphVisitor *visitor)
Interface for accepting an IGlyphVisitor.
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
void SetShowGene(bool flag)
virtual const objects::CSeq_loc & GetLocation() const
access the position of this object.
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
virtual TSeqRange GetRange(void) const
Get gene feature range instead.
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
virtual void Update(bool layout_only)
CGeneGroup implementations.
virtual void x_Draw() const
The default renderer for this layout object.
TModelUnit x_GetLabelHeight() const
Returns the height of the label with margin included.
const CFeatGlyph * x_GetFirstFeat() const
string m_Descr
description that can be used as label or tooltip
@ fNoCaching
The tooltip for this feature should not be cached.
int m_Flags
area flags, will need to replace m_Type
bool m_PositiveStrand
the default is true
CLayoutGroup is a container of CSeqGlyphs (layout objects).
void HideMaster(bool hidden=true)
TObjectList & SetChildren()
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
const TObjectList & GetChildren() const
CLayoutGroup inline methods.
void SetAsMaster(CRef< CSeqGlyph > master)
master glyph has some special meaning (e.g.
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
CConstRef< CSeqGlyph > GetChild(int idx) const
Get the layout object at index 'idx'.
void x_DrawBoundary() const
virtual void Update(bool layout_only)
Update content and layout including the bounding box.
size_t GetChildrenNum() const
Get total number of children.
bool x_isDrawn() const
determines whether the glyph should be drawn or not at all (currently children of unselected parents ...
virtual CRef< CSeqGlyph > HitTest(const TModelPoint &p)
Hit testing.
ILayoutPolicy::TObjectList TObjectList
CLinkedFeatsGroup is a container class contains related features.
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
virtual void x_Draw() const
The default renderer for this layout object.
CRef< objects::CSeq_loc > m_Location
just for satisfy IObjectBasedGlyph interface.
TCounts m_IntCounts
Shall have the same size as m_Intervals.
virtual bool Intersects(const TModelRect &rect, TConstObjects &objs) const
Intersect testing.
virtual bool NeedTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Check if need to show tooltip.
void x_DrawChildrenOnParent(TModelUnit &base) const
draw the merged feature bar with children on top of parent.
CConstRef< CFeatGlyph > m_ParentFeat
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
virtual bool Accept(IGlyphVisitor *visitor)
Interface for accepting an IGlyphVisitor.
void x_DrawLabels(TModelUnit &base, bool draw_left=true, bool draw_right=true) const
draw the labels for merged features.
void x_CalcIntervals()
calculate the merged feature bar intervals and overlapping counts.
virtual bool IsClickable() const
Query if this glyph is clickable.
CLinkedFeatsGroup()
CLinkedFeatsGroup implementations.
virtual string GetSignature() const
return signature for this glyph.
const ILayoutPolicy::TObjectList & GetChildren() const
CLinkedFeatsGroup inline methods.
bool x_LabelFirst() const
check to see if label needs to be drawn before (above) feature bar.
bool x_AreAllFeaturesOnSameStrand() const
const CFeatGlyph * x_GetFirstFeat() const
get the first feature glyph in the group.
void x_GetUniqueLabel(string &label) const
utility method for generating a unique label for the merged bar.
bool x_ShowLabel() const
Check if need to show label.
const CFeatGlyph * x_GetLastFeat() const
get the last feature glyph in the group.
virtual bool SetSelected(bool f)
Select or deselect this glyph.
void x_AddFeatHTMLActiveArea(TAreaVector *p_areas, const CFeatGlyph *feat, unsigned merged_feats_count=0) const
virtual void Update(bool layout_only)
Update content and layout including the bounding box.
TModelUnit x_GetLabelHeight() const
Returns the height of the label with margin included.
bool m_FirstIsParent
The first feature is the parent feature.
virtual const objects::CSeq_loc & GetLocation() const
access the position of this object.
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
void x_DrawFeatureBar(TModelUnit &base) const
draw the merged feature bar.
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
virtual CRef< CSeqGlyph > HitTest(const TModelPoint &p)
Hit testing.
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
access our core component - we wrap an object(s) of some sort.
virtual TSeqRange GetRange(void) const
get the total range of this object.
virtual const TIntervals & GetIntervals() const
access sub-intervals (if any).
CConstRef< CFeatureParams > m_Config
settings for rendering merged feature bar.
CMappedFeat –.
Definition: mapped_feat.hpp:59
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
void DrawPseudoBar(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &light_color, const CRgbaColor &dark_color) const
CRef< CSGSequenceDS > GetSeqDS() const
TModelRange IntersectVisible(const CSeqGlyph *obj) const
void DrawLine(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
void DrawQuad(const TModelRect &rc, bool border=false) const
void DrawSelection(const TModelRect &rc) const
bool IsSkipFrames() const
TModelUnit SeqToScreen(const TModelUnit &size) const
convert from sequence positions to screen pixels
TModelUnit GetMaxLabelWidth(const CGlBitmapFont &font) const
In screen pixel..
TModelUnit ScreenToSeq(const TModelUnit &size) const
convert from screen pixels to sequence positions
const CRgbaColor & GetSelLabelColor() const
bool WillLabelFit(const TModelRect &rc) const
void Draw3DQuad(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &color, bool border=false) const
void DrawBackground(const TModelRect &rcm, TModelUnit border) const
void DrawStrandIndicators(const TModelPoint &start, TModelUnit length, TModelUnit apart, TModelUnit size, const CRgbaColor &color, bool neg_strand, bool avoid_center=false, bool single_indicator_center=false, const vector< TModelRange > *labels_ranges=nullptr) const
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
TSeqPos GetSequenceLength() const
void x_InitHTMLActiveArea(CHTMLActiveArea &area) const
initialize the basic information for a given active area.
Definition: seq_glyph.cpp:380
CRenderingContext * m_Context
the rendering context
Definition: seq_glyph.hpp:346
virtual void x_OnLayoutChanged()
update the layout.
Definition: seq_glyph.cpp:353
void x_Parent2Local(TModelPoint &pnt) const
Transform the coordiante from parent coord. to local coord.
Definition: seq_glyph.hpp:710
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
int GetLevel() const
Definition: seq_glyph.hpp:286
virtual TModelUnit GetRight() const
Definition: seq_glyph.hpp:603
void x_DrawInnerLabels(TModelUnit base, const string &label, const CRgbaColor &color, const CGlTextureFont &font, bool side_label_visible, bool inside_only, vector< TModelRange > *labels_ranges=nullptr, TSeqRange *interval=nullptr, bool XOR_mode=false) const
Definition: seq_glyph.cpp:224
void x_DrawException() const
Draw a shading background to indicate exception.
Definition: seq_glyph.cpp:338
void SetParent(CSeqGlyph *p)
Definition: seq_glyph.hpp:670
bool IsIn(const TModelPoint &p) const
Hit test for points in PARENT COORD.
Definition: seq_glyph.hpp:569
virtual void SetWidth(TModelUnit w)
Definition: seq_glyph.hpp:646
bool IsSelected() const
Definition: seq_glyph.hpp:573
virtual void SetLeft(TModelUnit l)
Definition: seq_glyph.hpp:654
virtual TModelUnit GetTop() const
Definition: seq_glyph.hpp:599
virtual TModelUnit GetHeight() const
Definition: seq_glyph.hpp:587
virtual void Update(bool)
Update content and layout including the bounding box.
Definition: seq_glyph.cpp:86
virtual void SetTop(TModelUnit b)
Definition: seq_glyph.hpp:658
void Draw() const
render the layout.
Definition: seq_glyph.cpp:92
virtual bool SetSelected(bool flag)
Select or deselect this glyph.
Definition: seq_glyph.hpp:525
virtual void x_DrawHighlight() const
Definition: seq_glyph.cpp:170
virtual TModelUnit GetWidth() const
Definition: seq_glyph.hpp:591
virtual TModelUnit GetLeft() const
Definition: seq_glyph.hpp:595
TModelRect GetModelRect() const
get the bounding box.
Definition: seq_glyph.hpp:562
vector< CHTMLActiveArea > TAreaVector
Definition: seq_glyph.hpp:84
list< CConstRef< CSeqGlyph > > TConstObjects
Definition: seq_glyph.hpp:86
bool IsHighlighted() const
Definition: seq_glyph.hpp:577
Visitor interface for applying any potential actions or algorithms.
Definition: seq_glyph.hpp:384
virtual bool Visit(CSeqGlyph *glyph)=0
list< CRef< CSeqGlyph > > TObjectList
vector< TSeqRange > TIntervals
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
Definition: map.hpp:338
char value[7]
Definition: config.c:431
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
bool Empty(const CNcbiOstrstream &src)
Definition: fileutil.cpp:523
USING_SCOPE(objects)
static const int kLabelSpace
static const int kVertSpace
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 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
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
static bool IsException(const objects::CSeq_feat &feat)
Definition: utils.cpp:962
virtual void Translated(GLdouble x, GLdouble y, GLdouble z)=0
GLdouble TModelUnit
Definition: gltypes.hpp:48
T X() const
Definition: glpoint.hpp:59
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+.
IRender & GetGl()
convenience function for getting current render manager
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
virtual TModelUnit TextWidth(const CGlTextureFont *font, const char *text) const =0
virtual void PopMatrix()=0
T Left() const
Definition: glrect.hpp:81
void SetFontFace(EFontFace face, bool use_bitmap_overrides=true)
int TVPUnit
Definition: gltypes.hpp:47
CRange< TModelUnit > TModelRange
Definition: gltypes.hpp:56
void SetFontSize(unsigned int size)
Set/get font size in points.
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
static EFontFace FaceFromString(const string &str)
Selects a font face given a string or eFontFace_LastFont on failure.
CGlPoint< TModelUnit > TModelPoint
Definition: gltypes.hpp:51
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
virtual void PushMatrix()=0
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
CRgbaColor ContrastingColor(bool onlyBW=true) const
Return a color guaranteed to contrast nicely with this color.
void Darken(float scale)
Definition: rgba_color.cpp:472
virtual void AddRow(const string &sContents="", unsigned colspan=2)=0
add a row with a cell, spanning across all columns
void SetAlpha(float r)
Definition: rgba_color.cpp:287
static CIRef< ITooltipFormatter > CreateTooltipFormatter(ETooltipFormatters)
factory for requested tooltip formatter creation
Definition: tooltip.cpp:40
void SetGreen(float r)
Definition: rgba_color.cpp:275
void Lighten(float scale)
Definition: rgba_color.cpp:463
static CRgbaColor Interpolate(const CRgbaColor &color1, const CRgbaColor &color2, float alpha)
Interpolate two colors.
Definition: rgba_color.cpp:444
void SetBlue(float r)
Definition: rgba_color.cpp:281
@ eTooltipFormatter_CSSTable
generated table is CSS based, generated NCBI URLs are paths (recommended for SViewer)
Definition: tooltip.hpp:59
@ eContentAndProduct
Definition: label.hpp:71
@ eContent
Definition: label.hpp:62
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...
const CSeq_feat & GetMappedFeature(void) const
Feature mapped to the master sequence.
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:773
position_type GetLength(void) const
Definition: range.hpp:158
bool NotEmpty(void) const
Definition: range.hpp:152
position_type GetToOpen(void) const
Definition: range.hpp:138
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
static string SizetToString(size_t value, TNumToStringFlags flags=0, int base=10)
Convert size_t to string.
Definition: ncbistr.cpp:2751
#define kEmptyStr
Definition: ncbistr.hpp:123
static string LongToString(long value, TNumToStringFlags flags=0, int base=10)
Convert Int to string.
Definition: ncbistr.hpp:5140
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3310
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 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
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
@ eNa_strand_both_rev
in reverse orientation
Definition: Na_strand_.hpp:69
@ eNa_strand_both
in forward orientation
Definition: Na_strand_.hpp:68
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
n background color
int i
if(yy_accept[yy_current_state])
static void text(MDB_val *v)
Definition: mdb_dump.c:62
range(_Ty, _Ty) -> range< _Ty >
const struct ncbi::grid::netcache::search::fields::SIZE size
#define fabs(v)
Definition: ncbi_dispd.c:46
EIPRangeType t
Definition: ncbi_localip.c:101
T max(T x_, T y_)
T bound(T x_, T xlo_, T xhi_)
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 unsigned cnt[256]
#define _ASSERT
Modified on Tue Nov 28 02:29:15 2023 by modify_doxy.py rev. 669887