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 + -
显示快捷键?