align_row.cpp

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

CPP
1,105
字号
/* * =========================================================================== * PRODUCTION $Log: align_row.cpp,v $ * PRODUCTION Revision 1000.5  2004/06/01 21:07:00  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.41 * PRODUCTION * =========================================================================== *//*  $Id: align_row.cpp,v 1000.5 2004/06/01 21:07:00 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors:  Andrey Yazhuk * * File Description: * */#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbitime.hpp>#include <math.h>#include <gui/types.hpp>#include <gui/opengl/glhelpers.hpp>#include <gui/opengl/glbitmapfont.hpp>#include <objmgr/graph_ci.hpp>#include <objects/general/Dbtag.hpp>#include <objects/general/Object_id.hpp>#include <gui/widgets/aln_multiple/align_row.hpp>#include <gui/widgets/aln_multiple/aln_scoring.hpp>#include <gui/widgets/aln_multiple/trace_graph.hpp>#include <objmgr/util/sequence.hpp>#include <FL/Fl.H>BEGIN_NCBI_SCOPEUSING_SCOPE(ncbi::objects);///////////////////////////////////////////////////////////////////////////////////const CGlColor&   CAlnVecRowDisplayStyle::GetAlignTextColor() const{    return m_AlignTextColor;}const CGlColor&   CAlnVecRowDisplayStyle::GetAlignColor() const{    return m_AlignColor;}/////////////////////////////////////////////////////////////////////////////////// CAlnVecRowCAlnVecRow::CAlnVecRow(const CAlnVecRowHandle& handle):   m_Handle(handle),    m_pHost(NULL),    m_BaseHeight(0),    m_bExpanded(false),    m_pStyle(NULL),    m_pCache(NULL),    m_pGraph(NULL),    m_PixLeft(-1), m_PixRight(-1), m_ModelLeft(-1), m_ModelRight(-1){    const CSeq_id& id = sequence::GetId(m_Handle.GetBioseqHandle(),                                        sequence::eGetId_Best);    id.GetLabel(&m_Text);    /// instantiate but do not create    m_pGraph = new CTraceGraph(handle.GetBioseqHandle(), handle.IsNegativeStrand());    m_bExpanded = false;}CAlnVecRow::~CAlnVecRow(){    delete m_pGraph;    m_DList.Delete();    m_pStyle = NULL; //do not delete}void    CAlnVecRow::x_CreateGraph(){    m_pGraph->Create();}void    CAlnVecRow::x_DestroyGraph(){    m_pGraph->Destroy();}void    CAlnVecRow::SetScoreCache(CScoreCache* cache){    m_pCache = cache;}void    CAlnVecRow::GraphicsCacheCmd(EGraphCacheCmd cmd){    switch(cmd) {    case eInvalidate: m_DList.Invalidate(); break;    case eDelete: m_DList.Delete(); break;    }}void    CAlnVecRow::GetHTMLActiveAreas(EColumnType col_type, CGlPane& pane, TAreaVector& areas){    switch(col_type)    {    case eIcons:    {        string s_row = NStr::IntToString(m_Handle.GetRowNum());        CHTMLActiveArea area(CHTMLActiveArea::eCheckBox,                             x_GetButtonRect(pane, eExpand),                            s_row, "Click to expand/collapse", "toggle_expand");        areas.push_back(area);    }; break;    case eAlignment:    {        // create area for alignment        TSignedSeqPos start = m_Handle.GetSeqAlnStart();        TSignedSeqPos stop = m_Handle.GetSeqAlnStop();        const TModelRect& rc_vis = pane.GetVisibleRect();        start = max(start, (TSignedSeqPos) floor(rc_vis.Left()) );        stop = min(stop, (TSignedSeqPos) ceil(rc_vis.Right()) );                pane.OpenOrtho();        pane.Close();        TVPUnit vp_start = pane.ProjectX(start);        TVPUnit vp_stop = pane.ProjectX(stop);        TVPRect rc = pane.GetViewport();        rc.SetHorz(vp_start, vp_stop);                string s_row = NStr::IntToString(m_Handle.GetRowNum());        CHTMLActiveArea area(CHTMLActiveArea::eLink, rc,                             s_row, m_Text, "");        areas.push_back(area);    }; break;    default: break;    };}/// height of "white-space" between row borders and alignment bandstatic const int kAlignSpace = 2;/// height of sub-bands where the colored according to the exreme score values (min or max)static const int kExtremeArea = 3;static const int kGapExtremeArea = 1;/// vertical offset from the border of the alignment band to the border of gap bandstatic const int kGapOffset = 4;static const int kTextVertSpace = 1;static const int kSeqVertSpace = kAlignSpace + 2;void    CAlnVecRow::SetDisplayStyle(const CRowDisplayStyle* style){    m_pStyle = dynamic_cast<const CAlnVecRowDisplayStyle*>(style);    float h1 = kTextVertSpace * 2;    float h2 = kSeqVertSpace * 2;    if(m_pStyle)    {        h1 += m_pStyle->GetTextFont().TextHeight();        h2 += m_pStyle->GetSeqFont().TextHeight();    }    m_Height = m_BaseHeight = (int) max(h1, h2);    if(m_bExpanded) {        if(m_pGraph)   {            m_Height += m_pGraph->GetPreferredHeight();        }    }}const CRowDisplayStyle*    CAlnVecRow::GetDisplayStyle(){    return m_pStyle;}void    CAlnVecRow::SetHost(IAlignRowHost* pHost){    m_pHost = pHost;}int CAlnVecRow::GetRowNum()  const{    return m_Handle.GetRowNum();}int CAlnVecRow::GetHeightPixels()    const{    return m_Height;}void    CAlnVecRow::RenderColumn(EColumnType  col_type, CGlPane& pane, int State){    CGlAttrGuard AttrGuard(GL_POLYGON_MODE);    if(m_pStyle)    {        switch(col_type) {        case eDescr:    x_RenderDescr(pane, State); break;        case eIcons: x_RenderIcons(pane); break;        case eStart: x_RenderStartPos(pane); break;        case eAlignment:    x_RenderAlign(pane); break;        case eEnd: x_RenderEndPos(pane); break;        case eSeqEnd: x_RenderSeqEnd(pane); break;        default: break; // unknown column        }    }}int     CAlnVecRow::handle(CGUIEvent& event, EColumnType  col_type, CGlPane& pane){    switch(event.GetFLTKEvent())    {    case FL_PUSH: {        if(Fl::event_button() == FL_LEFT_MOUSE) {            TVPPoint pt = x_GetHost()->ARH_GetVPMousePos();            TVPRect rc_btn = x_GetButtonRect(pane, eExpand);            if(rc_btn.PtInRect(pt)) {                x_OnClickExpandBtn();                return 1;            }        }    }; break;    default: break;    }    return 0;}static const int kTooltipMaxLines = 5;static const int kMaxSeqInTooltip = 20;string  CAlnVecRow::GetTooltip(EColumnType col_type, CGlPane& pane){    switch(col_type) {    case eIcons: return x_GetIconsTooltip(pane);    case eStart: return "First visible position in sequence coordinates";    case eAlignment:    return x_GetAlignmentTooltip(pane);    case eEnd: return "Last visible position in sequence coordinates";    case eSeqEnd: return "Last position in sequence";    default: break;    }    return "";}string  CAlnVecRow::x_GetIconsTooltip(CGlPane& pane){    _ASSERT(x_GetHost());    string s_tip;    TVPPoint pt = x_GetHost()->ARH_GetVPMousePos();    TVPRect rc_btn = x_GetButtonRect(pane, eExpand);    if(rc_btn.PtInRect(pt)) {        if(IsExpandable())    {            s_tip = "Click to ";            s_tip += m_bExpanded ? "collapse" : "expand";        } else {            s_tip = "Nothing to expand";        }    } else {        rc_btn = x_GetButtonRect(pane, eSetupGraphs);        if(rc_btn.PtInRect(pt)) {            s_tip = "Setup Graphs";        }    }    return s_tip;}#define TOOLTIP_RANGE_PIX 3inline  void    glLined(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2){    glVertex2d(x1, y1);    glVertex2d(x2, y2);}string  FormatRange(TSignedSeqPos from, TSignedSeqPos to){    string s =  NStr::IntToString(to + 1);    s += "-";    s += NStr::IntToString(to + 1);    return s;}string  CAlnVecRow::x_GetAlignmentTooltip(CGlPane& pane){    pane.OpenOrtho();    pane.Close();    double w_x = pane.UnProjectX(Fl::event_x());    double pix_w = pane.UnProjectWidth(TOOLTIP_RANGE_PIX);    // append Name and Position    string s_tip = m_Text;    if(m_Handle.IsNegativeStrand())        s_tip += ", Negative Strand";    TSeqPos pos = (TSeqPos) w_x;    s_tip += string("\nPos ") + NStr::IntToString(pos + 1);    TSignedSeqPos seq_pos = m_Handle.GetSeqPosFromAlnPos(pos);    if(seq_pos >= 0)    {        s_tip += ", on Sequence ";        s_tip += NStr::IntToString(seq_pos + 1);    }    // Append information on gaps and inserts    TSeqPos start = (TSeqPos) floor(w_x - pix_w / 2);    TSeqPos end = (TSeqPos) ceil(w_x + pix_w / 2);    CAlnMap::TSignedRange range(start, end);    // obtain chunks in the range [start, end]    CRef<CAlnVec::CAlnChunkVec> v_chunks =  m_Handle.GetAlnChunks(range,                      CAlnVec::fAllChunks | CAlnVec::fDoNotTruncateSegs);    int chunks_n = min((int) v_chunks->size(), kTooltipMaxLines);    if(chunks_n)   { // show chunks tooltip        string seq;        for (int i = 0;  i < chunks_n;  i++) {            CConstRef<CAlnMap::CAlnChunk> chunk = (*v_chunks)[i];            CAlnMap::TSegTypeFlags type  = chunk->GetType();            const TSignedSeqRange& aln_r = chunk->GetAlnRange();            const TSignedSeqRange& seq_r = chunk->GetRange();            if((type & CAlnMap::fSeq)  &&  (type & CAlnMap::fNotAlignedToSeqOnAnchor))  { //insert                //generate string for sequence                TSeqRange seq_r(chunk->GetRange().GetFrom(), chunk->GetRange().GetTo());                bool b_ellipsis = false;                if((int) seq_r.GetLength() > kMaxSeqInTooltip)    { // to long to be displayed                    seq_r.SetToOpen(seq_r.GetFrom() + kMaxSeqInTooltip);                    b_ellipsis = true;                }                m_Handle.GetSeqString(seq, seq_r);                if(b_ellipsis)                    seq += "...";                // generate a string for the chunk                TSeqPos aln_left = aln_r.GetToOpen(); // a bit of hack                s_tip += "\nInsert ";                s_tip += FormatRange(aln_left, aln_left + 1);

⌨️ 快捷键说明

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