align_row.cpp

来自「ncbi源码」· C++ 代码 · 共 1,105 行 · 第 1/3 页

CPP
1,105
字号
                s_tip += ", on Sequence ";                s_tip += FormatRange(seq_r.GetFrom(), seq_r.GetTo() + 1);                s_tip += " : ";                s_tip += seq;            }   else if(type == 0)   {                // generate string for gap                s_tip += "\nGap ";                s_tip += FormatRange(aln_r.GetFrom() + 1, aln_r.GetTo() + 1);                s_tip += ", on Sequence ";                s_tip += FormatRange(seq_r.GetFrom() + 1, seq_r.GetTo() + 1);            }        }    }    return s_tip;}void    CAlnVecRow::x_OnClickExpandBtn(){    fl_cursor(FL_CURSOR_WAIT);    Expand(! IsExpanded());    fl_cursor(FL_CURSOR_DEFAULT);}/// Renders graphical part of the rowvoid    CAlnVecRow::x_RenderAlign(CGlPane& pane){    _ASSERT(m_pStyle);    pane.OpenOrtho();    TModelUnit offset_x = pane.GetOffsetX();    TModelUnit offset_y = pane.GetOffsetY();    TModelRect rc_lim = pane.GetModelLimitsRect();    TModelRect rc_model = pane.GetVisibleRect();    TModelUnit y2 = rc_lim.Top() + kAlignSpace - offset_y;    TModelUnit y1 = rc_lim.Top() + m_BaseHeight -1 - kAlignSpace - offset_y;    TSeqPos row_start = m_Handle.GetSeqAlnStart();    TSeqPos row_stop = m_Handle.GetSeqAlnStop();    glLineWidth(1.0f);    glColorC(m_pStyle->GetAlignColor());    // now render segments actually present    unsigned Left = (unsigned) floor(rc_model.Left());    unsigned Right = (unsigned) ceil(rc_model.Right());    CAlnMap::TSignedRange Range(Left, Right);    // render aligned segments    CRef<CAlnVec::CAlnChunkVec> vAlnChunks = m_Handle.GetAlnChunks(Range, CAlnVec::fSkipInserts);    if(m_pCache)    { // render parts of chunks accordingly to scores        pane.Close();        x_RenderAlignScores(pane, vAlnChunks);        pane.OpenOrtho();    } else { // scores are not available - render all chunks with a default color        // render a single line for all possible gaps        TModelUnit Yc = (y2 + y1) / 2;        glBegin(GL_LINES);        glLined(row_start - offset_x, Yc, row_stop - offset_x, Yc);        glEnd();        x_RenderAlignSegments(pane, vAlnChunks, (int) y1, (int) y2);    }    // render inserts    CRef<CAlnVec::CAlnChunkVec> vChunks = m_Handle.GetAlnChunks(Range, CAlnVec::fInsertsOnly);    glColor3d(0, 0, 0.5);    glBegin(GL_LINES);    for (int i = 0;  i < vChunks->size();  i++) {        CConstRef<CAlnMap::CAlnChunk> chunk = (*vChunks)[i];        _ASSERT(chunk->GetType() & CAlnMap::fSeq);        _ASSERT(chunk->GetType() & CAlnMap::fNotAlignedToSeqOnAnchor);        TModelUnit ins_pos = chunk->GetAlnRange().GetFrom() - offset_x;        TModelUnit len = chunk->GetRange().GetLength();        TModelUnit x1 = ins_pos - len / 2;        TModelUnit x2 = x1 + len;        // assuming glBegin(GL_LINES)        glLined(ins_pos, y1, ins_pos, y2);        glLined(x1, y1, x2, y1);        glLined(x1, y2, x2, y2);    }    glEnd();    // render sequence if its visible    if(x_CanRenderSeq(pane))    {        double H = m_pStyle->GetSeqFont().TextHeight();        double y = floor((y1 + y2 + H) / 2);        x_RenderSequence(pane, y, Left, Right);    }    pane.Close();    x_RenderGraph(pane, vAlnChunks);}void    CAlnVecRow::x_RenderAlignSegments(CGlPane& pane, TRefChunks& chunks, int top_y, int bottom_y){    glColorC(m_pStyle->GetAlignColor());    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);    TModelUnit offset_x = pane.GetOffsetX();    for (int i = 0;  i < chunks->size();  i++) {        CConstRef<CAlnMap::CAlnChunk> chunk = (*chunks)[i];        if((chunk->GetType() & CAlnMap::fSeq))  {            _ASSERT((chunk->GetType() & CAlnMap::fNotAlignedToSeqOnAnchor) == 0);            const TSignedSeqRange& R = chunk->GetAlnRange();            glRectd(R.GetFrom() - offset_x, top_y,                    R.GetToOpen() - offset_x, bottom_y);        }    }}/// Renders alignment (graphical) part of the row according to scores./// Score intervals are rendered differently depending on their size./// Long intervals ("long" meaning covering more than one full pixel) are rendered in/// "vector" mode - the series of pixels corresponding to a single interval/// is drawn as a single rectangle with color defined by the intreval's score./// Short intervals are rendered in "raster" mode - algorithm iterates by intervals/// and calculates average and maximal scores corresponding to a particular pixel,/// then each pixel is drawn with its individual color.void    CAlnVecRow::x_RenderAlignScores(CGlPane& pane, TRefChunks& chunks){    pane.OpenPixels();    const TVPRect& rc_vp = pane.GetViewport();    const TModelRect rc_vis = pane.GetVisibleRect();    glTranslated(0.0, rc_vp.Top(), 0.0); // to make the display list "scrollable" vertically    // if horz projection has changed - invalidate display list    if(m_PixLeft != rc_vp.Left()  ||  m_PixRight != rc_vp.Right()        ||  m_ModelLeft != rc_vis.Left()  ||  m_ModelRight != rc_vis.Right())    {        m_DList.Invalidate();        m_PixLeft = rc_vp.Left();        m_PixRight = rc_vp.Right();        m_ModelLeft = rc_vis.Left();        m_ModelRight = rc_vis.Right();    }    if(m_DList.IsValid())   {        m_DList.Call();    } else { // need to create a new one        m_DList.Begin(GL_COMPILE_AND_EXECUTE);        TModelUnit  left = rc_vis.Left();        TModelUnit  scale_x = pane.GetScaleX();        int range_pix_start = rc_vp.Left();        int range_pix_end = rc_vp.Right();        // visible alignment range in seq coords        int range_from = (int) (floor(left));        // int range_to_open = (int) (ceil(pane.GetVisibleRect().Right()));        int top_y = - kAlignSpace;        int bottom_y = - m_BaseHeight + kAlignSpace;        int off_y = 0, extr_off_y = 0;        // obtain Score Collection and setup iterators        const CScoreCache::TScoreColl& ScoreColl = m_pCache->GetScores(m_Handle.GetRowNum());        CScoreCache::TScoreColl::const_iterator it = ScoreColl.begin();        const CScoreCache::TScoreColl::const_iterator it_end = ScoreColl.end();        it = ScoreColl.find(it, it_end, range_from);        double int_score;        double  pix_start, pix_end;        double  score_sum = 0, score_min = 0, score_len = 0;        bool    b_first = true;     // "true" if pixel is being processed for the first time        bool    b_new_interval = true;        bool b_lines = true;        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);        glBegin(GL_LINES);        int i_prev_chunk = -1, i_chunk = 0, n_chunks = chunks->size();        CConstRef<CAlnMap::CAlnChunk> chunk;        // [pos_start, pos_end) defines range being processed        int pos_start = -1, pos_end = range_from;        bool b_skip  = false;        // iterate by pixels, score intervals and chunks        for( int pix = range_pix_start;             pix <= range_pix_end  &&  it != it_end  &&  i_chunk < n_chunks;  )        {            if(i_prev_chunk != i_chunk) {                chunk = (*chunks)[i_chunk];                int type = chunk->GetType();                b_skip = false;                if(type & CAlnMap::fSeq)    { // aligned segment                    off_y = 0;                    extr_off_y = kExtremeArea;                } else if(type & (CAlnVec::fNoSeqOnRight | CAlnVec::fNoSeqOnLeft))    {                    // empty space - do not draw anything                    b_skip = true;                } else { // gap                    off_y =  kGapOffset ;                    extr_off_y = kGapOffset + kGapExtremeArea;                }            }            if(b_new_interval)    { // new range                int_score = it->GetAttr();            }            if(i_chunk != i_prev_chunk  ||  b_new_interval) {                // [pos_start, pos_end) is defined as intersection of current score interval                // and current chunk                pos_start = pos_end;                pos_end = min((int) chunk->GetAlnRange().GetToOpen(), (int) it->GetToOpen());                // transform from seq. coords to pixels                pix_start = range_pix_start + ((double) (pos_start - left)) / scale_x;                pix_end = range_pix_start + ((double) (pos_end - left)) / scale_x;                i_prev_chunk = i_chunk;                b_new_interval = false;            }            if(b_skip  &&  (pix_start <= pix  &&  pix_end >= pix + 1))    {                int strip_end = (int) ceil(pix_end) - 1;                if(! b_skip)    {                if(b_lines) {                    glEnd();                    b_lines = false;                }                // interval covers current pixel and may be consequent pixels                // draw them in one iteration                glColorC(m_pCache->GetColorForScore(int_score));                glRectd(pix, top_y - off_y, strip_end, bottom_y + off_y);                }                pix = strip_end;                b_first = true;            }            //[start, end] specify part of the pixel covered by current score interval            double start = max((double) pix, pix_start);            double end = min((double) pix + 1, pix_end);            double len = end - start;            _ASSERT(len >= 0.0  && len <= 1.0);            double d_score = len * int_score;            if(b_first) {  // new pixel - reset assign values to accumulators                score_min = int_score;                score_sum = d_score;                score_len = len;                b_first = false;            } else { // accumulate                score_min = min(score_min, int_score);                score_sum += d_score;                score_len += len;            }            if(pix_end < pix + 1)    {  // current range ends before current pixel                if(it->GetToOpen() <= pos_end)  { // advance score interval                    it++;                    b_new_interval = true;                }                if(chunk->GetAlnRange().GetToOpen() <= pos_end)  { // advance chunk                    i_chunk++;                }            } else { // pixel is fully covered with current range - draw the pixel                if(! b_lines)   {                    glBegin(GL_LINES);                    b_lines = true;                }                double sc = score_sum / score_len;                bool b_diff = (score_min != sc);                glColorC(m_pCache->GetColorForScore(b_diff ? score_min : sc));                glLined(pix, top_y - off_y, pix, bottom_y + off_y);                if(b_diff) {                    glColorC(m_pCache->GetColorForScore(sc));                    glLined(pix, top_y - extr_off_y, pix, bottom_y + extr_off_y);                }                pix++;                b_first = true;            }        }        if(b_lines) {            glEnd();        }        m_DList.End();    }    glTranslated(0.0, -rc_vp.Top(), 0.0);    pane.Close();}#define SEQ_OFF_VERT 0#define SEQ_OFF_HORZ 0/// Checks if sequence can be drawn.bool CAlnVecRow::x_CanRenderSeq(CGlPane& pane){    if(m_pStyle)    {        double min_w = 1.0 / m_pStyle->GetSeqFont().GetMetric(CGlBitmapFont::eMetric_MaxCharWidth);        double scale_x = pane.GetScaleX();        return min_w >= scale_x;    } else return false;}// renders a row of seq symbols in the range [Start, Stop]void CAlnVecRow::x_RenderSequence(CGlPane& pane, float y, int start, int stop){    _ASSERT(m_pStyle);    string seq;    m_Handle.GetAlnSeqString(seq, CAlnVec::TSignedRange(start, stop));    replace(seq.begin(), seq.end(), '-', ' ');    glColorC(m_pStyle->GetAlignTextColor());    float x = start + 0.5 - pane.GetOffsetX();    m_pStyle->GetSeqFont().ArrayTextOut(x, y, 1.0f, 0.0f, seq.c_str(),                             (float) pane.GetScaleX(), 0.0f);}static const int kTextOffsetY = 0;static const int kTextOffsetX = 2;static const int kPosOffsetX = 4;void    CAlnVecRow::x_RenderDescr(CGlPane& pane, int state){    _ASSERT(m_pStyle);    pane.OpenPixels();    TVPRect rc_vp = pane.GetViewport();    bool b_wid_focused = (state & fWidgetFocused) != 0;    //draw background    if(state & fItemSelected) {        if(b_wid_focused)   {            glColorC(m_pStyle->GetSelBackFocusedColor());        } else {            glColorC(m_pStyle->GetSelBackColor());        }        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);        glRectd(rc_vp.Left(), rc_vp.Bottom() - 1, rc_vp.Right(), rc_vp.Top());    }    // draw text label    glColorC((state & fItemSelected) != 0 ? m_pStyle->GetSelTextColor()                                          : m_pStyle->GetTextColor());    int x = rc_vp.Left() + kTextOffsetX;    int w = rc_vp.Width() - kTextOffsetX;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?