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

Go to the SVN repository for this file.

1 /* $Id: alnmulti_renderer.cpp 47464 2023-04-20 00:19:10Z 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: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistl.hpp>
34 #include <corelib/ncbitime.hpp>
35 
37 #include <gui/opengl/irender.hpp>
40 #include <gui/objutils/tooltip.hpp>
41 
42 #include <algorithm>
43 #include <sstream>
44 
46 
47 static const int kRulerSpace = 4;
48 static const int kMasterRowSpace = 0;
49 
50 using namespace objects;
51 
52 CAlnMultiRenderer::CAlnMultiRenderer(const TVPRect &rc, bool add_columns)
53  : m_Context(NULL),
54  m_ResizableColumnIndex(-1),
55  m_bFocused(true),
56  m_HitResult(eNone),
57  m_TooltipRow(NULL),
58  m_TooltipColumn(-1)
59 {
60  m_Header.SetContext(this);
62 
63  SetBackColor(CRgbaColor(0.95f, 1.0f, 0.95f)); //light green
64  SetMasterBackColor(CRgbaColor(0.85f, 1.0f, 0.85f)); // slightly darker green
65 
68 
69  if (add_columns)
71 }
72 
74 {
75 }
76 
78 {
79  AddColumn(120, "Description", IAlignRow::eDescr);
80  // AddColumn(20, "Strand", IAlignRow::eIconStrand);
81  // AddColumn(20, "+", IAlignRow::eIconExpand);
82  AddColumn(40, "Markers", IAlignRow::eIcons);
83  AddColumn(50, "Seq. Start", IAlignRow::eSeqStart);
84  AddColumn(60, "First", IAlignRow::eStart);
85 
86  int index = AddColumn(0, "Alignment", IAlignRow::eAlignment); // resizable, takes 100% of free space
87  SetResizableColumn(index);
88 
89  AddColumn(50, "Last", IAlignRow::eEnd);
90  AddColumn(50, "Seq. End", IAlignRow::eSeqEnd);
91  AddColumn(50, "Seq. Length", IAlignRow::eSeqLength);
92  AddColumn(150, "Org. Name", IAlignRow::eTaxLabel);
93 
94  const char *v = (const char *)glGetString(GL_VERSION);
95  if (!v)
96  return;
97 
98  Resize(rc);
99 }
100 
102 {
103  m_Context = context;
104 }
105 
107 {
108  m_BackColor = color;
109 }
110 
112 {
113  return m_BackColor;
114 }
115 
117 {
119 }
120 
122 {
123  return m_MasterBackColor;
124 }
125 
127 {
128  return m_Ruler;
129 }
130 
132 {
133  m_rcBounds = rc;
134  x_LayoutColumns();
135  x_Layout();
136 }
137 
139 {
140  return m_rcBounds;
141 }
142 
144 {
145  return m_Header;
146 }
147 
148 /// Graphics is rendered inthe current OpenGL context in the viewport defined
149 /// by the / following rectangle
150 /// (0, 0, m_rcBounds.Width() - 1, m_rcBounds.Height() - 1)
152 {
153  x_Render(NULL);
154 }
155 
157 {
158  x_Render(&areas);
159 }
160 
162 {
163  string error;
164  try
165  {
166  glClearColor(m_BackColor.GetRed(), m_BackColor.GetGreen(),
168  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
170 
172  x_RenderHeader(p_areas);
174  x_RenderRuler(p_areas);
175 
178  {
179  x_RenderMasterRow(p_areas);
180  }
182  {
183  x_RenderItems(p_areas);
185  }
187  }
188  catch (CException &e)
189  {
190  error = e.GetMsg();
191  }
192  catch (std::exception &e)
193  {
194  error = e.what();
195  }
196  if (!error.empty())
197  {
198  ERR_POST("CAlnMultiRenderer::x_Render() " << error);
199  }
200 }
201 
203 {
204  if (!x_GetContext() || m_RowToList.empty())
205  return;
207  if (!row)
208  row = x_GetContext()->GetRowByLine(0);
209  if (!row)
210  return;
211  const CRowDisplayStyle *style = row->GetDisplayStyle();
212  if (!style)
213  return;
214  if (style->IsWebRendering())
215  return;
216  // render a top line
217  IRender &gl = GetGl();
220  rect.SetTop(rect.Top() + 1);
221  pane.SetViewport(rect);
222  pane.OpenPixels();
224  gl.Begin(GL_LINES);
225  gl.Vertex2d(rect.Left(), rect.Top());
226  gl.Vertex2d(rect.Right(), rect.Top());
227  gl.End();
228  pane.Close();
229 }
230 
231 void CAlnMultiRenderer::Update(bool layout_only)
232 {
233  x_Layout();
234 
235  x_InvalidateRows(layout_only);
236 }
237 
239 {
240  x_Layout();
241 
242  m_RowToList.clear();
243 }
244 
245 bool CAlnMultiRenderer::NeedTooltip(int vp_x, int vp_y)
246 {
247  m_TooltipVPPos.Init(vp_x, vp_y);
248  m_TooltipRow = NULL;
249 
250  m_HitResult = HitTest(vp_x, vp_y, m_TooltipColumn);
251 
252  switch (m_HitResult)
253  {
254  case eHeader:
255  {
256  CGlPane pane; // TODO
257  return m_Header.NeedTooltip(pane, vp_x, vp_y);
258  }
259  case eRows:
260  {
261  int line = x_GetLineByVPY(vp_y);
262  if (line != -1)
263  {
265  }
267  return row.NotNull();
268  //return m_TooltipRow != 0;
269  }
270  case eMasterRow:
271  {
273  //return m_TooltipRow != 0;
275  return row.NotNull();
276  }
277  default:
278  return false;
279  }
280 }
281 
283 {
284  switch (m_HitResult)
285  {
286  case eHeader:
287  return m_Header.GetTooltip();
288  case eMasterRow:
289  {
290  int row_top_y = GetMasterArea().Top(); // -kMasterRowSpace;
292  if (row.IsNull())
293  break;
294  return x_GetRowTooltip(m_TooltipVPPos, row, m_TooltipColumn, row_top_y);
295  }
296  case eRows:
297  {
299  if (row.IsNull())
300  break;
301  int line = x_GetContext()->GetLineByRowNum(row->GetRowNum());
302  if (line == -1)
303  { // not a visible row...
304  break;
305  }
306  int model_y = x_GetContext()->GetLinePosY(line);
307  int vp_top = GetVPListTop() + (int)x_GetContext()->GetAlignPort().GetVisibleRect().Top();
308  int row_top_y = vp_top - model_y;
309  return x_GetRowTooltip(m_TooltipVPPos, row, m_TooltipColumn, row_top_y);
310  }
311  default:
312  break;
313  };
314  return "";
315 }
316 
317 string CAlnMultiRenderer::GetAlignmentTooltip(int x, int y, IAlignRow *row, bool master)
318 {
319  int row_top_y;
320  // Our y coordinate is actually a "model" coordinate, so convert it to VP
321  int vp_top = m_rcBounds.Top();
322  int vp_y = vp_top - y;
323  if (master)
324  {
325  row_top_y = GetMasterArea().Top() - kMasterRowSpace;
326  }
327  else
328  {
329  int line = x_GetContext()->GetLineByRowNum(row->GetRowNum());
330  if (line == -1)
331  { // not a visible row...
332  return "";
333  }
334  int model_y = x_GetContext()->GetLinePosY(line);
335  int vp_top1 = GetVPListTop() + (int)x_GetContext()->GetAlignPort().GetVisibleRect().Top();
336  row_top_y = vp_top1 - model_y;
337  }
338  TVPPoint vpt(x, vp_y);
340 }
341 
342 void CAlnMultiRenderer::x_AddStatisticsRow(ITooltipFormatter &formatter, const string &tag, int part, int total)
343 {
344  stringstream statistics;
345  statistics << part << " of " << total << " rows (" << NStr::DoubleToString((double)100 * part / total, 1, NStr::fWithCommas) + "%)";
346  formatter.AddRow(tag, statistics.str());
347 }
348 
350 {
351  const CGlPane &port = x_GetContext()->GetAlignPort();
352 
353  auto rc_vp = m_MasterRect;
354  rc_vp.SetBottom(port.GetViewport().Bottom());
355  pane.SetViewport(rc_vp);
356 
357  //pane.SetViewport(m_MasterRect);
359  // setup model space
360  TModelRect rcV = port.GetVisibleRect();
361  rcV.SetVert(rc_vp.Height() - 1, 0);
362  pane.SetVisibleRect(rcV);
363 
364  TModelRect rcLim = port.GetModelLimitsRect();
365  rcLim.SetVert(H - 1, 0);
366  pane.SetModelLimitsRect(rcLim);
367  pane.SetExactOrthoProjection(m_bCgiMode == false); // need this to avoid text 'popping up and down' effect on window resize
368 }
369 
370 string CAlnMultiRenderer::x_GetRowTooltip(const TVPPoint &pt, IAlignRow *row, int i_col, int vp_top_y)
371 {
372  _ASSERT(row);
373 
374  CGlPane pane(x_GetContext()->GetAlignPort());
375  pane.EnableOffset();
376  if (x_GetContext()->GetMasterRow() == row)
377  {
378  x_PrepareMasterPane(pane);
379  }
380  row->PrepareRendering(pane, vp_top_y, 0);
381  SetupPaneForColumn(pane, i_col);
382 
385  row->GetTooltip(pt, type, pane, *formatter);
387  {
388  return formatter->Render();
389  }
390 
391  string colbases;
392  typedef map<char, int> MapCharInt;
393  MapCharInt counters;
394 
395  TSeqPos pos = (TSeqPos)pane.UnProjectX(pt.X());
396  string base;
397  row->GetStringAtPos(base, pos);
398  if (base.empty())
399  return formatter->Render();
400 
401  int num_rows = x_GetContext()->GetLinesCount();
402  if (!formatter->IsEmpty())
403  formatter->AddDividerRow();
404  char symbol = 0;
405  if (base.empty())
406  {
407  symbol = ' ';
408  }
409  else if (!(symbol = base[0]))
410  {
411  symbol = '-';
412  }
413 
414  if (row->UsesAATranslation())
415  {
416  string colstat = string(1, symbol);
417  try
418  {
420  }
421  catch (const CSeqportUtil::CBadSymbol &)
422  {
423  //colstat += "n/a";
424  }
425  formatter->AddRow("Amino acid:", colstat);
426  }
427  else
428  {
429  string colstat = string(1, symbol);
430  try
431  {
433  }
434  catch (const CSeqportUtil::CBadSymbol &)
435  {
436  }
437  formatter->AddRow("Base:", colstat);
438  }
439 
440  auto base_width = row->UsesAATranslation() && row->IsNucProtAlignment() ? 3 : 1;
441  if (base_width != 3)
442  { // count mis/matches only if it's not mixed alignment
443  IAlnExplorer::TSignedRange posrange(pos, pos);
444 
445  IAlignRow *consensus_row = x_GetContext()->GetConsensusRow();
446  for (int i = -1; i < num_rows; i++)
447  {
448  IAlignRow *itrow =
449  i < 0
452  if (itrow == NULL || itrow == consensus_row)
453  continue;
454 
455  string base;
456  itrow->GetAlnSeqString(base, posrange);
457 
458  char symbol = 0;
459  if (base.empty())
460  {
461  symbol = ' ';
462  }
463  else if (!(symbol = base[0]))
464  {
465  symbol = '-';
466  }
467 
468  colbases += symbol;
469  counters[symbol]++;
470  }
471 
472  int match = 0;
473  int mismatch = 0;
474  int gaps = 0;
475  int unaligned = 0;
476  int total = 0;
477  string colstat;
478 
479  ITERATE(MapCharInt, itr, counters)
480  {
481  char sym = itr->first;
482  int num = itr->second;
483 
484  if (sym == ' ')
485  {
486  unaligned += num;
487  }
488  else if (sym == '-')
489  {
490  gaps += num;
491  }
492  else if (sym == symbol)
493  {
494  match = num;
495  }
496  else
497  {
498  mismatch += num;
499  }
500 
501  total += num;
502  }
503 
504  ITooltipFormatter &tip_formatter = *formatter;
505  x_AddStatisticsRow(tip_formatter, "Matches:", match, total);
506  x_AddStatisticsRow(tip_formatter, "Mismatches:", mismatch, total);
507  x_AddStatisticsRow(tip_formatter, "Gaps:", gaps, total);
508  x_AddStatisticsRow(tip_formatter, "Unaligned:", unaligned, total);
509  formatter->AddRow("Total rows:", NStr::IntToString(total, NStr::fWithCommas));
510  }
511 
512  row->GetRowStatistics(*formatter);
513 
514  return formatter->Render();
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// protected members
520 {
521  return m_rcBounds.Height() - m_ListAreaRect.Height();
522 }
523 
525 {
526  int n_col = GetColumnsCount();
527  for (int i = 0; i < n_col; i++)
528  {
529  if (m_Columns[i].m_UserData == type)
530  return i;
531  }
532  return -1;
533 }
534 
535 TVPRect CAlnMultiRenderer::GetColumnRect(int i_col, bool include_header) const
536 {
537  const SColumn &Col = GetColumn(i_col);
538  TVPUnit h_h = include_header ? 0 : m_HeaderRect.Height();
539  TVPUnit h = m_rcBounds.Height() - 1 - h_h;
540  return TVPRect(Col.m_Pos, 0, Col.m_Pos + Col.m_Width - 1, h);
541 }
542 
544 {
545  int iCol = GetColumnIndexByType(Type);
546  return GetColumnRect(iCol, include_header);
547 }
548 
550 {
551  _ASSERT(i_col > -1);
552  int type = (int)GetColumn(i_col).m_UserData;
554 }
555 
557 {
558  int i_col = GetColumnIndexByX(x);
559  if (i_col >= 0)
560  {
561  int type = (int)GetColumn(i_col).m_UserData;
563  }
564  else
565  return IAlignRow::eInvalid;
566 }
567 
569 {
571 
572  // we arrange things from the top down
573  TVPUnit h = 0, top = m_rcBounds.Top();
574 
575  // Header is placed at the top and takes as much space as needed
577  {
579  h = m_Header.PreferredSize().Y();
582  top = m_HeaderRect.Bottom() - 1;
583  }
584  else
585  {
586  m_HeaderRect.Init(0, 0);
587  }
588 
589  bool align_visible = false;
590  const SColumn *col = 0;
592  if (iAlign >= 0)
593  {
594  col = &GetColumn(iAlign);
595  align_visible = col->VisibleWidth();
596  }
597 
598  // Ruler is placed below the header
600  {
603  m_RulerRect.SetRight(m_RulerRect.Left()); // reset width to 0
604 
605  // determine horizontal extent of the Ruler
606  if (align_visible)
607  {
608  _ASSERT(col);
609  m_RulerRect.SetVert(top - h + 1, top);
610  m_RulerRect.SetHorz(col->m_Pos, col->m_Pos + col->m_Width - 1);
611  }
612  else
613  {
614  m_RulerRect.SetVert(top, top);
615  }
617  top = m_RulerRect.Bottom() - 1;
618  }
619  else
620  {
621  m_RulerRect.Init(0, 0);
622  }
623 
625  {
626  // If Master is set the Master row are is placed right below the Ruler
627  h = kMasterRowSpace * 2;
628  if (x_GetContext())
629  {
631  if (row)
632  h += (row->GetHeightPixels() - 1);
633  }
634  if (h > 0)
635  {
637  m_MasterRect.SetVert(top - h, top);
638  top = m_MasterRect.Bottom() - 1;
639  }
640  else
641  {
642  m_MasterRect.SetVert(top, top);
643  }
644  }
645  else
646  {
647  m_MasterRect.Init(0, 0);
648  }
649 
650  // other rows occupy all the remaining space
652  m_ListAreaRect.SetTop(top);
653 }
654 
656 {
659  pane.SetExactOrthoProjection(m_bCgiMode == false); // need this to avoid text 'popping up and down' effect on window resize
660  m_Header.Render(pane);
661 }
662 
664 {
665  if (m_RulerRect.Width() > 1 && m_RulerRect.Height() > 1)
666  {
668 
669  const CGlPane &port = x_GetContext()->GetAlignPort();
670 
671  TModelRect rcM = port.GetModelLimitsRect();
672  rcM.SetVert(0, m_RulerRect.Height() - 1);
674 
675  TModelRect rcV = port.GetVisibleRect();
676  rcV.SetVert(0, m_RulerRect.Height() - 1);
678 
679  m_Ruler.Render(m_RulerPane); // render
680 
681  if (p_areas)
682  {
684  "Ruler", "Ruler", "");
685  p_areas->push_back(area);
686  }
687  }
688 }
689 
691 {
692  IAlignRow *p_row = x_GetContext()->GetMasterRow();
693  if (p_row)
694  {
695  IRender &gl = GetGl();
696 
698  pane.EnableOffset();
699  x_PrepareMasterPane(pane);
700  // fill the background
701  pane.OpenPixels();
703  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
705  pane.Close();
706 
707  // now render the row
709 
710  int row_state = p_row->GetRowState();
711  if (row_state & IAlignRow::fItemSelected)
712  { // master row selected ?
714  }
715 
716  //TVPUnit top_y = m_MasterRect.Bottom() + p_row->GetHeightPixels();
717  x_RenderRow(p_row, pane, state, m_MasterRect.Top() - 1, p_areas);
718  }
719 }
720 
721 // renders all visible rows in the List Area
723 {
724  if (x_GetContext())
725  {
726 
727  // calculate visible range
728  const CGlPane &port = x_GetContext()->GetAlignPort();
729  TModelRect rcM = port.GetVisibleRect();
730 
731  int iFirst = x_GetContext()->GetLineByModelY((int)rcM.Top());
732  iFirst = max(iFirst, 0);
733 
734  int iLast = x_GetContext()->GetLineByModelY((int)rcM.Bottom());
735  iLast = (iLast == -1) ? x_GetContext()->GetLinesCount() - 1 : iLast;
736 
737  if (iLast >= iFirst)
738  {
739  x_RenderItemsRange(iFirst, iLast, p_areas);
740  }
741  }
742 }
743 
744 // renders the specified range of the alignment rows
745 void CAlnMultiRenderer::x_RenderItemsRange(int iFirst, int iLast,
746  TAreaVector *p_areas)
747 {
748  if (x_GetContext())
749  {
750  const CGlPane &port = x_GetContext()->GetAlignPort();
751 
752  // create clipping rectangle
753  TVPRect rc_clip = port.GetViewport();
754  rc_clip.SetHorz(0, m_rcBounds.Width() - 1);
755  rc_clip.SetTop(rc_clip.Top() - 1);
756 
757  if (rc_clip.Height() && rc_clip.Width())
758  {
759  int y1 = GetVPListTop() + (int)port.GetVisibleRect().Top();
760 
761  const int base_state = m_bFocused ? IAlignRow::fWidgetFocused : IAlignRow::fNone;
762  int i_focused = x_GetContext()->GetFocusedItemIndex();
763 
764  // create a single CGlPane for rendering all cells in all rows
766  pane.EnableOffset();
767  pane.SetClipRect(&rc_clip);
768  pane.SetExactOrthoProjection(m_bCgiMode == false); // need this to avoid text 'popping up and down' effect on window resize
769  for (int i = iFirst; i <= iLast; i++)
770  {
771  IAlignRow *p_row = x_GetContext()->GetRowByLine(i);
773  pane.SetVisibleRect(port.GetVisibleRect());
775 
776  int state = base_state;
777  if (x_GetContext()->IsItemSelected(i))
779  if (i_focused == i)
781 
782  TVPUnit row_top = y1 - x_GetContext()->GetLinePosY(i);
783 
784  x_RenderRow(p_row, pane, state, row_top, p_areas);
785  }
786 
787  pane.SetClipRect(NULL);
788  }
789  }
790 }
791 
792 // renders all columns within the given Row, vp_top_y is OpenGL viewport
793 // coordinate of the top pixel in the row
795  TAreaVector *areas)
796 {
797  string error;
798  try
799  {
800  _ASSERT(row);
801 
802  m_RowToList[row] = true; // update "on-screen" attribute
803  row->PrepareRendering(pane, row_top, state);
804  row->RenderRow();
805  int col_n = GetColumnsCount();
806  for (int i_col = 0; i_col < col_n; i_col++)
807  {
808  const SColumn &col = GetColumn(i_col);
809  SetupPaneForColumn(pane, i_col);
811  if (col.VisibleWidth())
812  {
813  row->RenderColumn(type);
814  }
815  if (areas)
816  {
817  row->GetHTMLActiveAreas(type, pane, *areas);
818  }
819  }
820  }
821  catch (CException &e)
822  {
823  error = e.GetMsg();
824  }
825  catch (std::exception &e)
826  {
827  error = e.what();
828  }
829  if (!error.empty())
830  {
831  ERR_POST("CAlnMultiRenderer::x_RenderRow() " << error);
832  }
833 }
834 
835 
836 void CAlnMultiRenderer::AutoFitColumns(const CGlTextureFont& font, bool for_printer)
837 {
838  vector<string> col_text;
839  int col_n = GetColumnsCount();
840  col_text.resize(col_n);
841  int num_rows = x_GetContext()->GetLinesCount();
842  for (auto i = 0; i < num_rows; ++i) {
843  IAlignRow *p_row = x_GetContext()->GetRowByLine(i);
844  for (int i_col = 0; i_col < col_n; i_col++) {
845  const SColumn &col = GetColumn(i_col);
846  if (col.m_Visible && i_col != m_ResizableColumnIndex) {
847  TColumnType col_type = x_GetColumnType(col);
848  string text;
849  p_row->GetColumnText(col_type, text, for_printer);
850  text += "00";
851  if (col_text[i_col].length() < text.length())
852  col_text[i_col] = text;
853  }
854  }
855  }
856 
857  for (size_t i = 0; i < col_text.size(); ++i) {
858  if (col_text[i].empty())
859  continue;
860  TModelUnit w = ceil(font.GetMetric(IGlFont::eMetric_FullTextWidth, col_text[i].c_str()));
861  SetColumnWidth(static_cast<int>(i), int(w) + 12);
862  }
863  UpdateColumns();
864 }
865 
866 void CAlnMultiRenderer::SetupPaneForColumn(CGlPane &pane, int i_col) const
867 {
868  const SColumn &col = GetColumn(i_col);
869  pane.GetViewport().SetHorz(col.m_Pos, col.m_Pos + col.m_Width - 1);
870 }
871 
873 {
874  return m_MasterRect;
875 }
876 
878 {
879  return m_ListAreaRect.Top();
880 }
881 
882 //TODO
883 int CAlnMultiRenderer::HitTest(int vp_x, int vp_y, int &col)
884 {
885  col = GetColumnIndexByX(vp_x);
886  if (col == -1)
887  return eNone;
888  int limit = m_rcBounds.Top();
889 
891 
893  {
894  limit -= m_HeaderRect.Height();
895  if (vp_y > limit)
896  return eHeader;
897  }
898 
900  {
901  limit -= m_RulerRect.Height();
902  if (vp_y > limit)
903  return eRuler;
904  }
905 
907  {
908  int top = limit - kMasterRowSpace;
909  limit -= m_MasterRect.Height() - kMasterRowSpace;
910  if (vp_y < top && vp_y > limit)
911  return eMasterRow;
912  }
913 
915  {
916  if (vp_y < m_ListAreaRect.Top() && vp_y > m_ListAreaRect.Bottom())
917  return eRows;
918  }
919 
920  return eNone;
921 }
922 
924 {
925  int vpY = WinY - GetListTop();
926  int offset_y = (int)x_GetContext()->GetAlignPort().GetVisibleRect().Top();
927  return x_GetContext()->GetLineByModelY(vpY + offset_y);
928 }
929 
931 {
932  int offset_y = (int)x_GetContext()->GetAlignPort().GetVisibleRect().Bottom();
933  int model_y = offset_y - vp_y;
934 
935  return x_GetContext()->GetLineByModelY(model_y);
936 }
937 
939 {
940  int Top = 0, H = 0;
941  if (x_GetContext() && Index >= 0)
942  {
943  int offset_y = (int)x_GetContext()->GetAlignPort().GetVisibleRect().Top();
944  Top = x_GetContext()->GetLinePosY(Index) - offset_y;
945  H = x_GetContext()->GetLineHeight(Index);
946  }
947  return TVPRect(0, Top + H - 1, m_rcBounds.Width() - 1, Top);
948 }
949 
951 {
953  {
954  it->second = false;
955  }
956 }
957 
958 // invalidates display lists for all rows
960 {
961  const CGlPane &port = x_GetContext()->GetAlignPort();
962  // TModelRect rcV = port.GetVisibleRect();
964  {
965  IAlignRow &row = *it->first;
966  row.GraphicsCacheCmd(IAlignRow::eInvalidate);
967  }
968 
969  IAlignRow *master_row = x_GetContext()->GetMasterRow();
970  if (master_row)
971  master_row->Update(port, layout_only);
972 
973  TModelRect rcM = port.GetVisibleRect();
974  int iFirst = x_GetContext()->GetLineByModelY((int)rcM.Top());
975  iFirst = max(iFirst, 0);
976 
977  int iLast = x_GetContext()->GetLineByModelY((int)rcM.Bottom());
978  iLast = (iLast == -1) ? x_GetContext()->GetLinesCount() - 1 : iLast;
979  for (int i = iFirst; i <= iLast; i++)
980  {
981  IAlignRow *p_row = x_GetContext()->GetRowByLine(i);
982  p_row->Update(port, layout_only);
983  }
984 }
985 
986 // delete display list for off-screen rows
988 {
989  for (TRowToList::iterator it = m_RowToList.begin(); it != m_RowToList.end();)
990  {
991  if (!it->second)
992  {
993  //row is off-screen now - purge cached graphics
994  (it->first)->GraphicsCacheCmd(IAlignRow::eDelete);
996  ++next;
997  m_RowToList.erase(it);
998  it = next;
999  }
1000  else
1001  it++;
1002  }
1003 }
1004 
1005 const int kDefColumnWidth = 50;
1006 
1008  : m_Pos(0),
1009  m_Width(kDefColumnWidth),
1010  m_UserData(0),
1011  m_Visible(true)
1012 {
1013 }
1014 
1016 {
1017  return (int)m_Columns.size();
1018 }
1019 
1021 {
1022  _ASSERT(index >= 0 && index < (int)m_Columns.size());
1023  return m_Columns[index];
1024 }
1025 
1027 {
1028  _ASSERT(index >= 0 && index < (int)m_Columns.size());
1029  return m_Columns[index];
1030 }
1031 
1033 {
1034  return AddColumn(kDefColumnWidth, "", 0);
1035 }
1036 
1037 int CAlnMultiRenderer::AddColumn(int width, const string &label, int data)
1038 {
1039  int index = GetColumnsCount();
1040  return InsertColumn(index, width, label, data);
1041 }
1042 
1043 int CAlnMultiRenderer::InsertColumn(int index, int width,
1044  const string &label, int data)
1045 {
1046  _ASSERT(index >= 0 && index <= (int)m_Columns.size());
1047 
1048  SColumn col;
1049  col.m_Width = width;
1050  col.m_Name = label;
1051  col.m_UserData = data;
1053 
1054  TColumnVector::const_iterator it =
1055  m_Columns.insert(m_Columns.begin() + index, col);
1056  int i = int(it - m_Columns.begin());
1057 
1058  // update m_ResizableColumnIndex
1059  if (m_ResizableColumnIndex >= 0 && m_ResizableColumnIndex < (int)m_Columns.size())
1060  {
1061  if (m_ResizableColumnIndex >= i)
1062  {
1063  m_ResizableColumnIndex++;
1064  }
1065  }
1066  else
1067  {
1068  m_ResizableColumnIndex = i;
1069  }
1070  return i;
1071 }
1072 
1074 {
1075  if (index >= 0 && index < (int)m_Columns.size())
1076  {
1077  m_ResizableColumnIndex = index;
1078  }
1079  else
1080  {
1081  _ASSERT(false);
1082  }
1083 }
1084 
1085 void CAlnMultiRenderer::SetColumns(const vector<SColumn> &columns, int resizable_index)
1086 {
1087  m_Columns = columns;
1088  SetResizableColumn(resizable_index);
1089 
1090  x_LayoutColumns();
1091  x_Layout();
1092 }
1093 
1094 void CAlnMultiRenderer::SetColumnWidth(int index, int width)
1095 {
1096  width = max(width, 0);
1097 
1098  m_Columns[index].m_Width = width;
1099 }
1100 
1101 void CAlnMultiRenderer::SetColumnPos(int index, int pos)
1102 {
1103  m_Columns[index].m_Pos = pos;
1104 }
1105 
1107 {
1108  _ASSERT(index >= 0 && index < (int)m_Columns.size());
1109  m_Columns[index].m_UserData = data;
1110 }
1111 
1112 void CAlnMultiRenderer::SetColumnVisible(int index, bool b_visible)
1113 {
1114  _ASSERT(index >= 0 && index < (int)m_Columns.size());
1115 
1116  SColumn &col = m_Columns[index];
1117  if (col.m_Visible != b_visible)
1118  {
1119  col.m_Visible = b_visible;
1120  int delta = b_visible ? col.m_Width : -col.m_Width;
1121  if (col.m_Visible && delta == 0)
1122  {
1123  delta = col.m_Width = kDefColumnWidth;
1124  }
1125  for (int i = index + 1; delta != 0 && i < (int)m_Columns.size(); i++)
1126  {
1127  m_Columns[i].m_Pos += delta;
1128  }
1129  }
1130 
1131  Resize(m_rcBounds);
1132 }
1133 
1134 
1136 {
1137  _ASSERT(index >= 0 && index < (int)m_Columns.size());
1138 
1139  return m_Columns[index].m_Visible;
1140 }
1141 
1142 
1144 {
1145  // get the name of the resizable column, we will use it to update
1146  // resizable column index after rearranging is completed
1147  size_t rs_index = GetResizableColumnIndex();
1148  _ASSERT(rs_index < m_Columns.size());
1149  string rs_name = m_Columns[rs_index].m_Name;
1150 
1151  vector<SColumn> new_columns;
1152 
1153  // iterate by columns in the style and place them first
1155  {
1156  const CWidgetDisplayStyle::SColumn &col = *it;
1157 
1158  for (size_t i = 0; i < m_Columns.size(); i++)
1159  {
1160  if (m_Columns[i].m_Name == col.m_Name)
1161  {
1162  // update the column and place into the new container
1163  m_Columns[i].m_Width = col.m_Width;
1164  m_Columns[i].m_Visible = col.m_Visible;
1165  new_columns.push_back(m_Columns[i]);
1166  // delete it from m_Columns
1167  m_Columns.erase(m_Columns.begin() + i);
1168  }
1169  }
1170  }
1171 
1172  // now in m_Columns we have onl columns not recorded in the style
1173  // add them to the end without changes
1174  new_columns.insert(new_columns.end(), m_Columns.begin(), m_Columns.end());
1175 
1176  m_Columns = new_columns;
1177 
1178  // update rs_index
1179  for (size_t j = 0; j < m_Columns.size(); j++)
1180  {
1181  if (m_Columns[j].m_Name == rs_name)
1182  {
1183  rs_index = j;
1184  break;
1185  }
1186  }
1187 
1188  // finish rearranging
1189  SetResizableColumn((int)rs_index);
1190 
1191  Resize(m_rcBounds);
1192 }
1193 
1194 /*
1195 void CAlnMultiRenderer::SetHiddenColumns(const vector<string>& names)
1196 {
1197  // get the name of the resizable column, we will use it to update
1198  // resizable column index after rearranging is completed
1199  int rs_index = GetResizableColumnIndex();
1200  _ASSERT(rs_index >= 0 && rs_index < (int) m_Columns.size());
1201  string rs_name = m_Columns[rs_index].m_Name;
1202 
1203  rs_index = -1;
1204 
1205  // reset Visible flag
1206  NON_CONST_ITERATE(TColumnVector, it, m_Columns) {
1207  it->m_Visible = true;
1208  }
1209 
1210  vector<SColumn> hid_columns;
1211 
1212  // iterate by hidden columns
1213  for( size_t i = 0; i < names.size(); i++ ) {
1214  TColumnVector::iterator it = m_Columns.begin();
1215  for(; it != m_Columns.end(); ++it) {
1216  if(it->m_Name == names[i])
1217  break;
1218  }
1219 
1220  if(it != m_Columns.end()) {
1221  it->m_Visible = false;
1222  hid_columns.push_back(*it);
1223  m_Columns.erase(it);
1224  }
1225  }
1226 
1227  m_Columns.insert(m_Columns.end(), hid_columns.begin(), hid_columns.end());
1228 
1229  // update rs_index
1230  for( size_t j = 0; j < m_Columns.size(); j++ ) {
1231  if(m_Columns[j].m_Name == rs_name) {
1232  rs_index = j;
1233  break;
1234  }
1235  }
1236 
1237  // finish rearranging
1238  SetResizableColumn(rs_index);
1239 
1240  Resize(m_rcBounds);
1241 }
1242 */
1243 
1245 {
1246  names.clear();
1247  ITERATE(TColumnVector, it, m_Columns)
1248  {
1249  if (it->m_Visible)
1250  {
1251  names.push_back(it->m_Name);
1252  }
1253  }
1254 }
1255 
1257 {
1258  ITERATE(TColumnVector, it, m_Columns)
1259  {
1260  if (it->m_Visible && x >= it->m_Pos && x < it->m_Pos + it->m_Width)
1261  return int(it - m_Columns.begin());
1262  }
1263  return -1;
1264 }
1265 
1267 {
1268  return m_ResizableColumnIndex;
1269 }
1270 
1272 {
1273  Resize(m_rcBounds);
1274 }
1275 
1277 {
1278  int w = m_rcBounds.Width();
1279  int n_col = (int)m_Columns.size();
1280 
1281  if (w > 0 && n_col > 0)
1282  { // resize all columns
1283  int total_w = 0;
1284  for (int j = 0; j < n_col; j++)
1285  {
1286  SColumn &col = m_Columns[j];
1287  if (col.m_Visible && j != m_ResizableColumnIndex)
1288  {
1289  total_w += col.m_Width;
1290  }
1291  }
1292 
1293  int pos = 0;
1294  for (int j = 0; j < n_col; j++)
1295  {
1296  SColumn &col = m_Columns[j];
1297  if (col.m_Visible)
1298  {
1299  col.m_Pos = pos;
1300  if (j == m_ResizableColumnIndex)
1301  {
1302  int w_rest = w - total_w;
1303  col.m_Width = w_rest > 0 ? w_rest : 0;
1304  }
1305  pos += col.m_Width;
1306  }
1307  _ASSERT(col.m_Width >= 0);
1308  }
1309  }
1310 }
1311 
User-defined methods of the data storage class.
const int kDefColumnWidth
static const int kRulerSpace
static const int kMasterRowSpace
@ eNone
None specified.
Definition: blast_def.h:326
CAlnMultiHeader.
virtual void Render(CGlPane &pane)
virtual void SetContext(IAlnMultiHeaderContext *context)
virtual bool NeedTooltip(CGlPane &pane, int vp_x, int vp_y)
virtual string GetTooltip()
virtual TVPPoint PreferredSize()
void x_RenderRuler(TAreaVector *p_areas)
void x_RenderRow(IAlignRow *row, CGlPane &pane, int state, TVPUnit row_top, TAreaVector *areas)
TVPPoint m_TooltipVPPos
is it invoked by alnmulti.cgi
CAlnMultiHeader & GetHeader()
int x_GetLineByVPY(int vp_y) const
virtual void UpdateOnDataChanged()
bool IsColumnVisible(int index) const
virtual void Resize(const TVPRect &rc)
TColumnType GetColumnTypeByX(int vp_x) const
void SetContext(IAlnMultiRendererContext *pContext)
void SetColumnsByStyle(CWidgetDisplayStyle &style)
virtual int GetColumnsCount() const
virtual void SetupColumns(const TVPRect &rc)
Adds default columns for the renderer, allows custom setup (column icon override, etc)
int InsertColumn(int pos, int width, const string &label, int data)
bool m_bCgiMode
indicate whether it shoulde be rendered using "focused" color or not
CAlnMultiHeader m_Header
TColumnType x_GetColumnType(const SColumn &C)
virtual int GetColumnIndexByX(int x) const
void x_AddStatisticsRow(ITooltipFormatter &formatter, const string &tag, int part, int total)
virtual bool NeedTooltip(int vp_x, int vp_y)
vector< SColumn > TColumnVector
void x_RenderHeader(TAreaVector *p_areas)
TVPRect GetMasterArea() const
virtual const SColumn & GetColumn(int index) const
void SetColumnUserData(int index, int data)
virtual int GetResizableColumnIndex() const
void x_RenderItems(TAreaVector *p_areas)
void x_RenderMasterRow(TAreaVector *p_areas)
IAlignRow::TColumnType TColumnType
void x_RenderItemsRange(int iFisrt, int iLast, TAreaVector *p_areas)
void AutoFitColumns(const CGlTextureFont &font, bool for_printer)
void GetVisibleColumns(vector< string > &labels)
CAlnMultiRenderer()
Empty object constructor – for two-phase construction call SetupColums() to finish the class construc...
IAlnMultiRendererContext * m_Context
IAlnMultiRendererContext * x_GetContext()
void x_InvalidateRows(bool layout_only=false)
TVPRect GetColumnRectByType(TColumnType type, bool include_header) const
void SetColumns(const vector< SColumn > &columns, int resizable_index)
virtual int HitTest(int vp_x, int vp_y, int &col)
void SetColumnPos(int index, int pos)
int GetColumnIndexByType(TColumnType type) const
const CRgbaColor & GetBackColor() const
void SetColumnWidth(int index, int width)
void SetBackColor(const CRgbaColor Color)
void x_PrepareMasterPane(CGlPane &pane)
CWeakIRef< IAlignRow > m_TooltipRow
virtual string GetTooltip()
string x_GetRowTooltip(const TVPPoint &pt, IAlignRow *p_row, int i_col, int vp_top_y)
void SetColumnVisible(int index, bool b_visible)
virtual string GetAlignmentTooltip(int x, int y, IAlignRow *row, bool master)
virtual void Render()
renders OpenGL graphics
int GetVPListTop() const
return OpenGL viewport coordinate of the top pixel in the list area
const CRgbaColor & GetMasterBackColor() const
void x_Render(TAreaVector *p_areas)
TVPRect GetColumnRect(int i_col, bool include_header) const
virtual void Update(bool layout_only=false)
void SetMasterBackColor(const CRgbaColor Color)
virtual TVPRect GetRect() const
void SetupPaneForColumn(CGlPane &pane, int i_col) const
void SetResizableColumn(int index)
vector< CHTMLActiveArea > TAreaVector
TVPRect x_GetLineRect(int Index)
TColumnType GetColumnTypeByIndex(int i_col) const
int x_GetLineByWindowY(int WinY) const
int GetListTop() const
protected members
class CGlPane
Definition: glpane.hpp:62
virtual void SetVPRect(const TVPRect &rc)
Definition: renderable.cpp:58
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CRowDisplayStyle is a base class representing a display style for IAlignRow.
virtual const CRgbaColor & GetColor(TColorType type) const
bool IsWebRendering() const
CRuler is a renderable object drawing a scale with position labels.
Definition: ruler.hpp:49
void SetFont(CGlTextureFont::EFontFace font_type, unsigned int font_size=12)
Definition: ruler.cpp:145
virtual void SetVPRect(const TVPRect &rect)
Definition: ruler.cpp:302
@ eTop
Definition: ruler.hpp:93
TVPPoint GetPreferredSize(int max_num=0) const
Definition: ruler.cpp:286
void SetHorizontal(bool b_horz, ELabelPlacement place=eDefault, ELabelAlign aln=eAln_Center)
Definition: ruler.cpp:92
virtual void Render(CGlPane &pane)
Definition: ruler.cpp:460
static const string & GetName(CSeq_data::E_Choice code_type, TIndex idx)
static TIndex GetIndex(CSeq_data::E_Choice code_type, const string &code)
CWidgetDisplayStyle is a collection of display properties common for all rows in the CAlnMultiWidget.
vector< SColumn > TColumns
Interface IAlignRow - abstracts row rendering in Multiple Alignment Widget.
Definition: ialign_row.hpp:67
virtual string & GetColumnText(TColumnType col_type, string &text, bool for_printer=false) const =0
virtual string & GetAlnSeqString(string &buffer, const IAlnExplorer::TSignedRange &aln_rng) const =0
int TColumnType
Definition: ialign_row.hpp:70
@ fWidgetFocused
it isn'e exactly a row state;
Definition: ialign_row.hpp:106
virtual int GetRowState() const =0
Returns row state (combination of EState flags)
virtual int GetHeightPixels() const =0
Returns height of the row in pixels.
virtual void Update(const CGlPane &pane, bool layout_only=false)
Definition: ialign_row.hpp:149
@ eIcons
Strand + Expand icons.
Definition: ialign_row.hpp:77
virtual int GetColumnsCount() const =0
virtual int GetResizableColumnIndex() const =0
IAlnMultiRendererContext - this interface represents context in which CAlnMultiRenderer lives.
virtual IAlignRow * GetConsensusRow()=0
virtual int GetLineByRowNum(TNumrow row) const =0
virtual int GetShownElements()=0
virtual bool IsRendererFocused()=0
virtual const CGlPane & GetAlignPort() const =0
virtual int GetFocusedItemIndex() const =0
virtual IAlignRow * GetRowByLine(int index)=0
all Y coordinates are OpenGL Viewport coordinates (not widget coords) "index" is a line index (not ro...
virtual int GetLinePosY(int index) const =0
virtual int GetLineHeight(int index) const =0
virtual IAlignRow * GetMasterRow()=0
virtual int GetLineByModelY(int y) const =0
virtual TNumrow GetLinesCount() const =0
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
void erase(iterator pos)
Definition: map.hpp:167
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
static const struct name_t names[]
#define true
Definition: bool.h:35
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
static int type
Definition: getdata.c:31
#define H(x, y, z)
Definition: md4.c:180
static const column_t columns[]
Definition: utf8_2.c:22
char data[12]
Definition: iconv.c:80
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
string
Definition: cgiapp.hpp:690
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetModelLimitsRect(const TModelRect &R)
Definition: glpane.hpp:342
void SetRight(T right)
Definition: glrect.hpp:114
T X() const
Definition: glpoint.hpp:59
T Height() const
Definition: glrect.hpp:90
void SetClipRect(const TVPRect *rc_clip=NULL)
set clipping rect that will be used by glScissor, NULL for reset
Definition: glpane.hpp:395
void SetViewport(const TVPRect &R)
Definition: glpane.cpp:96
void Init()
Definition: glrect.hpp:62
virtual void Begin(GLenum mode)=0
Start rendering.
void SetBottom(T bottom)
Definition: glrect.hpp:113
T Top() const
Definition: glrect.hpp:84
void Color3f(GLfloat r, GLfloat g, GLfloat b)
Definition: irender.hpp:95
T Bottom() const
Definition: glrect.hpp:82
T Width() const
Definition: glrect.hpp:86
bool OpenPixels()
Definition: glpane.hpp:432
IRender & GetGl()
convenience function for getting current render manager
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
T Right() const
Definition: glrect.hpp:83
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
CGlRect< TVPUnit > TVPRect
Definition: gltypes.hpp:53
TModelUnit UnProjectX(TVPUnit m_x) const
Definition: glpane.cpp:706
TModelRect & GetModelLimitsRect(void)
Definition: glpane.hpp:347
void Init(T x, T y)
Definition: glpoint.hpp:58
T Left() const
Definition: glrect.hpp:81
T Y() const
Definition: glpoint.hpp:60
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
void SetVert(T bottom, T top)
Definition: glrect.hpp:123
void SetVisibleRect(const TModelRect &R)
Definition: glpane.cpp:113
virtual TModelUnit GetMetric(EMetric metric, const char *text=NULL, int len=-1) const
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
void SetExactOrthoProjection(bool exact_projection)
Definition: glpane.hpp:509
void SetHorz(T left, T right)
Definition: glrect.hpp:117
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void SetTop(T top)
Definition: glrect.hpp:115
void Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
Definition: irender.hpp:193
void EnableOffset(bool b_en=true)
Offset is used as a workaround for OpenGL precision problems emerging when size of visible range is s...
Definition: glpane.hpp:405
@ eMetric_FullTextWidth
Definition: glfont.hpp:93
@ eNeverUpdate
Definition: glpane.hpp:84
@ eAlwaysUpdate
Definition: glpane.hpp:85
virtual void AddRow(const string &sContents="", unsigned colspan=2)=0
add a row with a cell, spanning across all columns
float GetBlue(void) const
Definition: rgba_color.hpp:333
float GetGreen(void) const
Definition: rgba_color.hpp:327
float GetAlpha(void) const
Definition: rgba_color.hpp:339
static CIRef< ITooltipFormatter > CreateTooltipFormatter()
Definition: tooltip.cpp:264
float GetRed(void) const
Get specific channels in floating point values.
Definition: rgba_color.hpp:321
TRefType Lock(void) const
Lock the object and return reference to it.
Definition: ncbiobj.hpp:2864
#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 DoubleToString(double value, int precision=-1, TNumToStringFlags flags=0)
Convert double to string.
Definition: ncbistr.hpp:5181
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
@ fWithCommas
Use commas as thousands separator.
Definition: ncbistr.hpp:254
static const char label[]
@ eSeq_code_type_iupacaa
IUPAC 1 letter amino acid code.
@ eSeq_code_type_iupacna
IUPAC 1 letter nuc acid code.
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
n background color
int i
static void text(MDB_val *v)
Definition: mdb_dump.c:62
constexpr bool empty(list< Ts... >) noexcept
const char * tag
The NCBI C++/STL use hints.
Defines: CTimeFormat - storage class for time format.
T max(T x_, T y_)
Int4 delta(size_t dimension_, const Int4 *score_)
static int match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, uint16_t top_bracket, PCRE2_SIZE frame_size, pcre2_match_data *match_data, match_block *mb)
Definition: pcre2_match.c:594
#define row(bind, expected)
Definition: string_bind.c:73
SColumn describes a single column.
int m_Width
horizontal position in viewport
bool m_Visible
can be used to identify column
Definition: type.c:6
#define _ASSERT
#define Type
static CS_CONTEXT * context
Definition: will_convert.c:21
Modified on Fri Sep 20 14:57:06 2024 by modify_doxy.py rev. 669887