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

Go to the SVN repository for this file.

1 /* $Id: ruler.cpp 47485 2023-05-02 14:46:59Z 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: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  */
31 
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbistd.hpp>
35 
36 #include <gui/opengl/glhelpers.hpp>
37 #include <gui/opengl/glresmgr.hpp>
38 #include <gui/opengl/irender.hpp>
39 #include <gui/opengl/glstate.hpp>
41 #include <gui/widgets/gl/ruler.hpp>
42 
43 #include <math.h>
44 
45 
47 
48 CRuler::CRuler(bool horz)
49 : m_Visible(true),
50  m_FontRotate(CGlTextureFont::fFontRotateBase),
51  m_FontRotateDegrees(0),
52  m_AutoRange(true),
53  m_BaseWidth(1),
54  m_BaseOffset(0.5),
55  m_DisplayOptions(fDefaultDisplayOptions),
56  m_Font(CGlTextureFont::eFontFace_Helvetica, 12),
57  m_TextColor(0.1f, 0.2f, 0.1f),
58  m_RulerColor(0.2f, 0.2f, 0.2f),
59  m_BackColor(0.95f, 0.95f, 0.95f),
60  m_MajorTickSize(6),
61  m_MinorTickSize(3),
62  m_LabelTickSize(6),
63  m_OppMajorTickSize(0),
64  m_OppMinorTickSize(0),
65  m_OppLabelTickSize(6),
66  m_Dirty(true),
67  m_ScaleX(0),
68  m_ScaleY(0),
69  m_MaxLabelW(0),
70  m_MaxLabelH(0),
71  m_BaseStep(0),
72  m_PosLabelsStep(-1),
73  m_TickSpace(0)
74 {
75  SetHorizontal(horz);
78 }
79 
80 
82 {
83 }
84 
85 
86 const static int kMinTickStepPixels = 5;
87 const static int kLabelSepPixX = 12; // min distance between labels
88 const static int kLabelSepPixY = 12; // min distance between labels
89 
90 
91 // change Ruler orientation
93 {
94  m_Horz = horz;
95 
96  if(m_Horz) {
97  switch(place) {
98  case eLeft:
99  case eRight: _ASSERT(false);
100  case eDefault:
101  case eBottom: m_LabelPlace = eBottom; break;
102  case eTop: m_LabelPlace = eTop; break;
103  }
104  } else {
105  switch(place) {
106  case eBottom:
107  case eTop: _ASSERT(false);
108  case eDefault:
109  case eLeft: m_LabelPlace = eLeft; break;
110  case eRight: m_LabelPlace = eRight; break;
111  }
112  }
113 
114  switch (aln) {
115  case eAln_Right:
116  case eAln_Top:
117  m_LabelAln = horz ? eAln_Right : eAln_Top;
118  break;
119  case eAln_Left:
120  case eAln_Bottom:
121  m_LabelAln = horz ? eAln_Left : eAln_Bottom;
122  break;
123  case eAln_Center:
124  default:
126  break;
127  }
128 
129  m_Dirty = true;
130 }
131 
132 
134 {
135  switch(type) {
136  case eRuler: m_RulerColor = color; break;
137  case eText: m_TextColor = color; break;
138  case eBackground: m_BackColor = color; break;
139  default: _ASSERT(false);
140  }
141  m_Dirty = true;
142 }
143 
144 
146  unsigned int font_size)
147 {
148  m_Font.SetFontFace(font_type);
149  m_Font.SetFontSize(font_size);
150 
151  m_Dirty = true;
152 }
153 
154 
156  int rotate_degrees)
157 {
160 
161  m_FontRotateDegrees = rotate_degrees;
162 }
163 
164 
165 void CRuler::SetDisplayOptions(int options)
166 {
167  m_DisplayOptions = options;
168 }
169 
170 
172 {
173  m_AutoRange = true;
174 }
175 
176 
177 // keep this functions for simplicity and backward compatibility
178 void CRuler::SetRange(int start, int end, int seq_start, bool reverse)
179 {
180  m_AutoRange = false;
181 
182  m_Mapping.clear();
183 
184  int len = end - start + 1;
185  TAlignRange range(start, seq_start, len, ! reverse);
187 }
188 
189 
191 {
192  m_AutoRange = false;
193  m_Mapping = coll;
194 }
195 
196 
197 void CRuler::SetTextLabel(const string& label)
198 {
199  m_TextLabel = label;
200 }
201 
202 
204 {
205  switch(geom) {
206  case eMinorTickHeight: m_MinorTickSize = value; break;
207  case eMajorTickHeight:
211  }
212  break;
213  case eLabelTickHeight: m_LabelTickSize = value; break;
215  case eOppMajorTickHeight:
219  }
220  break;
222  default: _ASSERT(false);
223  }
224 
225  m_Dirty = true;
226 }
227 
228 
229 /// spacing between text and borders or between text and other graphics
230 static int kTextSpaceX = 2;
231 static int kTextSpaceY = 2;
232 
233 
235 {
236  bool horz_text = (m_FontRotateDegrees == 0) ||
237  (m_FontRotateDegrees == 180);
238  return m_Horz == horz_text;
239 }
240 
241 /// Ruler contains two layers. The first layer displays the axis with Ticks and
242 /// optional Labels, the second displays Metric and Origin.
243 
244 /// Returns V size necessary for drawing axis ticks and labels.
245 /// V is the size in the direction normal to the axis
246 int CRuler::x_GetTicksLabelsSizeV(int max_num) const
247 {
248  IRender& gl = GetGl();
249 
250  int text_space = m_Horz ? kTextSpaceY : kTextSpaceX;
251  int v = m_MajorTickSize + m_OppMajorTickSize + text_space;
252  if((m_DisplayOptions & fHideLabels) == 0) {
253  double text_v = x_TextAlongAxis() ? gl.TextHeight(&m_Font) :
254  gl.GetMaxWidth(&m_Font, max_num);
255  if (m_LabelAln == eAln_Center) {
257  2 * text_space + (int) ceil(text_v);
258  } else {
259  v = m_LabelTickSize;
260  v += max(m_OppLabelTickSize, m_OppMajorTickSize + 3 * text_space + (int) ceil(text_v));
261  }
262  }
263 
264  return v;
265 }
266 
267 
269 {
270  int v = 0;
271 
272  IRender& gl = GetGl();
273 
275  // metric and origin text is always dispalyed along the axis
276  int text_v = (int) ceil(gl.TextHeight(&m_Font));
277  int text_space = m_Horz ? kTextSpaceY : kTextSpaceX;
278 
279  v = max(text_v, m_MajorTickSize) + text_space * 2;
280  }
281  return v;
282 }
283 
284 
285 // "max_num" - is the biggest number that needs to be represented by the ruler
287 {
288  int text_v = x_GetTicksLabelsSizeV(max_num);
289  int metric_v = x_GetOriginMetricSizeV();
290  int v = text_v + metric_v;
291  return m_Horz ? TVPPoint(0, v) : TVPPoint(v, 0);
292 }
293 
294 
296 {
297  TVPPoint pt = GetPreferredSize(0);
298  return TVPRect(0, 0, pt.X(), pt.Y());
299 }
300 
301 
303 {
304  // do nothing
305 }
306 
307 
309 {
310  return TModelRect();
311 }
312 
313 
315 {
316  _ASSERT(false); // not supported
317 }
318 
319 
321 {
322  return TVPPoint(0, 0);
323 }
324 
325 
327 {
328  return m_Visible;
329 }
330 
331 
333 {
334  m_Visible = set;
335 }
336 
337 
338 bool CRuler::NeedTooltip(CGlPane& /*pane*/, TVPUnit /*vp_x*/, TVPUnit /*vp_y*/)
339 {
340  return false;
341 }
342 
343 
345 {
346  return "Error";
347 }
348 
349 
350 // returns the maximal absolute number (having maximum number of digits) that needs
351 // to be displayed on the Ruler.
352 // This number can be used to deterime how much space do we need for displaying labels
354 {
355  int total_max = 0;
357  const TAlignRange& r = *it;
358  int mod_start = abs(x_ToDisplay(r, r.GetFirstFrom()));
359  int mod_end = abs(x_ToDisplay(r, r.GetFirstTo()));
360  int max_int = max(mod_start, mod_end);
361  total_max = max(total_max, max_int);
362  }
363  return total_max;
364 }
365 
366 
367 // calculates distance in pixels between position labels
369 {
370  IRender& gl = GetGl();
372 
373  // determining maximal number of characters in a label
374  int max_num = x_GetMaxNum();
375 
377  double comma_w = gl.TextWidth(&m_Font, ",");
378 
379  int sep_pix = m_Horz ? kLabelSepPixX : kLabelSepPixY;
380  m_MaxLabelW = sep_pix + (int) ceil(gl.GetMaxWidth(&m_Font, max_num));
381 
382  // calculate size of the longest label in model coords
383  double scale = m_Horz ? pane.GetScaleX() : pane.GetScaleY();
384  double max_label_sym = 0; // in symbols
385 
386  if(x_TextAlongAxis()) {
387  max_label_sym = scale * m_MaxLabelW;
388  } else {
389  max_label_sym = 2 * scale * m_MaxLabelH;
390  }
391 
392  // choosing step in model coords
393  double log = (max_label_sym >= 1.0) ? log10(max_label_sym) : 0;
394  log = ceil(log);
395  double step = pow((double)10, log) * m_BaseWidth;
396  double base_step = step;
397  if(step > 10.001) {
398  // try to mimimize step without intersecting labels
399  if(m_Horz) {
400  // adjusting order
401  int groups_n = 0;
402  step = step * 10; // to compensate effect of the first iteration
403  double max_label_w = m_MaxLabelW;
404  do
405  {
406  _ASSERT(step > 0);
407  step = step / 10;
408  log = ceil(log10(step));
409  groups_n = (int) (log / 3); // number of comma-separated groups (111,222,333)
410  if(groups_n) {
411  int d_digits = 3 * groups_n - 2;
412  max_label_w = m_MaxLabelW - d_digits * char_w + groups_n * comma_w;
413  max_label_sym = scale * max_label_w;
414  }
415  } while(groups_n && step > max_label_sym * 10);
416  m_MaxLabelW = max_label_w;
417  base_step = step;
418  }
419  // currently step has 10^X form, lets check if we can choose
420  // a smaller step in a form K * 10^(X-1), where K = 2, 5
421  // this adjusment does not affect labels size
422  if(step > max_label_sym * 5) {
423  base_step = step / 10; // 10^(X-1)
424  step = step / 5; // 2 * 10^(X-1)
425  }
426  else if(step > max_label_sym * 2) {
427  base_step = step / 10; // 10^(X-1)
428  step = step / 2; // 5 * 10^(X-1)
429  }
430  }
431 
432  m_BaseStep = (int) base_step;
433  m_BaseStep = max(m_BaseStep, 1);
434 
435  m_PosLabelsStep = (int) step;
437 
438  x_ChooseTickSpace(scale);
439 
440  m_Dirty = false;
441 }
442 
443 
444 // choosing optimal distance between ticks
445 void CRuler::x_ChooseTickSpace(double scale)
446 {
448  int ar_K[] = { 10, 5 ,2 };
449  for( int i = 0; i < 3; i++ ) {
450  int space = m_TickSpace / ar_K[i];
451  if(space >= 1 && space / scale > kMinTickStepPixels) {
452  m_TickSpace = space;
453  break;
454  }
455  }
456 }
457 
458 
459 // Renders the Ruler
461 {
462  if (!m_Visible)
463  return;
464 
465  if(m_AutoRange) {
466  x_UpdateMappingByPane(pane);
467  }
468  x_UpdatePosLabelsStep(pane);
469 
470  // clean background
471  CGlAttrGuard AttrGuard(GL_POLYGON_BIT | GL_LINE_BIT);
472 
473  IRender& gl = GetGl();
474 
475  if (gl.IsPrinterFriendly()) {
476  TVPRect viewport = pane.GetViewport();
477  gl.BeginClippingRect(viewport.Left(), viewport.Top(), viewport.Width(), viewport.Height());
478  }
479 
480  gl.LineWidth(1.0f);
481 
482  if(m_PosLabelsStep > 0) {
483  // step is valid - calculating range to draw
484  TModelRect rc_v = pane.GetVisibleRect();
485 
486  // [first_elem, last_elem] - is a range being rendered in model coords (clipping)
487  int first_elem = (int) floor(m_Horz ? rc_v.Left() : rc_v.Bottom());
488  int last_elem = (int) ceil(m_Horz ? rc_v.Right() : rc_v.Top()) -1;
489 
490  // find iterators that define the set of ranges that are visible
491  TAlignColl::const_iterator it_first = m_Mapping.find_2(first_elem).first;
492  pair<TAlignColl::const_iterator, bool> res = m_Mapping.find_2(last_elem);
493  TAlignColl::const_iterator it_end = res.second ? ++res.first : res.first;
494 
495  // iterate with in the visible range and render things
496  for( TAlignColl::const_iterator it = it_first; it != it_end; it++) {
497  const TAlignRange& range = *it;
498  if (range.Empty() || range.GetLength() <= 0)
499  continue;
500 
501  TRange clip_r = range.GetFirstRange();
502  clip_r.SetFrom( max(clip_r.GetFrom(), first_elem) );
503  clip_r.SetTo( min(clip_r.GetTo(), last_elem) );
504 
505  if( ! clip_r.Empty() && (!(m_DisplayOptions & fHideNegative) || range.GetSecondFrom() >= 0)) {
506  x_RenderRange(pane, range, clip_r);
507  }
508  }
509 
510  }
511 
512  if (gl.IsPrinterFriendly()) {
513  gl.EndClippingRect();
514  }
515 }
516 
517 
518 // if Auto Mode is enabled - update m_Mapping so that it represents
519 // the model limits rect of the pane
521 {
523  const TModelRect& rc_lim = pane.GetModelLimitsRect();
524 
525  int from = (int) (m_Horz ? rc_lim.Left() : rc_lim.Bottom());
526  int to = (int) (m_Horz ? rc_lim.Right() : rc_lim.Top()) - 1;
527 
528  bool update = false;
529  if(m_Mapping.size() != 1) {
530  update = true;
531  } else {
532  const TAlignRange& range = *m_Mapping.begin();
533  int old_from_1 = range.GetFirstFrom();
534  int old_from_2 = range.GetSecondFrom();
535  int old_to_1 = range.GetFirstTo();
536  int old_to_2 = range.GetSecondTo();
537  update = (from != old_from_1 || from != old_from_2 || to != old_to_1 || to != old_to_2);
538  }
539  if(update) {
540  m_Mapping.clear();
541  m_Mapping.insert(TAlignRange(from, from, to - from + 1, true));
542  }
543 }
544 
545 
546 // recalculate step only if needed
548 {
549  bool b_update = m_Dirty || m_PosLabelsStep <= 0;
550  if(! b_update) {
551  const TModelRect& rc_lim = pane.GetModelLimitsRect();
552  bool b_scale_changed = m_Horz ? (m_ScaleX != pane.GetScaleX())
553  : (m_ScaleY != pane.GetScaleY());
554  b_update = b_scale_changed || ! (m_rcLimits == rc_lim);
555 
556  m_rcLimits = rc_lim;
557  m_ScaleX = pane.GetScaleX();
558  m_ScaleY = pane.GetScaleY();
559  }
560 
561  if(b_update) {
563  }
564 }
565 
566 
567 // renders a segment of the Ruler
568 void CRuler::x_RenderRange(CGlPane& pane, const TAlignRange& range, const TRange& clip_r)
569 {
570  _ASSERT( ! clip_r.Empty());
571 
572  pane.OpenOrtho();
573 
575  const TModelRect& rc_v = pane.GetVisibleRect();
576  x_RenderBackground(pane, rc_v, clip_r);
577  }
578 
579  x_RenderScale(pane, range, clip_r); // render ticks and labels
580 
581  if((m_DisplayOptions & fHideLabels) == 0) {
582  x_RenderAllPosLabels(pane, range, clip_r);
583  }
584 
585  x_RenderOriginAndMetric(pane, clip_r);
586 
587  pane.Close();
588 }
589 
590 
591 // returns a number displayed on screen (1-based biologist's coordinate system)
592 int CRuler::x_ToDisplay(const TAlignRange& range, int model) const
593 {
594  // prg - 0-based programmer's coordinates
595  int prg = range.GetSecondPosByFirstPos(model);
596  if (m_BaseWidth > 1)
597  prg /= m_BaseWidth;
598  return prg >= 0 ? (prg + 1) : prg;
599 }
600 
601 
602 // converts display coordinates to model coordinates
603 TModelUnit CRuler::x_ToModel(const TAlignRange& range, int display) const
604 {
605  TModelUnit prg = (display > 0) ? (display - 1) : display;
606  if (m_BaseWidth > 1) {
607  prg *= m_BaseWidth;
608  prg += m_BaseOffset;
609  }
610  TModelUnit model = range.GetFirstPosBySecondPos(prg);
611  return model;
612 }
613 
614 
615 void CRuler::x_RenderBackground(CGlPane& pane, const TModelRect& rc, const TRange& clip_r)
616 {
617  IRender& gl = GetGl();
618 
619  gl.LineWidth(1.0f);
620  gl.ColorC(m_BackColor);
621  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
622 
623  TModelUnit from = (TModelUnit) clip_r.GetFrom();
624  TModelUnit to_open = (TModelUnit) clip_r.GetToOpen();
625  TModelRect rc_back(rc);
626 
627  if(m_Horz) {
628  rc_back.SetLeft(max(rc_back.Left(), from));
629  rc_back.SetRight(min(rc_back.Right(), to_open));
630  } else {
631  rc_back.SetBottom(max(rc_back.Bottom(), from));
632  rc_back.SetTop(min(rc_back.Top(), to_open));
633  }
634 
635  TModelUnit offset_x = pane.GetOffsetX();
636  TModelUnit offset_y = pane.GetOffsetY();
637  rc_back.Offset(-offset_x, -offset_y);
638 
639  gl.RectC(rc_back);
640 }
641 
643 {
644  from_offset = m_BaseOffset;
645  to_offset = m_BaseOffset;
646  if (m_BaseWidth > 1) {
647  int start_pos = range.GetSecondPosByFirstPos(range.GetFirstFrom());
648  int stop_pos = range.GetSecondPosByFirstPos(range.GetFirstTo());
649  if (start_pos > 0) {
650  if (start_pos < stop_pos) {
651  from_offset = m_BaseWidth - start_pos % m_BaseWidth;
652  } else {
653  from_offset = (start_pos + 1) % m_BaseWidth;
654  }
655  from_offset = from_offset > 0 ? from_offset * 0.5 : m_BaseOffset;
656  }
657  if (stop_pos > 0) {
658  if (start_pos < stop_pos) {
659  to_offset = (stop_pos + 1) % m_BaseWidth;
660  } else {
661  to_offset = m_BaseWidth - stop_pos % m_BaseWidth;
662  }
663 
664  to_offset = to_offset > 0 ? to_offset * 0.5 : m_BaseOffset;
665  }
666  }
667 }
668 
669 void CRuler::x_RenderScale(CGlPane& pane, const TAlignRange& range, const TRange& clip_r)
670 {
671  int clip_from = clip_r.GetFrom();
672  int clip_to = clip_r.GetTo();
673 
674  if( ! clip_r.Empty()) {
675  TModelUnit offset_x = pane.GetOffsetX();
676  TModelUnit offset_y = pane.GetOffsetY();
677 
678  int from = range.GetFirstFrom();
679  int to = range.GetFirstTo();
680  double MinU = from;
681  double MaxU = to + 1;
682  TModelUnit from_offset = 0;
683  TModelUnit to_offset = 0;
684  x_CalcStartStopOffsets(range, from_offset, to_offset);
685  MinU += from_offset;
686  MaxU -= to_offset;
687 
688  // setup rendering parameters
689 
690  double u1 = max(MinU, (double) clip_from);
691  double u2 = min(MaxU, (double) clip_to + 1);
692 
693  TModelUnit v0 = 0.0, v1 = 0.0, v2 = 0.0, v3 = 0.0, v4 = 0.0;
694  switch(m_LabelPlace) {
695  case eTop:
696  case eRight:
697  {{
698  v0 = m_LabelTickSize;
699  v1 = v0 + m_OppMinorTickSize;
700  v2 = v0 - m_MinorTickSize;
701  v3 = v0 + m_OppMajorTickSize;
702  v4 = v0 - m_MajorTickSize;;
703  }}
704  break;
705  case eLeft:
706  {{
707  v0 = pane.GetVisibleRect().Width() - m_LabelTickSize - 1;
708  v1 = v0 - m_OppMinorTickSize;
709  v2 = v0 + m_MinorTickSize;
710  v3 = v0 - m_OppMajorTickSize;
711  v4 = v0 + m_MajorTickSize;
712  }}
713  break;
714  case eBottom:
715  {{
716  v0 = pane.GetVisibleRect().Height() - m_LabelTickSize - 1;
717  v1 = v0 - m_OppMinorTickSize;
718  v2 = v0 + m_MinorTickSize;
719  v3 = v0 - m_OppMajorTickSize;
720  v4 = v0 + m_MajorTickSize;
721  }}
722  break;
723  default:
724  _ASSERT(false);
725  break;
726  }
727 
728  IRender& gl = GetGl();
729 
730  gl.LineWidth(1.0f);
731  gl.ColorC(m_RulerColor);
732  gl.Disable(GL_LINE_SMOOTH);
733  gl.Begin(GL_LINES);
734 
735 
736  if(m_Horz) {
737  gl.Vertex2d(u1 - offset_x, v0 - offset_y);
738  gl.Vertex2d(u2 - offset_x, v0 - offset_y);
739  } else {
740  gl.Vertex2d(v0 - offset_x, u1 - offset_y);
741  gl.Vertex2d(v0 - offset_x, u2 - offset_y);
742  }
743 
744  // draw Minor ticks
745  if(m_TickSpace) {
746  int i_first_disp = (x_ToDisplay(range, clip_from) / m_TickSpace ) * m_TickSpace;
747  int i_last_disp = (x_ToDisplay(range, clip_to) / m_TickSpace) * m_TickSpace;
748 
749  if (i_last_disp < i_first_disp)
750  swap(i_last_disp, i_first_disp);
751 
752  for( int i = i_first_disp; i <= i_last_disp; i += m_TickSpace) {
753  bool major = (m_BaseStep > 1) && (i % m_BaseStep) == 0;
754  double v_f = major ? v4 : v2;
755  double v_t = major ? v3 : v1;
756  double model = x_ToModel(range, i);
757 
758  if(model >= u1 && model < u2) {
759  double u = model + 0.5;
760  // render tick
761  if(m_Horz) {
762  gl.Vertex2d(u - offset_x, v_f - offset_y);
763  gl.Vertex2d(u - offset_x, v_t - offset_y);
764  } else {
765  gl.Vertex2d(v_f - offset_x, u - offset_y);
766  gl.Vertex2d(v_t - offset_x, u - offset_y);
767  }
768  }
769  }
770  }
771  gl.End();
772  }
773 }
774 
775 
776 // This function fills given vector with indices of the Alignment elements
777 // for which position labels should be shown
779  int first_elem, int last_elem, vector<TModelUnit>& vElemPos)
780 {
781  vElemPos.clear();
782  const int& step = m_PosLabelsStep;
783 
784  int i_first_disp = (x_ToDisplay(range, first_elem) / step ) * step;
785  int i_last_disp = (x_ToDisplay(range, last_elem) / step) * step;
786 
787  // labels shall be generated from left to right
788  if(i_last_disp < i_first_disp) {
789  for( int i = i_first_disp; i >= i_last_disp; i -= step) {
790  TModelUnit model = x_ToModel(range, i);
791  if(model >= first_elem && model <= last_elem) {
792  vElemPos.push_back(model);
793  }
794  }
795  } else {
796  for( int i = i_first_disp; i <= i_last_disp; i += step) {
797  TModelUnit model = x_ToModel(range, i);
798  if(model >= first_elem && model <= last_elem) {
799  vElemPos.push_back(model);
800  }
801  }
802  }
803 }
804 
805 // returns label size in ruler coordinate system (U, V)
807 {
808  IRender& gl = GetGl();
809  double w = gl.TextWidth(&m_Font, label.c_str());
810  double h = gl.TextHeight(&m_Font);
811 
812  double scale_u = pane.GetScaleX();
813  double scale_v = pane.GetScaleY();
814 
815  return TModelPoint(w * scale_u, h * scale_v);
816 }
817 
818 
820 {
821  IRender& gl = GetGl();
822  double w = gl.TextWidth(&m_Font, label.c_str());
823  double h = gl.TextHeight(&m_Font);
824 
825  return TModelPoint(w, h);
826 }
827 
828 //TODO refactor this function so that it can render several intervals and
829 // apply the existing algorithm to every interval
830 
831 // Renders all labels on the ruler
832 void CRuler::x_RenderAllPosLabels(CGlPane& pane, const TAlignRange& range, const TRange& clip_r)
833 {
834  vector<TModelUnit> vLabelsPos;
835  x_GenerateLabelPositions(range, clip_r.GetFrom() + 1, clip_r.GetTo() - 1, vLabelsPos);
836 
837  double scale = m_Horz ? pane.GetScaleX() : pane.GetScaleY();
838  double label_size = 0;
839  double label_size_scaled = 0.;
840  //const TModelRect& rc_m = pane.GetVisibleRect();
841 
842  double low_limit = clip_r.GetFrom();
843  double high_limit = clip_r.GetToOpen();
844 
845  int sep_pix = m_Horz ? kLabelSepPixX : kLabelSepPixY;
846 
848  label_size = x_GetLabelSizeUnscaled(pane, m_TextLabel).X()*scale + sep_pix * scale;
849  const TModelRect& rc_vis = pane.GetVisibleRect();
850 
851  double pos = m_Horz? rc_vis.Left() : rc_vis.Bottom();
852  x_RenderPosLabel(pane, 0, pos, m_TextLabel, false);
853  low_limit = pos + label_size;
854  }
855 
856  int from = range.GetFirstFrom();
857  int to = range.GetFirstTo();
858 
859  TModelUnit from_offset = 0;
860  TModelUnit to_offset = 0;
861  x_CalcStartStopOffsets(range, from_offset, to_offset);
862 
863  // setup rendering parameters
864  double label_u = from_offset + from; // label position along the Ruler
865  string S = kEmptyStr;
866 
867  // draw the first Label
868  if (!(m_DisplayOptions & fHideFirstLabel) ) {
869  S = x_GetPositionLabel(range, from);
870  if (m_DisplayOptions & fFirstLabelHasText && !m_TextLabel.empty()) {
871  S += " ";
872  S += m_TextLabel;
873  }
874  label_size_scaled = x_GetLabelSizeUnscaled(pane, S).X()*scale;
875  label_size = label_size_scaled + sep_pix * scale;
876 
877  double label_right = label_u + label_size;
878  if(label_u > low_limit) {
879  if(label_right > high_limit || label_size_scaled >= range.GetLength()) {
880  S.erase();
881  } else {
882  low_limit = label_u + label_size + sep_pix * scale;
883  }
884  //double shift = -min(label_size_scaled * 0.5, (double)label_u - from);
885  x_RenderPosLabel(pane, label_u, 0, S);
886  }
887  }
888 
889  label_u = (to + 1) - to_offset; // label position along the Ruler
890  if(label_u) {
891  // draw the Last label
892  if (!(m_DisplayOptions & fHideLastLabel) ) {
893  S = x_GetPositionLabel(range, to);
894  // there is enough space at least for the last label
895  label_size = x_GetLabelSizeUnscaled(pane, S).X()*scale;
896  if (label_u - label_size < low_limit
897  || label_u > high_limit
898  || label_size >= range.GetLength()) {
899  S.erase();
900  } else {
901  high_limit = label_u - (label_size + sep_pix * scale);
902  }
903  x_RenderPosLabel(pane, label_u, -label_size, S.c_str());
904  }
905 
906  // draw regular labels
907  int labels_n = (int)vLabelsPos.size();
908  for( int i_label = labels_n - 1; i_label >= 0; i_label-- ) {
909  TModelUnit pos = vLabelsPos[i_label];
910  S = x_GetPositionLabel(range, pos);
911  label_u = pos + 0.5;
912 
913  label_size = x_GetLabelSizeUnscaled(pane, S).X()*scale;
914 
915  double shift = -label_size * 0.5;
917  shift = -kTextSpaceX * scale - label_size;
918  } else if (m_LabelAln == eAln_Right || m_LabelAln == eAln_Top) {
919  shift = kTextSpaceX * scale;
920  }
921 
922  bool b_draw_text = (label_u + shift + label_size < high_limit)
923  && (label_u + shift > low_limit);
924  if(b_draw_text) {
925  high_limit = label_u + shift;
926  } else {
927  S = "";
928  }
929 
930  if ( !S.empty() || (label_u < high_limit && label_u > low_limit)) {
931  x_RenderPosLabel(pane, label_u, shift, S);
932  }
933  }
934  }
935 }
936 
937 
938 /// distance in pixels between left side of the ruler and origin labels
939 const static int kOriginOffsetX = 6;
940 
941 /// minimal size of the metric in pixels
942 const static int kMinMetricPix = 20;
943 
944 
946 {
947  // Metric and Origin can only be displayed in horizontal Ruler
948  bool can_draw = m_Horz && (m_Mapping.size() == 1); // mapping is linear
949 
950  if(can_draw) {
951  IRender& gl = GetGl();
952 
953  // translate clipping region into viewport coordinates
954  TVPUnit clip_vp_left = pane.ProjectX(clip_r.GetFrom());
955  TVPUnit clip_vp_right = pane.ProjectX(clip_r.GetToOpen());
956  TVPUnit clip_vp_len = clip_vp_right - clip_vp_left + 1;
957 
959  int text_h = (int) ceil(t_h);
960 
961  bool top_label = (m_LabelPlace == eTop);
962  int max_num = x_GetMaxNum();
963  TModelUnit off = x_GetTicksLabelsSizeV(max_num);
964  const TVPRect& rc_vp = pane.GetViewport();
965  TModelUnit y = top_label ? (rc_vp.Bottom() + off) : (rc_vp.Top() - off);
966 
967  int origin_right = clip_vp_left; // rightmost point of the origin label
968 
969  pane.Close();
970  pane.OpenPixels();
971 
972  if(m_DisplayOptions & fShowOrigin ) { // render Origin label
973  const TAlignRange& range = *m_Mapping.begin(); // the only segment
974  int origin = -1;
975  if(range.IsDirect()) {
976  origin = range.GetFirstFrom() - range.GetSecondFrom();
977  } else {
978  origin = range.GetSecondTo() + range.GetFirstFrom();
979  }
980 
981  string s = "Origin : " + CTextUtils::FormatSeparatedNumber(origin + 1, true);
982  int or_text_w = (int) ceil(gl.TextWidth(&m_Font, s.c_str()));
983 
984  or_text_w = min(or_text_w, clip_vp_len - kOriginOffsetX);
985  int x = origin_right + kOriginOffsetX;
986  TModelUnit text_y = (float) (top_label ? y : (y - text_h));
988  gl.WriteText(x, text_y, x + or_text_w, text_y + text_h, s.c_str());
989  gl.EndText();
990 
991  origin_right += (x + or_text_w); // advance origin_right to point at the end of the label
992  }
993 
995  // choose metric size
996  TModelUnit scale_x = pane.GetScaleX();
997  TModelUnit step = m_BaseStep;
998  while(step / scale_x < kMinMetricPix) {
999  step *= 10;
1000  }
1001 
1002  int pix_l = (int) ceil(step / scale_x); //length of metric in pixels
1003  string s = CTextUtils::FormatSeparatedNumber((int) step, true);
1004  s += " ";
1005  int text_w = (int) ceil(gl.TextWidth(&m_Font, s.c_str()));
1006 
1007  int metric_w = max(pix_l, text_w);
1008  if(origin_right + metric_w + kOriginOffsetX < clip_vp_right) {
1009  // there is enough space for rendering metric
1010 
1011  TModelUnit x = clip_vp_right - kOriginOffsetX - metric_w;
1012  int half_h = max(text_h, m_MajorTickSize) / 2;
1013  TModelUnit yc = y + (top_label ? half_h : -half_h);
1014 
1015  TModelUnit y1 = yc + m_MajorTickSize / 2;
1016  TModelUnit y2 = yc - m_MajorTickSize / 2;
1017 
1018  gl.Begin(GL_LINES);
1019  gl.Vertex2d(x, y1);
1020  gl.Vertex2d(x, y2);
1021 
1022  gl.Vertex2d(x, yc);
1023  gl.Vertex2d(x + pix_l, yc);
1024 
1025  gl.Vertex2d(x + pix_l, y1);
1026  gl.Vertex2d(x + pix_l, y2);
1027  gl.End();
1028 
1029  TModelUnit x1 = x - text_w;
1031  gl.WriteText(x1, y1, x, y2, s.c_str(),
1033  gl.EndText();
1034  }
1035  }
1036 
1037  }
1038 }
1039 
1040 
1041 // "pos_u" is the coordinate of the point in the model space
1042 // "u_label_offset" - offset of the label origin relative to this point
1043 void CRuler::x_RenderPosLabel(CGlPane& pane, double pos_u,
1044  double u_label_offset, const string& s_text,
1045  bool draw_tick)
1046 {
1047  if(m_Horz) {
1048  x_RenderHorzPosLabel(pane, pos_u, u_label_offset, s_text, draw_tick);
1049  } else {
1050  x_RenderVertPosLabel(pane, pos_u, u_label_offset, s_text, draw_tick);
1051  }
1052 }
1053 
1054 
1055 // renders a label on horizontal ruler
1056 void CRuler::x_RenderHorzPosLabel(CGlPane& pane, double pos_u,
1057  double u_label_offset, const string& s_text,
1058  bool draw_tick)
1059 {
1060  TModelPoint size = x_GetLabelSize(pane, s_text);
1061  TModelUnit text_u = size.X();
1062  TModelUnit text_v = size.Y();
1063 
1065  TModelUnit x = pos_u + u_label_offset;
1066 
1067  // don't render label if label is only partially visible
1068  if (x + text_u > pane.GetVisibleRect().Right()) return;
1069 
1070  TModelUnit label_bottom, tick_bottom;
1071 
1072  bool bottom_label = (m_LabelPlace == eBottom);
1073  if(bottom_label) {
1074  tick_bottom = pane.GetVisibleRect().Top() - tick_h;
1075  if (m_LabelAln == eAln_Center) {
1076  label_bottom = tick_bottom - kTextSpaceY - text_v;
1077  } else {
1078  label_bottom = tick_bottom - text_v;
1079  label_bottom += m_LabelTickSize - kTextSpaceY - m_MajorTickSize;
1080  }
1081  } else {
1082  tick_bottom = pane.GetVisibleRect().Bottom();
1083  if (m_LabelAln == eAln_Center) {
1084  label_bottom = tick_bottom + tick_h + kTextSpaceY;
1085  } else {
1086  label_bottom = tick_bottom + m_LabelTickSize + m_OppMajorTickSize + kTextSpaceY;
1087  }
1088  }
1089 
1091  switch(m_FontRotateDegrees) {
1092  case 0:
1093  text_align = bottom_label ? IGlFont::eAlign_Top : IGlFont::eAlign_Bottom;
1094  break;
1095  case 90:
1096  text_align = bottom_label ? IGlFont::eAlign_Right : IGlFont::eAlign_Left;
1097  break;
1098  case 180:
1099  text_align = bottom_label ? IGlFont::eAlign_Bottom : IGlFont::eAlign_Top;
1100  break;
1101  case 270:
1102  text_align = bottom_label ? IGlFont::eAlign_Left : IGlFont::eAlign_Right;
1103  break;
1104  default:
1105  break;
1106  }
1107 
1108  TModelUnit offset_x = pane.GetOffsetX();//(TModelUnit)((int)pane.GetOffsetX()+TModelUnit(0.5));
1109  TModelUnit offset_y = pane.GetOffsetY();//(TModelUnit)((int)pane.GetOffsetY()+TModelUnit(0.5));
1110 
1111  // render the label
1112  IRender& gl = GetGl();
1113  if (!s_text.empty()) {
1114  TModelUnit x1 = x - offset_x;
1115  TModelUnit y1 = label_bottom - offset_y;
1116 
1117  // not forcing text to integer x coords makes it slide more smoothly with
1118  // the ruler tic marks
1119  if (m_Font.GetFontSize() >= 12)
1120  m_Font.SetSnapToPixel(false, true);
1121  else
1122  m_Font.SetSnapToPixel(true, true);
1123 
1125  gl.WriteText(x1, y1, text_u, text_v, s_text.c_str(), text_align,
1127  gl.EndText();
1128  }
1129 
1130  if(draw_tick) {
1131  gl.LineWidth(1.0f);
1132  gl.ColorC(m_RulerColor);
1133  gl.Disable(GL_LINE_SMOOTH);
1134 
1135  gl.Begin(GL_LINES);
1136  gl.Vertex2d(pos_u - offset_x, tick_bottom - offset_y);
1137  gl.Vertex2d(pos_u - offset_x, tick_bottom + tick_h - offset_y);
1138  gl.End();
1139  }
1140 }
1141 
1142 // renders a label on vertical ruler
1143 void CRuler::x_RenderVertPosLabel(CGlPane& pane, double pos_u,
1144  double u_label_offset, const string& s_text,
1145  bool draw_tick)
1146 {
1147  TModelPoint size = x_GetLabelSizeUnscaled(pane, s_text);
1148  TModelUnit text_u = size.X()*pane.GetScaleX();
1149  TModelUnit text_v = size.Y()*pane.GetScaleY();
1150 
1152  TModelUnit y = pos_u + u_label_offset;
1153 
1154  TModelUnit label_left, tick_left;
1155 
1156  bool left_label = (m_LabelPlace == eLeft);
1157  if(left_label) {
1158  tick_left = pane.GetVisibleRect().Right() - tick_w;
1159  if (m_LabelAln == eAln_Center) {
1160  label_left = tick_left - kTextSpaceX;
1161  } else {
1162  label_left = tick_left - text_v;
1163  label_left += m_LabelTickSize - kTextSpaceY - m_MajorTickSize;
1164  }
1165  } else {
1166  tick_left = pane.GetVisibleRect().Left();
1167  if (m_LabelAln == eAln_Center) {
1168  label_left = tick_left + tick_w + kTextSpaceX;
1169  } else {
1170  label_left = tick_left + m_LabelTickSize +
1172  }
1173  }
1174 
1176  switch(m_FontRotateDegrees) {
1177  case 0:
1178  text_align = left_label ? IGlFont::eAlign_Right : IGlFont::eAlign_Left;
1179  break;
1180  case 90:
1181  text_align = left_label ? IGlFont::eAlign_Bottom : IGlFont::eAlign_Top;
1182  break;
1183  case 180:
1184  text_align = left_label ? IGlFont::eAlign_Left : IGlFont::eAlign_Right;
1185  break;
1186  case 270:
1187  text_align = left_label ? IGlFont::eAlign_Top : IGlFont::eAlign_Bottom;
1188  break;
1189  default:
1190  break;
1191  }
1192 
1193  TModelUnit offset_x = pane.GetOffsetX();
1194  TModelUnit offset_y = pane.GetOffsetY();
1195 
1196  // render Label
1197  IRender& gl = GetGl();
1198 
1199  TModelUnit x1 = label_left - offset_x;
1200  TModelUnit y1 = y - offset_y;
1201 
1202  // not forcing text to integer y coords makes it slide more smoothly with
1203  // the ruler tic marks
1204  if (m_Font.GetFontSize() >= 12)
1205  m_Font.SetSnapToPixel(true, false);
1206  else
1207  m_Font.SetSnapToPixel(true, true);
1208 
1210  gl.WriteText(x1, y1, text_u, text_v, s_text.c_str(), text_align,
1212  gl.EndText();
1213 
1214  if(draw_tick) {
1215  gl.ColorC(m_RulerColor);
1216  gl.LineWidth(1.0f);
1217  gl.Disable(GL_LINE_SMOOTH);
1218 
1219  gl.Begin(GL_LINES);
1220  gl.Vertex2d(tick_left - offset_x, pos_u - offset_y);
1221  gl.Vertex2d(tick_left + tick_w - offset_x, pos_u - offset_y);
1222  gl.End();
1223  }
1224 }
1225 
1226 
1227 // i_elem is in model coords
1229 {
1230  int pos = x_ToDisplay(range, i_elem);
1231  string S = CTextUtils::FormatSeparatedNumber(pos, true);
1232  return S;
1233 }
1234 
1235 
#define true
Definition: bool.h:35
size_type size() const
TAlignRangeVector::const_iterator const_iterator
const_iterator insert(const TAlignRange &r)
pair< const_iterator, bool > find_2(position_type pos) const
returns an iterator pointing to a range containing "pos"; if such a range does not exists an iterator...
const_iterator begin() const
CAlignRange Represents an element of pairwise alignment of two sequences.
Definition: align_range.hpp:63
CGlAttrGuard - guard class for restoring OpenGL attributes.
Definition: glutils.hpp:130
class CGlPane
Definition: glpane.hpp:62
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
void SetColor(EColorType type, const CRgbaColor &color)
Definition: ruler.cpp:133
TModelPoint x_GetLabelSizeUnscaled(CGlPane &pane, const string &label)
Definition: ruler.cpp:819
CAlignRange< TPos > TAlignRange
Definition: ruler.hpp:122
float m_BaseOffset
Definition: ruler.hpp:258
ELabelAlign m_LabelAln
Definition: ruler.hpp:236
void SetRange(int start, int end, int seq_start, bool reverse)
SetRange() activates "manual" mode; in this mode ruler's range in model space is explicitly limited t...
Definition: ruler.cpp:178
void x_RenderVertPosLabel(CGlPane &pane, double pos_u, double label_offset_u, const string &text, bool draw_tick=true)
Definition: ruler.cpp:1143
CGlTextureFont m_Font
Definition: ruler.hpp:266
@ fShowOrigin
Definition: ruler.hpp:110
@ fFillBackground
Definition: ruler.hpp:113
@ fFirstLabelHasText
Definition: ruler.hpp:117
@ fHideNegative
Definition: ruler.hpp:114
@ fHideLastLabel
Definition: ruler.hpp:116
@ fShowTextLabel
Definition: ruler.hpp:112
@ fShowMetric
Definition: ruler.hpp:111
@ fHideFirstLabel
Definition: ruler.hpp:115
@ fHideLabels
Definition: ruler.hpp:109
virtual string GetTooltip()
Definition: ruler.cpp:344
void SetTextLabel(const string &label)
Definition: ruler.cpp:197
void x_CalcStartStopOffsets(const TAlignRange &range, TModelUnit &from_offset, TModelUnit &to_offset)
Definition: ruler.cpp:642
string m_TextLabel
Definition: ruler.hpp:260
EColorType
Definition: ruler.hpp:51
@ eRuler
Definition: ruler.hpp:52
@ eText
Definition: ruler.hpp:53
@ eBackground
Definition: ruler.hpp:54
virtual void SetModelRect(const TModelRect &rc)
Definition: ruler.cpp:314
CRgbaColor m_TextColor
Definition: ruler.hpp:268
void SetFont(CGlTextureFont::EFontFace font_type, unsigned int font_size=12)
Definition: ruler.cpp:145
TModelRect m_rcLimits
"true" if parameters affecting layout have been changed
Definition: ruler.hpp:284
virtual TModelRect GetModelRect() const
Definition: ruler.cpp:308
double m_MaxLabelW
Definition: ruler.hpp:287
void x_RenderPosLabel(CGlPane &pane, double pos_u, double label_offset_u, const string &text, bool draw_tick=true)
Definition: ruler.cpp:1043
int m_BaseStep
Definition: ruler.hpp:290
void x_RenderOriginAndMetric(CGlPane &pane, const TRange &clip_r)
Definition: ruler.cpp:945
bool m_Dirty
Definition: ruler.hpp:282
int m_DisplayOptions
Definition: ruler.hpp:264
virtual void SetVPRect(const TVPRect &rect)
Definition: ruler.cpp:302
int x_GetMaxNum()
Definition: ruler.cpp:353
CGlTextureFont::EFontRotateFlags m_FontRotate
Font rotation flags (rotate around base or cap)
Definition: ruler.hpp:239
virtual TVPRect GetVPRect() const
Definition: ruler.cpp:295
CRgbaColor m_BackColor
Definition: ruler.hpp:270
double m_ScaleY
Definition: ruler.hpp:285
void x_RenderBackground(CGlPane &pane, const TModelRect &rc, const TRange &clip_r)
Definition: ruler.cpp:615
int x_GetOriginMetricSizeV() const
Definition: ruler.cpp:268
int m_FontRotateDegrees
Use degrees as int for safe comparison to 0, 90, 180 etc.
Definition: ruler.hpp:241
string x_GetPositionLabel(const TAlignRange &range, int iElem)
Definition: ruler.cpp:1228
ELabelPlacement
Definition: ruler.hpp:91
@ eBottom
Definition: ruler.hpp:92
@ eDefault
Definition: ruler.hpp:96
@ eTop
Definition: ruler.hpp:93
@ eLeft
Definition: ruler.hpp:94
@ eRight
Definition: ruler.hpp:95
virtual ~CRuler()
Definition: ruler.cpp:81
TVPPoint GetPreferredSize(int max_num=0) const
Definition: ruler.cpp:286
CRgbaColor m_RulerColor
Definition: ruler.hpp:269
int m_BaseWidth
Definition: ruler.hpp:257
int m_MinorTickSize
Definition: ruler.hpp:275
CRuler(bool horz=true)
Origin specifies the position in the model space that is represented as "1" in the Ruler's display sp...
Definition: ruler.cpp:48
double m_ScaleX
Definition: ruler.hpp:285
EGeometryParam
Ticks and labels placement.
Definition: ruler.hpp:82
@ eOppLabelTickHeight
tick size at label position (opposite)
Definition: ruler.hpp:88
@ eOppMajorTickHeight
major tick on the opposite side
Definition: ruler.hpp:87
@ eMajorTickHeight
Definition: ruler.hpp:84
@ eMinorTickHeight
Definition: ruler.hpp:83
@ eOppMinorTickHeight
minor tick on the opposite side
Definition: ruler.hpp:86
@ eLabelTickHeight
tick size at label position
Definition: ruler.hpp:85
void x_RenderRange(CGlPane &pane, const TAlignRange &range, const TRange &clip_r)
Definition: ruler.cpp:568
virtual void SetVisible(bool set)
Definition: ruler.cpp:332
int m_PosLabelsStep
Definition: ruler.hpp:291
bool m_Visible
Definition: ruler.hpp:233
void SetHorizontal(bool b_horz, ELabelPlacement place=eDefault, ELabelAlign aln=eAln_Center)
Definition: ruler.cpp:92
int x_GetTicksLabelsSizeV(int max_num) const
Ruler contains two layers.
Definition: ruler.cpp:246
int m_OppMinorTickSize
Definition: ruler.hpp:278
void SetAutoRange()
SetAutoRange() activates automatic mode; in this mode ruler's range is equal to the provided model li...
Definition: ruler.cpp:171
void SetLabelOrientation(CGlTextureFont::EFontRotateFlags rotate, int rotate_degrees)
Definition: ruler.cpp:155
int m_MajorTickSize
Definition: ruler.hpp:274
ELabelPlacement m_LabelPlace
Definition: ruler.hpp:235
int m_LabelTickSize
Definition: ruler.hpp:276
void x_UpdatePosLabelsStep(CGlPane &pane)
Definition: ruler.cpp:547
void SetDisplayOptions(int options)
Definition: ruler.cpp:165
void x_RenderScale(CGlPane &pane, const TAlignRange &range, const TRange &clip_r)
Definition: ruler.cpp:669
ELabelAlign
How labels align around ticks.
Definition: ruler.hpp:100
@ eAln_Bottom
valid for vertical mode only (mapped to eAln_Left for horizontal mode)
Definition: ruler.hpp:105
@ eAln_Top
valid for vertical mode only (mapped to eAln_Right for horizontal mode)
Definition: ruler.hpp:104
@ eAln_Right
valid for horizontal mode only (mapped to eAln_Top for vertical mode)
Definition: ruler.hpp:103
@ eAln_Left
valid for horizontal mode only (mapped to eAln_Bottom for vertical mode)
Definition: ruler.hpp:102
@ eAln_Center
Definition: ruler.hpp:101
void x_RenderAllPosLabels(CGlPane &pane, const TAlignRange &range, const TRange &clip_r)
Definition: ruler.cpp:832
void x_ChooseTickSpace(double scale)
Definition: ruler.cpp:445
int m_TickSpace
Definition: ruler.hpp:292
bool m_Horz
Definition: ruler.hpp:234
void x_RenderHorzPosLabel(CGlPane &pane, double pos_u, double label_offset_u, const string &text, bool draw_tick=true)
Definition: ruler.cpp:1056
int m_OppLabelTickSize
Definition: ruler.hpp:279
void x_GenerateLabelPositions(const TAlignRange &range, int first_elem, int last_elem, vector< TModelUnit > &vElemPos)
Definition: ruler.cpp:778
virtual TVPPoint PreferredSize()
Definition: ruler.cpp:320
virtual void Render(CGlPane &pane)
Definition: ruler.cpp:460
void x_CalculatePosLabelsStep(CGlPane &Pane)
Definition: ruler.cpp:368
int x_ToDisplay(const TAlignRange &range, int model) const
Definition: ruler.cpp:592
TModelUnit x_ToModel(const TAlignRange &range, int display) const
Definition: ruler.cpp:603
virtual bool NeedTooltip(CGlPane &pane, int vp_x, int vp_y)
Definition: ruler.cpp:338
void SetGeometryParam(EGeometryParam geom, int value)
Definition: ruler.cpp:203
TModelPoint x_GetLabelSize(CGlPane &pane, const string &label)
Definition: ruler.cpp:806
double m_MaxLabelH
Definition: ruler.hpp:288
bool m_AutoRange
Definition: ruler.hpp:246
int m_OppMajorTickSize
Definition: ruler.hpp:277
void SetMapping(const TAlignColl &coll)
Definition: ruler.cpp:190
virtual bool IsVisible()
Definition: ruler.cpp:326
TAlignColl m_Mapping
range displayed is [m_Start + m_Offset, m_End + m_Offset]
Definition: ruler.hpp:255
void x_UpdateMappingByPane(CGlPane &pane)
Definition: ruler.cpp:520
bool x_TextAlongAxis() const
Definition: ruler.cpp:234
Definition: set.hpp:45
char value[7]
Definition: config.c:431
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
const CVect2< U > & v2
Definition: globals.hpp:440
void SetSnapToPixel(bool xpix, bool ypix)
If true (the default) text output position is rounded to nearest pixel coordinate,...
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetRight(T right)
Definition: glrect.hpp:114
T X() const
Definition: glpoint.hpp:59
T Height() const
Definition: glrect.hpp:90
bool OpenOrtho()
Definition: glpane.hpp:427
virtual void Begin(GLenum mode)=0
Start rendering.
CGlPoint< TVPUnit > TVPPoint
Definition: gltypes.hpp:50
void SetBottom(T bottom)
Definition: glrect.hpp:113
T Top() const
Definition: glrect.hpp:84
void SetFontRotate(TFontRotateFlags rot)
Set rotation flags (for center of rotation and re-orienting)
virtual void BeginClippingRect(GLint x, GLint y, GLsizei width, GLsizei height)=0
T Bottom() const
Definition: glrect.hpp:82
void Offset(T d_x, T d_y)
Definition: glrect.hpp:186
T Width() const
Definition: glrect.hpp:86
bool OpenPixels()
Definition: glpane.hpp:432
EFontRotateFlags
Font rotate options.
TVPUnit ProjectX(TModelUnit m_x) const
Definition: glpane.cpp:661
IRender & GetGl()
convenience function for getting current render manager
void RectC(const TVPRect &rc)
Definition: irender.hpp:197
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
T Right() const
Definition: glrect.hpp:83
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
CGlRect< TVPUnit > TVPRect
Definition: gltypes.hpp:53
virtual void BeginText(const CGlTextureFont *font, const CRgbaColor &color)=0
Text is drawn is pixel coordinates.
virtual TModelUnit TextWidth(const CGlTextureFont *font, const char *text) const =0
TModelUnit GetOffsetY() const
Definition: glpane.hpp:415
static string FormatSeparatedNumber(int number, bool b_postfix=false)
virtual void EndText()=0
Pops matrices and attributes after writing text.
virtual TModelUnit GetMaxWidth(const CGlTextureFont *font, int max_num) const =0
TModelRect & GetModelLimitsRect(void)
Definition: glpane.hpp:347
T Left() const
Definition: glrect.hpp:81
T Y() const
Definition: glpoint.hpp:60
void SetFontFace(EFontFace face, bool use_bitmap_overrides=true)
virtual void EndClippingRect()=0
virtual bool IsPrinterFriendly() const =0
virtual void End()=0
Finish rendering (create buffer and send to renderer)
void Close(void)
Definition: glpane.cpp:178
virtual void PolygonMode(GLenum face, GLenum mode)=0
Set the polygon rasterization mode.
int TVPUnit
Definition: gltypes.hpp:47
EFontFace
Set of pre-defined fonts for which we know we have valid font files.
virtual void WriteText(TModelUnit x, TModelUnit y, const char *text, TModelUnit rotate_degrees=0.0)=0
Write text at specified model coords.
void SetLeft(T left)
Definition: glrect.hpp:112
void SetFontSize(unsigned int size)
Set/get font size in points.
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
CGlRect< TModelUnit > TModelRect
Definition: gltypes.hpp:54
virtual void Disable(GLenum glstate)=0
glDisable()
virtual TModelUnit GetMetric(const CGlTextureFont *font, IGlFont::EMetric metric, const char *text=NULL, int len=-1) const =0
Calls the standard font metric functions except for pdf in which case it first replaces any bitmap fo...
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
TModelUnit GetScaleY(void) const
Definition: glpane.cpp:123
TModelUnit GetOffsetX() const
Definition: glpane.hpp:410
CGlPoint< TModelUnit > TModelPoint
Definition: gltypes.hpp:51
unsigned int GetFontSize() const
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void SetTop(T top)
Definition: glrect.hpp:115
int TAlign
Definition: glfont.hpp:113
@ eAlign_Center
Definition: glfont.hpp:111
@ eAlign_Right
Definition: glfont.hpp:104
@ eAlign_Top
Definition: glfont.hpp:107
@ eAlign_Bottom
Definition: glfont.hpp:109
@ eAlign_Left
Definition: glfont.hpp:102
@ eMetric_FullCharHeight
Definition: glfont.hpp:80
@ eMetric_AvgCharWidth
Definition: glfont.hpp:83
@ eTruncate_None
Definition: glfont.hpp:64
position_type GetToOpen(void) const
Definition: range.hpp:138
bool Empty(void) const
Definition: range.hpp:148
#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[]
void SetFrom(TFrom value)
Assign a value to From data member.
Definition: Range_.hpp:231
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
void SetTo(TTo value)
Assign a value to To data member.
Definition: Range_.hpp:278
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
n background color
int i
int len
#define S(x, n)
range(_Ty, _Ty) -> range< _Ty >
constexpr auto rotate(list< Ts... >) -> decltype((list<>{}+...+rotate_item< Ts >{}))
const struct ncbi::grid::netcache::search::fields::SIZE size
#define abs(a)
Definition: ncbi_heapmgr.c:130
T max(T x_, T y_)
T log10(T x_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
static const GLdouble origin[]
static int kTextSpaceX
spacing between text and borders or between text and other graphics
Definition: ruler.cpp:230
static const int kMinMetricPix
minimal size of the metric in pixels
Definition: ruler.cpp:942
static const int kLabelSepPixY
Definition: ruler.cpp:88
static const int kOriginOffsetX
distance in pixels between left side of the ruler and origin labels
Definition: ruler.cpp:939
static const int kLabelSepPixX
Definition: ruler.cpp:87
static int kTextSpaceY
Definition: ruler.cpp:231
static const int kMinTickStepPixels
Definition: ruler.cpp:86
Definition: type.c:6
#define _ASSERT
Modified on Mon Dec 11 02:40:11 2023 by modify_doxy.py rev. 669887