ruler.cpp
来自「ncbi源码」· C++ 代码 · 共 722 行 · 第 1/2 页
CPP
722 行
double u2 = min(MaxU, (double) last_elem + 1); TModelUnit v1 = 0, v2 = 0, v3 = 0; switch(m_LabelPlace) { case eTop: case eRight: { v1 = m_MajorTickSize; v2 = v1 - m_RegTickSize; v3 = v1 - m_MajorTickSize; }; break; case eLeft: { v1 = pane.GetVisibleRect().Width() - m_MajorTickSize - 1; v2 = v1 + m_RegTickSize; v3 = v1 + m_MajorTickSize; }; break; case eBottom: { v1 = pane.GetVisibleRect().Height() - m_MajorTickSize - 1; v2 = v1 + m_RegTickSize; v3 = v1 + m_MajorTickSize; }; break; default: _ASSERT(false); } glColorC(m_RullerColor); glBegin(GL_LINES); if(m_bHorz) { glVertex2d(u1 - offset_x, v1 - offset_y); glVertex2d(u2 - offset_x, v1 - offset_y); } else { glVertex2d(v1 - offset_x, u1 - offset_y); glVertex2d(v1 - offset_x, u2 - offset_y); } // draw regular ticks if(m_TickSpace) { int orig_disp = (x_ToDisplay(m_Start) / m_BaseStep) * m_BaseStep; int orig = x_ToModel(orig_disp); int i_first_disp = (x_ToDisplay(first_elem) / m_TickSpace ) * m_TickSpace; int i_last_disp = (x_ToDisplay(last_elem) / m_TickSpace) * m_TickSpace; int i_start = x_ToModel(i_first_disp); int i_end = x_ToModel(i_last_disp) + m_TickSpace; if(i_start < first_elem) i_start += m_TickSpace; while(i_end > last_elem) i_end -= m_TickSpace; for( int i = i_start; i <= i_end; i += m_TickSpace ) { double v = ((i - orig) % m_BaseStep) ? v2 : v3; double u = 0.5 + i; if(m_bHorz) { glVertex2d(u - offset_x, v - offset_y); glVertex2d(u - offset_x, v1 - offset_y); } else { glVertex2d(v - offset_x, u - offset_y); glVertex2d(v1 - offset_x, u - offset_y); } } } glEnd(); }}// This function fills given vector with indeces of the Alignment elements // for which position labels should be shownvoid CRuler::x_GenerateLabelPositions(int first_elem, int last_elem, vector<int>& vElemPos){ vElemPos.clear(); const int& step = m_PosLabelsStep; // i_start and i_end are positions in model space int i_first_disp = (x_ToDisplay(first_elem) / step ) * step; int i_last_disp = (x_ToDisplay(last_elem) / step) * step; int i_start = x_ToModel(i_first_disp); int i_end = x_ToModel(i_last_disp) + step; while(i_start < first_elem) i_start += step; while(i_end > last_elem) i_end -= step; for( int i = i_start; i <= i_end; i += step ) vElemPos.push_back(i);}/// Renders all labels on the ruller.void CRuler::x_RenderAllPosLabels(CGlPane& pane, int first_elem, int last_elem){ vector<int> vLabelsPos; x_GenerateLabelPositions(first_elem, last_elem, vLabelsPos); // setup text output params double scale = m_bHorz ? pane.GetScaleX() : pane.GetScaleY(); // draw the First Label int pos = m_Start; string S = x_GetPositionLabel(m_Start); double label_size = 0; if(m_bHorz) { label_size = (m_Font.TextWidth(S.c_str()) + kLabelSepPix) * scale; } else { label_size = (m_Font.TextHeight() + kLabelSepPix) * scale; } double label_u = 0.5 + m_Start; x_RenderPosLabel(pane, label_u, 0, S); double low_limit = label_u + label_size; // draw the Last label label_u = 0.5 + m_End; S = x_GetPositionLabel(m_End); if(m_bHorz) { label_size = m_Font.TextWidth(S.c_str()) * scale; } if(label_u) // there is enough space at least for the last label { x_RenderPosLabel(pane, label_u, -label_size, S.c_str()); double high_limit = label_u - (label_size + kLabelSepPix * scale); // draw regular labels int labels_n = vLabelsPos.size(); for( int i_label = labels_n - 1; i_label >= 0; i_label-- ) { pos = vLabelsPos[i_label]; string S = x_GetPositionLabel(pos); label_u = pos + 0.5; if(m_bHorz) { label_size = m_Font.TextWidth(S.c_str()) * scale; } double half_size = label_size / 2.0; bool b_draw_text = (label_u + half_size < high_limit) && (label_u - half_size > low_limit); if(! b_draw_text) { S = ""; } else { high_limit = label_u - half_size; } x_RenderPosLabel(pane, label_u, -half_size, S); } }}/// distnce in pixels between left side of ruler and origin labelsconst static int kOriginOffsetX = 6; /// minimal size of the metric in pixelsconst static int kMinMetricPix = 20; /// returns height necessary for drawing ticks and tick labels (if not hidden)int CRuler::x_GetBaseHeight() const{ int h = m_MajorTickSize + kTextSpaceY; if((m_DisplayOptions & fHideLabels) == 0) { h += m_MajorTickSize + (int)m_Font.TextHeight() + kTextSpaceY; } return h;}void CRuler::x_RenderOriginAndMetric(CGlPane& pane){ if(m_bHorz) { TVPRect rc_vp = pane.GetViewport(); double t_h = m_Font.GetMetric(CGlBitmapFont::eMetric_FullCharHeight); int text_h = (int) ceil(t_h); TModelUnit y = rc_vp.Bottom() + x_GetBaseHeight(); // bottoom int origin_right = rc_vp.Left(); // rightmost point of the origin label if(m_DisplayOptions & fShowOrigin) { // render Origin label int origin = x_ToModel(1) + 1; string s = "Origin : " + CTextUtils::FormatSeparatedNumber(origin, true); int or_text_w = (int) ceil(m_Font.TextWidth(s.c_str())); or_text_w = min(or_text_w, rc_vp.Width() - kOriginOffsetX); int x = rc_vp.Left() + kOriginOffsetX; m_Font.TextOut(x, y, or_text_w, text_h, s.c_str()); // render label origin_right += kOriginOffsetX + or_text_w; } if(m_DisplayOptions & fShowMetric) { // choose metric size TModelUnit scale_x = pane.GetScaleX(); TModelUnit step = m_BaseStep; while(step / scale_x < kMinMetricPix) { step *= 10; } int pix_l = (int) ceil(step / scale_x); //length of metric in pixels string s = CTextUtils::FormatSeparatedNumber((int) step, true); s += " "; int text_w = (int) ceil(m_Font.TextWidth(s.c_str())); int metric_w = max(pix_l, text_w); if(origin_right + metric_w + kOriginOffsetX < rc_vp.Right()) { // there is enough space for rendering metric TModelUnit x = rc_vp.Right() - kOriginOffsetX - metric_w; TModelUnit yc = y + max(text_h, m_MajorTickSize) / 2; TModelUnit y1 = yc + m_MajorTickSize / 2; TModelUnit y2 = yc - m_MajorTickSize / 2; glBegin(GL_LINES); glVertex2d(x, y1); glVertex2d(x, y2); glVertex2d(x, yc); glVertex2d(x + pix_l, yc); glVertex2d(x + pix_l, y1); glVertex2d(x + pix_l, y2); glEnd(); m_Font.TextOut(x - text_w, y, text_w, text_h, s.c_str(), FL_ALIGN_RIGHT); } } }}// pos_u is in model coordsvoid CRuler::x_RenderPosLabel(CGlPane& pane, double pos_u, double u_label_offset, const string& s_text ){ TModelUnit offset_x = pane.GetOffsetX(); TModelUnit offset_y = pane.GetOffsetY(); if(m_bHorz) { // horizontal orientation TModelUnit y1, y2, text_y; TModelUnit tick_h = 2 * m_MajorTickSize; if(m_LabelPlace == eTop) { y1 = 0; y2 = tick_h; text_y = y2 + kTextSpaceY; } else { y2 = pane.GetVisibleRect().Top(); y1 = y2 - tick_h; text_y = y1 - kTextSpaceY - m_Font.TextHeight(); } glColorC(m_TextColor); m_Font.TextOut(pos_u + u_label_offset - offset_x, text_y - offset_y, s_text.c_str()); // draw label's tick glColorC(m_RullerColor); glBegin(GL_LINES); glVertex2d(pos_u - offset_x, y1 - offset_y); glVertex2d(pos_u - offset_x, y2 - offset_y); glEnd(); } else { // vertical orientation TModelUnit tick_w = 2 * m_MajorTickSize; TModelUnit text_w = pane.GetVisibleRect().Width() - tick_w; TModelUnit y = pos_u + u_label_offset; TModelUnit h = m_Font.TextHeight(); TModelUnit x0 = pane.GetVisibleRect().Left(); TModelUnit tick_x = text_w; if (m_LabelPlace == eRight) { x0 += tick_w + kLabelSepX; tick_x = 0; } int text_align = FL_ALIGN_BOTTOM | ((m_LabelPlace == eRight) ? FL_ALIGN_LEFT : FL_ALIGN_RIGHT); glColorC(m_TextColor); m_Font.TextOut(x0 - offset_x, y - offset_y, text_w - kLabelSepX, h, s_text.c_str(), text_align); // draw label's tick glColorC(m_RullerColor); glBegin(GL_LINES); glVertex2d(tick_x - offset_x, pos_u - offset_y); glVertex2d(tick_x + tick_w - offset_x, pos_u - offset_y); glEnd(); }}// i_elem is in model coordsstring CRuler::x_GetPositionLabel(int i_elem){ int pos = x_ToDisplay(i_elem); string S = CTextUtils::FormatSeparatedNumber(pos, true); return S;}END_NCBI_SCOPE/* * =========================================================================== * $Log: ruler.cpp,v $ * Revision 1000.4 2004/06/01 21:10:43 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15 * * Revision 1.15 2004/05/21 22:27:54 gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.14 2004/03/23 14:07:37 dicuccio * Fixed compiler warnings * * Revision 1.13 2004/03/04 19:31:48 yazhuk * Improved layout, labels spacing * * Revision 1.12 2004/03/02 21:54:12 yazhuk * Added rendering of origin and metric * * Revision 1.11 2004/02/17 15:23:10 yazhuk * Refactoring - replaced CGlParam with CGlAttrGuard * * Revision 1.10 2004/02/11 15:24:57 yazhuk * Fixed background rendering * * Revision 1.9 2003/12/23 17:39:19 yazhuk * Fixed bug with labels generation in "reverse" mode. * * Revision 1.8 2003/12/12 17:37:24 ivanov * Explicit using pow(double,double) to avoid compilation error on MSVC 7 * * Revision 1.7 2003/12/10 16:55:34 yazhuk * Implemented control over displayed range, offset and direction. * * Revision 1.6 2003/12/08 15:12:02 yazhuk * Fixed "first label is always 1" problem. Workaround for OpenGL * rounding/precision problems. * * Revision 1.5 2003/12/01 16:36:06 yazhuk * Improved labels layout algorithm and ruller ticks rendering . * * Revision 1.4 2003/11/18 17:57:08 yazhuk * Fixed GCC warnings * * Revision 1.3 2003/11/18 00:59:03 yazhuk * Restored IRenderable implementation * * Revision 1.2 2003/11/17 23:43:12 yazhuk * Fixed GCC compilation problem. * * Revision 1.1 2003/11/17 20:24:19 yazhuk * Renamed from ruller.cpp * * Revision 1.2 2003/10/31 14:04:18 dicuccio * Corrected spelling error: CRuller -> CRuler * * Revision 1.1 2003/10/29 23:18:28 yazhuk * Initial revision * * =========================================================================== */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?