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

Go to the SVN repository for this file.

1 /* $Id: clone_placement_glyph.cpp 47194 2022-10-25 23:28:59Z evgeniev $
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: Mike DiCuccio, Liangshou Wu
27  *
28  * File Description:
29  * CClonePlacementGlyph -- utility class to arrange CSeq_feat objects in hierarchical
30  * (tree) order.
31  */
32 
33 #include <ncbi_pch.hpp>
36 #include <gui/opengl/irender.hpp>
39 #include <gui/objutils/tooltip.hpp>
40 #include <objmgr/util/sequence.hpp>
45 #include <math.h>
46 
49 
50 /// vertical space between elements.
51 static const int kVertSpace = 2;
52 static const int kHorzSpace = 3;
53 
54 //
55 // CClonePlacementGlyph::CClonePlacementGlyph()
56 //
58  : m_Feature(f)
59  , m_Location(&f.GetLocation())
60  , m_HideLabel(false)
61 {}
62 
64  : m_Feature(f)
65  , m_Location(&loc)
66  , m_HideLabel(false)
67 {}
68 
69 
70 bool CClonePlacementGlyph::NeedTooltip(const TModelPoint& /*p*/, ITooltipFormatter& /*tt*/, string& /*t_title*/) const
71 {
72  return true;
73 }
74 
75 
76 void CClonePlacementGlyph::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
77 {
78  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
79  SConstScopedObject scoped_obj(&GetMappedFeature().GetMappedFeature(), &scope);
80  CIRef<IGuiObjectInfo> gui_info(
81  CreateObjectInterface<IGuiObjectInfo>(scoped_obj, NULL));
82 
83  if ( !gui_info ) return;
84 
85  CGuiObjectInfoSeq_feat* gui_info_feat =
86  dynamic_cast<CGuiObjectInfoSeq_feat*>(gui_info.GetPointer());
87  if (gui_info_feat) {
88  gui_info_feat->SetLocation(*m_Location);
89  }
90 
91  TSeqPos at_p = (TSeqPos)-1;
92  if (p.X() >= 0) {
93  at_p = (TSeqPos)p.X();
94  }
95 
96  gui_info->GetToolTip(tt, t_title, at_p);
97  gui_info->GetLinks(tt, false);
98 }
99 
100 
102 {
103  CHTMLActiveArea area;
105  area.m_Bounds.SetTop(area.m_Bounds.Top() + 2);
106  area.m_Signature = GetSignature();
107  p_areas->push_back(area);
108 }
109 
110 
112 {
114  try { // watch out for mix loc with multiple seq-ids
115  range = m_Location->GetTotalRange();
116  } catch (CException&) {
117  // get range from intervals
119  range.CombineWith(*it);
120  }
121  }
122  return range;
123 }
124 
125 
127 {
128  return true;
129 }
130 
132 {
133  m_HideLabel = b;
134 }
135 
136 
138 {
140 }
141 
142 
143 
144 const objects::CSeq_loc& CClonePlacementGlyph::GetLocation(void) const
145 {
146  return *m_Location;
147 }
148 
149 
151 {
152  return CConstRef<CObject>(&m_Feature.GetOriginalFeature());
153 }
154 
155 
157 {
158  objs.push_back( CConstRef<CObject>(&m_Feature.GetOriginalFeature()) );
159 }
160 
161 
163 {
164  return &m_Feature.GetOriginalFeature() == obj.GetPointer();
165 }
166 
167 
169 {
172  GetLocation(), &m_Context->GetScope(), m_Feature.GetAnnot());
173 }
174 
175 
177 {
178  return m_Intervals;
179 }
180 
181 
183 {
184  string label = kEmptyStr;
185  const CSeqFeatData& data = GetFeature().GetData();
186  if (data.IsUser()) {
187  const CUser_object& user = data.GetUser();
188  if (user.HasField("name")) {
189  label = user.GetField("name").GetData().GetStr();
190  }
191  }
192 
193  if (label.empty()) {
195  &m_Context->GetScope());
196  }
197 
198  return label;
199 }
200 
201 
202 GLubyte dense_vert_lines[] = {
203  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
204  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
205  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
206  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
207  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
208  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
209  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
210  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
211  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
212  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
213  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
214  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
215  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
216  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
217  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
218  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc
219 };
220 
221 
222 GLubyte dense_horz_lines[] = {
223  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
224  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
225  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
226  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
227  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
228  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
229  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
230  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
231  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
232  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
233  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
234  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
235  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
236  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
237  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
238  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
239 };
240 
241 
242 GLubyte no_fill[] = {
243  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
259 };
260 
261 
262 GLubyte dense_diag_lines[] = {
263  0x00, 0x7f, 0xff, 0x00, 0x00, 0x3f, 0xff, 0x80,
264  0x00, 0x1f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xe0,
265  0x00, 0x07, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xf8,
266  0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xfe,
267  0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x3f, 0xff,
268  0xc0, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x0f, 0xff,
269  0xf0, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x03, 0xff,
270  0xfc, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0xff,
271  0xff, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x3f,
272  0xff, 0xc0, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x0f,
273  0xff, 0xf0, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x03,
274  0xff, 0xfc, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00,
275  0x7f, 0xff, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00,
276  0x1f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xe0, 0x00,
277  0x07, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xf8, 0x00,
278  0x01, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xfe, 0x00
279 };
280 
281 GLubyte dense_vert_lines2[] = {
282  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
283  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
284  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
285  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
286  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
287  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
288  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
289  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
290  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
291  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
292  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
293  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
294  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
295  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
296  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
297  0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33
298 };
299 
300 GLubyte dense_vert_lines3[] = {
301  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
302  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
303  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
304  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
305  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
306  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
307  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
308  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
309  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
310  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
311  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
312  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
313  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
314  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
315  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff,
316  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff
317 };
318 
320 {
321  if (GetHeight() == 0) {
322  return;
323  }
324 
326 
327  IRender& gl = GetGl();
328 
329  TModelUnit bar_h = 0.0, head_h = 0.0;
330  x_GetBarSize(bar_h, head_h);
331 
332  TModelUnit base = GetBottom();
333  TModelUnit line_center = base - head_h * 0.5f;
334  TModelUnit line_b = line_center + bar_h * 0.5;
335  TModelUnit line_t = line_center - bar_h * 0.5;
336 
337  TCloneEnds clone_ends;
338  TCloneEnds prototype_ends;
339  // support type for all other non-prototype ends
341  x_GetCloneEnds(clone_ends, prototype_ends);
342 
343  EConcordancy concordancy = eCCNotSet;
344  EUniqueness unique = eUniqueNotSet;
346  const CSeqFeatData& data = GetFeature().GetData();
347  if (data.IsClone()) {
348  const CSeqFeatData::TClone& clone = data.GetClone();
349  if (clone.IsSetConcordant()) {
350  concordancy = clone.GetConcordant() ? eConcordant : eDiscordant;
351  }
352  if (clone.IsSetUnique()) {
353  unique = clone.GetUnique() ? eUnique : eMultiple;
354  }
355  if (clone.IsSetPlacement_method()) {
356  placement = clone.GetPlacement_method();
357  }
358  } else if (data.IsUser()) { // old clone feature stored as user_type
359  const CUser_object& user = data.GetUser();
360  CConstRef<CUser_field> user_field = user.GetFieldRef("concordant");
361  if (user_field) {
362  concordancy = user_field->GetData().GetBool() ? eConcordant : eDiscordant;
363  }
364  }
365 
367  if (concordancy == eConcordant) {
368  base_color = m_Config->m_ConcordantColor;
369  } else if (concordancy == eDiscordant){
370  base_color = m_Config->m_DiscordantColor;
371  }
372 
373  TSeqRange total_range = x_GetTotalRange();
374  TModelUnit pix_size = m_Context->ScreenToSeq(1.0);
375  CRgbaColor boundary_color = base_color;
376  boundary_color.Darken(0.3f);
377 
378  CRgbaColor combined_plmt_color = m_Config->m_CombinedPlacementColor;
379 
380  // draw highlighting background for some
381  CRgbaColor highlight_color = m_Config->m_HighlightColor;
382  highlight_color.SetAlpha(0.3f);
384  eNonsupporting == non_prototype_st ||
385  eMixed == non_prototype_st)
386  {
387  TModelUnit padding_y = 1.0;
388  TModelUnit padding_x = padding_y * pix_size;
389 
391  if (eNonsupporting == non_prototype_st || eMixed == non_prototype_st) {
392  gl.ColorC(highlight_color);
393  m_Context->DrawQuad(GetLeft() - padding_x, GetTop() - padding_y, GetRight() + padding_x, GetBottom() + padding_y);
394  gl.Enable(GL_POLYGON_STIPPLE);
396  }
397  gl.ColorC(combined_plmt_color);
398  }
399  else {
400  gl.ColorC(highlight_color);
401  }
402 
403  m_Context->DrawQuad(GetLeft() - padding_x, GetTop() - padding_y, GetRight() + padding_x, GetBottom() + padding_y);
404  gl.Disable(GL_POLYGON_STIPPLE);
405  }
406 
407 
408  if (total_range.GetLength() < pix_size) { // less than a pixel size
409  m_Context->Draw3DQuad(total_range.GetFrom(), line_t,
410  total_range.GetTo(), line_b, base_color);
411  } else {
412  TModelUnit size = head_h * 0.5;
413  TModelUnit head_len = m_Context->ScreenToSeq(size);
414 
415  // draw connection line
416  if (prototype_ends.size() == 2) {
417  if (unique == eMultiple) {
419  gl.Enable(GL_POLYGON_STIPPLE);
420  } else if (unique == eUniqueNotSet) {
422  gl.Enable(GL_POLYGON_STIPPLE);
423  }
424  gl.ColorC(boundary_color);
425  TModelUnit x1 = prototype_ends[0].m_Range.GetToOpen();
426  TModelUnit x2 = prototype_ends[1].m_Range.GetFrom();
427  if (prototype_ends[0].m_Strand == eNegative &&
428  head_len > prototype_ends[0].m_Range.GetLength()) {
429  x1 = prototype_ends[0].m_Range.GetFrom() + head_len;
430  }
431  if (prototype_ends[1].m_Strand == ePositive &&
432  head_len > prototype_ends[1].m_Range.GetLength()) {
433  x2 = prototype_ends[1].m_Range.GetToOpen() - head_len;
434  }
435 
436  m_Context->DrawQuad(x1, line_center - 1, x2, line_center + 1);
437  gl.Disable(GL_POLYGON_STIPPLE);
438  }
439 
440  // draw the clone ends
441  ITERATE (TCloneEnds, iter, prototype_ends) {
442  TModelUnit from = iter->m_Range.GetFrom();
443  TModelUnit to = iter->m_Range.GetToOpen();
444 
445  CGlAttrGuard AttrGuard(GL_LINE_BIT);
446  gl.Disable(GL_LINE_SMOOTH);
447 
448  EUniqueness end_uniqueness = iter->m_Uniqueness;
449  if (((CClone_ref_Base::ePlacement_method_end_seq != placement) || end_uniqueness == eUniqueNotSet) && prototype_ends.size() == 1) {
450  end_uniqueness = unique;
451  }
452 
453  gl.ColorC(base_color);
454  x_SetPolygonStipple(end_uniqueness);
455 
456  gl.ShadeModel(GL_SMOOTH);
457  if (iter->m_Strand == eStrandNotSet) {
458  m_Context->DrawQuad(from, line_b, to, line_t);
459  gl.ColorC(boundary_color);
460  m_Context->DrawRect(from, line_b, to, line_t);
461  } else {
462  bool forward = iter->m_Strand == ePositive;
463  TModelUnit x3 = forward ? to : from;
464  TModelUnit x2 = x3 - (forward ? head_len : -head_len);
465  TModelUnit x1 = forward ? from : to;
466  if (iter->m_Range.GetLength() < head_len) {
467  x1 = x2;
468  }
469 
470  m_Context->DrawArrow(x1, x2, x3, line_center,
471  - (forward ? 0.5 : -0.5) * bar_h,
472  - (forward ? 0.5 : -0.5) * head_h);
473  gl.ColorC(boundary_color);
474  m_Context->DrawArrowBoundary(x1, x2, x3, line_center,
475  0.5 * bar_h, 0.5 * head_h);
476  }
477  gl.ShadeModel(GL_FLAT);
478  gl.Disable(GL_POLYGON_STIPPLE);
479  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
480  }
481 
482  }
483 
484  // draw label
485  if (x_ShowLabel()) {
486  string label = GetLabel();
487  const CGlTextureFont& font = m_Config->m_LabelFont;
488  TModelUnit label_w = gl.TextWidth(&font, label.c_str());
491  // top label
492  TModelUnit widthP = m_Context->SeqToScreen(r.GetLength());
493  if (label_w > widthP) {
494  label = font.Truncate(label.c_str(), widthP);
495  }
496 
497  if (IsSelected()) {
499  } else {
501  }
502 
503  TModelUnit xM = (r.GetFrom() + r.GetTo()) * 0.5;
504  TModelUnit yM = line_center - kVertSpace * 2;
505  if (clone_ends.size() == 1) {
506  yM = base - head_h;
507  } else {
508  TModelRange in_range((TModelUnit)clone_ends[0].m_Range.GetToOpen(),
509  (TModelUnit)clone_ends[1].m_Range.GetFrom());
510  in_range = m_Context->IntersectVisible(in_range);
511  if (label_w > m_Context->SeqToScreen(in_range.GetLength())) {
512  yM = base - head_h;
513  } else {
514  xM = (in_range.GetFrom() + in_range.GetTo() ) * 0.5;
515  }
516  }
517  m_Context->TextOut(&font, label.c_str(), xM, yM, true);
518  } else { // side label
519  TModelUnit max_w = m_Context->GetMaxLabelWidth(font);
520  if (label_w > max_w) {
521  label_w = max_w;
522  label = font.Truncate(label.c_str(), label_w);
523  }
524  label_w = m_Context->ScreenToSeq(label_w);
525  if (r.GetLength() < label_w) {
526  return;
527  }
528 
529  TModelUnit label_b = line_center + gl.TextHeight(&font) * 0.5;
530  if (GetLeft() < 0) {
531  label_b = GetTop() + 1 + gl.TextHeight(&font);
532  }
533 
534  TModelUnit label_x = r.GetFrom();
535  if (r.GetFrom() > GetLeft()) {
536  gl.Color3f(1.0f, 1.0f, 1.0f);
538  TModelRect(label_x, label_b + 1, label_x + label_w,
539  label_b - gl.TextHeight(&font) - 1), 0);
540  }
541 
542  gl.ColorC(IsSelected() ?
544  m_Context->TextOut(&font, label.c_str(), label_x,
545  label_b - 1.0, false, true);
546  }
547  }
548 
549  if (IsSelected()) {
550  TModelRect rcm = GetModelRect();
551  m_Context->DrawSelection(rcm);
552  }
553 }
554 
555 // The grey highlight is used if seq-ids in non - supporting or supports - other are different than seq - ids in prototype OR supporting.
557 {
559 
560  const CSeqFeatData& data = GetFeature().GetData();
561  if (!data.IsClone())
562  return result;
563 
564  const CSeqFeatData::TClone& clone = data.GetClone();
565  if (!clone.CanGetClone_seq())
566  return result;
567 
568  TStrSet supporting;
569  typedef map<int, TStrVector> TEndMap;
570  TEndMap end_map;
571  const CClone_ref::TClone_seq::Tdata& ends = clone.GetClone_seq().Get();
572  ITERATE(CClone_ref::TClone_seq::Tdata, e_iter, ends) {
573  const CClone_seq& seq = **e_iter;
574  if (!seq.CanGetSeq() || !seq.CanGetSupport())
575  continue;
576 
577  const CSeq_id* id = seq.GetSeq().GetId();
578  if (!id)
579  continue;
580 
582  supporting.insert(id->GetSeqIdString(true));
583  continue;
584  }
585 
586  end_map[seq.GetSupport()].push_back(id->GetSeqIdString(true));
587  }
588 
589  if (end_map.count(CClone_seq::eSupport_non_supporting) > 0) {
590  if (!x_MatchIds(supporting, end_map[CClone_seq::eSupport_non_supporting]))
592  }
593 
594  if (end_map.count(CClone_seq::eSupport_supports_other) > 0) {
595  if (!x_MatchIds(supporting, end_map[CClone_seq::eSupport_supports_other]))
597  }
598 
599  return result;
600 }
601 
602 bool CClonePlacementGlyph::x_MatchIds(const TStrSet &supportingIds, const TStrVector &nonSupportingIds) const
603 {
604  TStrVector::const_iterator itId;
605  for (itId = nonSupportingIds.begin(); itId != nonSupportingIds.end(); ++itId) {
606  if (supportingIds.count(*itId) == 0)
607  return false;
608  }
609  return true;
610 }
611 
613 {
614  IRender& gl = GetGl();
615 
616  switch (uniqueness) {
617  case eVirtual:
618  gl.Enable(GL_POLYGON_STIPPLE);
620  break;
621  case eMultiple:
622  gl.Enable(GL_POLYGON_STIPPLE);
624  break;
625  case eUniqueNotSet:
626  gl.Enable(GL_POLYGON_STIPPLE);
628  break;
629  default:
630  break;
631  }
632 }
633 
635 {
637 
638  IRender& gl = GetGl();
639 
640  TModelUnit bar_h = 0.0, head_h = 0.0;
641  x_GetBarSize(bar_h, head_h);
642 
643  TSeqRange total_range = x_GetTotalRange();
644  SetHeight(head_h);
645  SetWidth(total_range.GetLength());
646  SetLeft(total_range.GetFrom());
647 
648  TCloneEnds clone_ends;
649  TCloneEnds prototype_ends;
650  // support type for all other non-prototype ends
651  x_GetCloneEnds(clone_ends, prototype_ends);
652 
653  // in case the triangle's screen size is larger than the
654  // is clone's start end size (screen size) and the end strand
655  // is forward, we need to add an extra space to avoid overlapping
656  if (prototype_ends[0].m_Strand == ePositive) {
657  TSeqPos end_len = prototype_ends[0].m_Range.GetLength();
658  TModelUnit extra_space =
659  m_Context->ScreenToSeq(head_h * 0.5) - end_len;
660  if (extra_space > 0) {
661  SetWidth(GetWidth() + extra_space);
662  SetLeft(GetLeft() - extra_space);
663  }
664  }
665  size_t end_num = prototype_ends.size();
666  if (end_num > 1 && prototype_ends[end_num - 1].m_Strand == eNegative) {
667  TSeqPos end_len = prototype_ends[end_num - 1].m_Range.GetLength();
668  TModelUnit extra_space =
669  m_Context->ScreenToSeq(head_h * 0.5) - end_len;
670  if (extra_space > 0) {
671  SetWidth(GetWidth() + extra_space);
672  }
673  }
674 
675  if ( !x_ShowLabel() ) {
677  return;
678  }
679 
680  string label = GetLabel();
681  const CGlTextureFont& font = m_Config->m_LabelFont;
682 
684  // top label, preserve label vertical space
685  if (prototype_ends.size() == 2) {
686  TModelUnit text_w =
687  m_Context->ScreenToSeq(gl.TextWidth(&font, label.c_str()));
688 
689  TModelRange in_range((TModelUnit)prototype_ends[0].m_Range.GetToOpen(),
690  (TModelUnit)prototype_ends[1].m_Range.GetFrom());
691  in_range = m_Context->IntersectVisible(in_range);
692  if (text_w < in_range.GetLength()) {
693  SetHeight(GetHeight() + gl.TextHeight(&font) +
694  kVertSpace * 2 - GetHeight() * 0.5);
695  } else {
696  SetHeight(GetHeight() + gl.TextHeight(&font));
697  }
698  } else {
699  SetHeight(GetHeight() + gl.TextHeight(&font));
700  }
701  } else { // side label
702  TModelUnit text_w =
703  min(gl.TextWidth(&font, label.c_str()), m_Context->GetMaxLabelWidth(font));
704  text_w = m_Context->ScreenToSeq(text_w + kHorzSpace);
705  SetWidth(GetWidth() + text_w);
706  SetLeft(GetLeft() - text_w);
707 
708  TModelRange vis_r = m_Context->IntersectVisible(this);
709 
710  if (GetLeft() < 0 && vis_r.GetLength() >= text_w) {
711  // can't fit, move label above the bar
712  SetHeight(GetHeight() + gl.TextHeight(&font) + kVertSpace + 1);
713  }
714  }
715 }
716 
717 
719 {
720  bool shown = false;
723  shown = !m_HideLabel;
724  } else { // can be either ePos_Above or ePos_Inside
726  if (m_Context->WillLabelFit(r)) {
727  shown = !m_HideLabel || IsSelected();
728  }
729  }
730  }
731 
732  return shown;
733 }
734 
735 
737 {
738  return GetLocation().GetTotalRange();
739 }
740 
741 
743  TCloneEnds& prototype_ends) const
744 {
745  const CSeq_id* main_id = GetLocation().GetId();
746  const CSeqFeatData& data = GetFeature().GetData();
747  if (data.IsClone()) {
748  const CSeqFeatData::TClone& clone = data.GetClone();
749  if (clone.IsSetClone_seq()) {
750  const CClone_ref::TClone_seq::Tdata& ends = clone.GetClone_seq().Get();
751  ITERATE (CClone_ref::TClone_seq::Tdata, e_iter, ends) {
752  const CClone_seq& seq = **e_iter;
753 
754  if (!main_id->Match(*seq.GetLocation().GetId()))
755  continue;
756 
757  SCloneEnd end;
758  end.m_Range = seq.GetLocation().GetTotalRange();
759  if (seq.GetLocation().IsSetStrand()) {
760  end.m_Strand =
762  } else if (seq.CanGetSeq() && seq.GetSeq().IsSetStrand()) {
763  end.m_Strand =
765  }
766  // check if there is any fake end
767  if (seq.IsSetConfidence()) {
768  switch (seq.GetConfidence()) {
770  end.m_Uniqueness = eVirtual;
771  break;
773  end.m_Uniqueness = eUnique;
774  break;
776  end.m_Uniqueness = eMultiple;
777  break;
778  default:
779  break;
780  }
781  }
782 
783  clone_ends.push_back(end);
784 
785  if (!seq.CanGetSupport())
786  continue;
787 
789  prototype_ends.push_back(end);
790  continue;
791  }
792  }
793  }
794  }
795 
796  // in case of no clone end or it is user type feature
797  if (clone_ends.empty()) {
798  CSeq_loc_CI loc_it(GetLocation());
799  size_t num_loc = 0;
800  for (; loc_it && num_loc < 2; ++loc_it, ++num_loc) {
801  SCloneEnd end;
802  end.m_Range = loc_it.GetRange();
803  if (loc_it.IsSetStrand()) {
804  end.m_Strand = loc_it.GetStrand() == eNa_strand_minus ? eNegative : ePositive;
805  }
806  clone_ends.push_back(end);
807  prototype_ends.push_back(end);
808  }
809  }
810 
811  if (!clone_ends.empty() && data.IsUser()) { // old clone feature stored as user_type
812  const CUser_object& user = data.GetUser();
813  if (user.HasField("end1_fake") &&
814  user.GetField("end1_fake").GetData().GetBool()) {
815  clone_ends[0].m_Uniqueness = eVirtual;
816  }
817  if (clone_ends.size() > 1 && user.HasField("end2_fake") &&
818  user.GetField("end2_fake").GetData().GetBool()) {
819  clone_ends[1].m_Uniqueness = eVirtual;
820  }
821  }
822 
823  if (prototype_ends.empty()) {
824  // if there are no prototype ends, use the feature range as "virtual" prototype ends
825  CSeq_loc_CI loc_it(GetLocation());
826  size_t num_loc = 0;
827  for (; loc_it && num_loc < 2; ++loc_it, ++num_loc) {
828  SCloneEnd end;
829  end.m_Range = loc_it.GetRange();
830  if (loc_it.IsSetStrand()) {
831  end.m_Strand = loc_it.GetStrand() == eNa_strand_minus ? eNegative : ePositive;
832  }
833  prototype_ends.push_back(end);
834  }
835  }
836 }
837 
838 
840  TModelUnit& head_h) const
841 {
842  bar_h = m_Config->m_BarHeight;
843  head_h = m_Config->m_HeadHeight;
845  bar_h = floor(bar_h * m_Config->m_OverviewFactor);
846  head_h = floor(head_h * m_Config->m_OverviewFactor);
847  }
848 }
849 
850 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
CClonePlacementGlyph(const objects::CMappedFeat &feat)
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
Retrieve the feature as an object.
virtual bool NeedTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Check if need to show tooltip.
virtual string GetSignature() const
return signature for this glyph.
CConstRef< CClonePlacementParams > m_Config
All the configs needed for rendering a feature.
virtual void SetHideLabel(bool b)
Force to hide label.
const objects::CSeq_feat & GetFeature(void) const
Access the original feature.
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
void x_GetCloneEnds(TCloneEnds &clone_ends, TCloneEnds &prototype_ends) const
virtual bool IsClickable() const
Query if this glyph is clickable.
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
virtual TSeqRange GetRange(void) const
get the total range of this object.
objects::CMappedFeat m_Feature
we store a mapped feature object which in turn holds the original feature.
virtual void x_Draw() const
The default renderer for this layout object.
virtual const TIntervals & GetIntervals(void) const
access sub-intervals (if any).
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
CConstRef< objects::CSeq_loc > m_Location
Mapped location in top sequence coordinate.
void x_SetPolygonStipple(EUniqueness uniqueness) const
void x_GetBarSize(TModelUnit &bar_h, TModelUnit &head_h) const
bool x_MatchIds(const TStrSet &supportingIds, const TStrVector &nonSupportingIds) const
const objects::CMappedFeat & GetMappedFeature(void) const
Access a new, fully remapped feature.
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
TSeqRange x_GetTotalRange() const
virtual bool HasSideLabel() const
Query if there is label and label is on the side.
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
bool m_HideLabel
Force to hide the label.
vector< SCloneEnd > TCloneEnds
TIntervals m_Intervals
intervals (like for features or alignments).
ESupportType x_GetSupportTypeForNonPrototypeEnds() const
CGlTextureFont m_LabelFont
CRgbaColor m_UnknownConcordancyColor
TModelUnit m_HeadHeight
absolute size (in pixel)
CRgbaColor m_CombinedPlacementColor
TModelUnit m_OverviewFactor
ratio to bar height
CRgbaColor m_ConcordantColor
TLabelPosition m_LabelPos
CRgbaColor m_DiscordantColor
TModelUnit m_BarHeight
absolute size (in pixel)
CClone_ref –.
Definition: Clone_ref.hpp:66
CClone_seq –.
Definition: Clone_seq.hpp:66
@ ePos_NoLabel
no label
@ ePos_Side
always on 5' side
@ ePos_Above
above the rendered bar
CGlAttrGuard - guard class for restoring OpenGL attributes.
Definition: glutils.hpp:130
CMappedFeat –.
Definition: mapped_feat.hpp:59
static string GetFeatSignature(const objects::CSeq_feat &feat, objects::CScope *scope, const string &data_source="", const string &sAdditionalInfo="")
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
void DrawArrowBoundary(TModelUnit x1, TModelUnit x2, TModelUnit x3, TModelUnit line_center, TModelUnit bar_h, TModelUnit head_h) const
TModelRange IntersectVisible(const CSeqGlyph *obj) const
void DrawArrow(TModelUnit x1, TModelUnit x2, TModelUnit x3, TModelUnit line_center, TModelUnit bar_h, TModelUnit head_h) const
void DrawRect(const TModelRect &rc) const
objects::CScope & GetScope()
void DrawQuad(const TModelRect &rc, bool border=false) const
void DrawSelection(const TModelRect &rc) 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
bool IsOverviewMode() const
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
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CScope –.
Definition: scope.hpp:92
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 SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
virtual TModelUnit GetRight() const
Definition: seq_glyph.hpp:603
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 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
virtual TModelUnit GetBottom() const
Definition: seq_glyph.hpp:607
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:453
CConstRef< CUser_field > GetFieldRef(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Definition: User_object.cpp:84
bool HasField(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Verify that a named field exists.
const CUser_field & GetField(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Access a named field in this user object.
Definition: User_object.cpp:71
vector< TSeqRange > TIntervals
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
GLubyte no_fill[]
USING_SCOPE(objects)
static const int kHorzSpace
static const int kVertSpace
vertical space between elements.
GLubyte dense_vert_lines[]
GLubyte dense_diag_lines[]
GLubyte dense_horz_lines[]
GLubyte dense_vert_lines3[]
GLubyte dense_vert_lines2[]
#define false
Definition: bool.h:36
static FILE * f
Definition: readconf.c:23
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 NULL
Definition: ncbistd.hpp:225
GLdouble TModelUnit
Definition: gltypes.hpp:48
T X() const
Definition: glpoint.hpp:59
virtual void Enable(GLenum glstate)=0
T Top() const
Definition: glrect.hpp:84
void Color3f(GLfloat r, GLfloat g, GLfloat b)
Definition: irender.hpp:95
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 ShadeModel(GLenum mode)=0
Set shade model for default lighting: glShadeModel(GL_FLAT or GL_SMOOTH)
virtual void PolygonMode(GLenum face, GLenum mode)=0
Set the polygon rasterization mode.
virtual void PolygonStipple(GLubyte *mask)=0
Set polygon stipple pattern: glPolygonStipple(). Deprecated in gl 3.2+.
CGlRect< TModelUnit > TModelRect
Definition: gltypes.hpp:54
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void SetTop(T top)
Definition: glrect.hpp:115
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
static void GetLabel(const CObject &obj, string *label, ELabelType type=eDefault)
Definition: label.cpp:140
void Darken(float scale)
Definition: rgba_color.cpp:472
void SetLocation(const objects::CSeq_loc &loc)
void SetAlpha(float r)
Definition: rgba_color.cpp:287
@ eContent
Definition: label.hpp:62
string GetSeqIdString(bool with_version=false) const
Return seqid string with optional version for text seqid type.
Definition: Seq_id.cpp:2145
bool Match(const CSeq_id &sid2) const
Match() - TRUE if SeqIds are equivalent.
Definition: Seq_id.hpp:1065
ENa_strand GetStrand(void) const
Get the location's strand.
Definition: Seq_loc.cpp:882
TRange GetTotalRange(void) const
Definition: Seq_loc.hpp:913
bool IsSetStrand(void) const
Get strand.
Definition: Seq_loc.hpp:1049
bool IsSetStrand(EIsSetStrand flag=eIsSetStrand_Any) const
Check if strand is set for any/all part(s) of the seq-loc depending on the flag.
Definition: Seq_loc.cpp:858
const CSeq_id * GetId(void) const
Get the id of the location return NULL if has multiple ids or no id at all.
Definition: Seq_loc.hpp:941
TRange GetRange(void) const
Get the range.
Definition: Seq_loc.hpp:1042
ENa_strand GetStrand(void) const
Definition: Seq_loc.hpp:1056
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
position_type GetLength(void) const
Definition: range.hpp:158
#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 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
const TStr & GetStr(void) const
Get the variant data.
const TData & GetData(void) const
Get the Data member data.
TBool GetBool(void) const
Get the variant data.
TConcordant GetConcordant(void) const
Get the Concordant member data.
Definition: Clone_ref_.hpp:512
bool CanGetClone_seq(void) const
Check if it is safe to call GetClone_seq method.
Definition: Clone_ref_.hpp:640
bool IsSetUnique(void) const
OPTIONAL? Check if a value has been assigned to Unique data member.
Definition: Clone_ref_.hpp:537
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Clone_seq_.hpp:504
bool IsSetConcordant(void) const
OPTIONAL? Check if a value has been assigned to Concordant data member.
Definition: Clone_ref_.hpp:487
bool CanGetSeq(void) const
Check if it is safe to call GetSeq method.
Definition: Clone_seq_.hpp:528
bool IsSetConfidence(void) const
Check if a value has been assigned to Confidence data member.
Definition: Clone_seq_.hpp:445
list< CRef< CClone_seq > > Tdata
TConfidence GetConfidence(void) const
Get the Confidence member data.
Definition: Clone_seq_.hpp:464
TSupport GetSupport(void) const
Get the Support member data.
Definition: Clone_seq_.hpp:583
bool IsSetPlacement_method(void) const
Check if a value has been assigned to Placement_method data member.
Definition: Clone_ref_.hpp:587
TUnique GetUnique(void) const
Get the Unique member data.
Definition: Clone_ref_.hpp:562
const Tdata & Get(void) const
Get the member data.
const TClone_seq & GetClone_seq(void) const
Get the Clone_seq member data.
Definition: Clone_ref_.hpp:646
TPlacement_method GetPlacement_method(void) const
Get the Placement_method member data.
Definition: Clone_ref_.hpp:606
const TSeq & GetSeq(void) const
Get the Seq member data.
Definition: Clone_seq_.hpp:534
bool CanGetSupport(void) const
Check if it is safe to call GetSupport method.
Definition: Clone_seq_.hpp:570
bool IsSetClone_seq(void) const
Check if a value has been assigned to Clone_seq data member.
Definition: Clone_ref_.hpp:634
@ eConfidence_multiple
Multiple hits.
Definition: Clone_seq_.hpp:95
@ eConfidence_virtual
Virtual (hasn't been sequenced)
Definition: Clone_seq_.hpp:101
@ eSupport_supporting
sequence supports placement
Definition: Clone_seq_.hpp:113
@ eSupport_supports_other
supports a different placement
Definition: Clone_seq_.hpp:114
@ eSupport_prototype
sequence used to place clone
Definition: Clone_seq_.hpp:112
@ eSupport_non_supporting
does not support any placement
Definition: Clone_seq_.hpp:115
@ ePlacement_method_end_seq_insert_alignment
combined end-seq and insert align
Definition: Clone_ref_.hpp:98
@ ePlacement_method_end_seq
Clone placed by end sequence.
Definition: Clone_ref_.hpp:93
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
range(_Ty, _Ty) -> range< _Ty >
const struct ncbi::grid::netcache::search::fields::SIZE size
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define _ASSERT
else result
Definition: token2.c:20
Modified on Fri Sep 20 14:57:06 2024 by modify_doxy.py rev. 669887