cross_aln_render.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:18k
- /*
- * ===========================================================================
- * PRODUCTION $Log: cross_aln_render.cpp,v $
- * PRODUCTION Revision 1000.2 2004/06/01 21:06:30 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: cross_aln_render.cpp,v 1000.2 2004/06/01 21:06:30 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: Vlad Lebedev
- *
- */
- #include <ncbi_pch.hpp>
- #include "cross_aln_render.hpp"
- #include <gui/widgets/aln_crossaln/cross_aln_ds.hpp>
- #include <gui/widgets/seq_graphic/compact_policy.hpp>
- #include <gui/widgets/seq_graphic/default_layoutpolicy.hpp>
- #include <gui/opengl/glutils.hpp>
- #include <math.h>
- BEGIN_NCBI_SCOPE
- const TModelUnit kZoomFactorX = 2.0;
- const TModelUnit kLenseZoomFactor = 10.0;
- const TVPUnit kMaxPixelsBase = 12;
- CCrossAlnRenderer::CCrossAlnRenderer()
- {
- m_Offset2 = 0;
- m_DS = NULL;
- m_MinZoomX = log(1.0f / kMaxPixelsBase); // Enougth to fit seq. letters
-
- m_FP1.SetMinScaleX(1.0f / kMaxPixelsBase);
- m_FP1.EnableZoom(true, false);
- m_FP1.SetAdjustToLimits(true, false);
- m_FP1.EnableOffset(true);
-
- m_RP1.SetMinScaleX(1.0f / kMaxPixelsBase);
- m_RP1.EnableZoom(true, false);
- m_RP1.SetAdjustToLimits(true, false);
- m_CP.SetMinScaleX(1.0f / kMaxPixelsBase);
- m_CP.EnableZoom(true, false);
- m_CP.SetAdjustToLimits(true, false);
- m_CP.EnableOffset(true);
- m_FP2.SetMinScaleX(1.0f / kMaxPixelsBase);
- m_FP2.EnableZoom(true, false);
- m_FP2.SetAdjustToLimits(true, false);
- m_FP2.EnableOffset(true);
-
- m_RP2.SetMinScaleX(1.0f / kMaxPixelsBase);
- m_RP2.EnableZoom(true, false);
- m_RP2.SetAdjustToLimits(true, false);
- m_RulerPanel1.SetHorizontal(true, CRuler::eTop);
- // tune panels
- m_FeatPanel1.SetSelectedObjects(&m_SelectedObjects);
- m_FeatPanel2.SetSelectedObjects(&m_SelectedObjects);
-
- // add to containers
- m_AllPanes.push_back(&m_FP1);
- m_AllPanes.push_back(&m_RP1);
- m_AllPanes.push_back(&m_CP);
- m_AllPanes.push_back(&m_RP2);
- m_AllPanes.push_back(&m_FP2);
- m_ScrollXPanes1.push_back(&m_FP1);
- m_ScrollXPanes1.push_back(&m_RP1);
- m_ScrollXPanes1.push_back(&m_CP);
- m_ScrollXPanes2.push_back(&m_FP2);
- m_ScrollXPanes2.push_back(&m_RP2);
- m_AllRenderers.push_back(&m_FeatPanel1);
- m_AllRenderers.push_back(&m_RulerPanel1);
- m_AllRenderers.push_back(&m_CrossPanel);
- m_AllRenderers.push_back(&m_RulerPanel2);
- m_AllRenderers.push_back(&m_FeatPanel2);
-
- CRef<IPolicy> compact_policy(new CCompactPolicy());
- CRef<ILayoutPolicy> layout_policy(new CDefaultLayoutPolicy());
- m_FeatPanel1.SetRenderPolicy(compact_policy);
- m_FeatPanel2.SetRenderPolicy(compact_policy);
- m_FeatPanel1.SetLayoutPolicy(layout_policy);
- m_FeatPanel2.SetLayoutPolicy(layout_policy);
- }
- CCrossAlnRenderer::~CCrossAlnRenderer()
- {
- }
- void CCrossAlnRenderer::SetConfig(CRef<CSeqGraphicConfig> config)
- {
- m_FeatPanel1.SetConfig(config);
- m_FeatPanel2.SetConfig(config);
- }
- void CCrossAlnRenderer::Update()
- {
- CBioseq_Handle hndl1 = m_DS->GetQueryHandle();
- CBioseq_Handle hndl2 = m_DS->GetSubjectHandle();
-
- m_SeqLength1 = hndl1.GetBioseqLength();
- m_SeqLength2 = hndl2.GetBioseqLength();
- m_FeatPanel1.SetHandle(hndl1);
- m_FeatPanel2.SetHandle(hndl2);
- x_SetupModelLimits();
-
- ZoomOnAlignment();
-
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::SetDataSource(const TVPRect& rc, CCrossAlnDataSource* ds)
- {
- m_DS = ds;
-
- m_CrossPanel.SetDataSource(ds);
- x_SetupViewPorts(rc);
-
- m_MaxZoomX = log(m_FP1.GetModelLimitsRect().Width() / rc.Width());
- }
- void CCrossAlnRenderer::x_SetupViewPorts(const TVPRect& rc)
- {
- int kCrossPanelSize = 100;
-
- TVPUnit total = rc.Top();
- TVPUnit ruler_height = m_RulerPanel1.GetVPRect().Height();
- TVPUnit feat_height = (total - ruler_height * 2 - kCrossPanelSize) / 2;
- if (feat_height < 0) // panel resized too small
- feat_height = 0; // do not resize any more
-
- m_FP1.SetViewport( TVPRect(rc.Left(), total - feat_height, rc.Right(), total) );
- total -= feat_height;
-
- m_RP1.SetViewport( TVPRect(rc.Left(), total - ruler_height, rc.Right(), total) );
- total -= ruler_height;
-
- m_CP.SetViewport( TVPRect(rc.Left(), total - kCrossPanelSize, rc.Right(), total) );
- total -= kCrossPanelSize;
-
- m_RP2.SetViewport( TVPRect(rc.Left(), total - ruler_height, rc.Right(), total) );
- total -= ruler_height;
-
- m_FP2.SetViewport( TVPRect(rc.Left(), total - feat_height, rc.Right(), total) );
- }
- void CCrossAlnRenderer::x_SetupModelLimits()
- {
- if (!m_DS) return;
-
- m_Offset2 = m_DS->GetOffset();
- //cout << "offset: " << m_Offset2 << endl;
- //m_Offset2 = -200;
- TSignedSeqPos max_len = max(m_SeqLength1 - m_Offset2,
- m_SeqLength2 + m_Offset2);
-
- TModelRect rc1(0, 0, max_len + 1, m_FP1.GetViewport().Height());
-
- TModelRect rc2(0, 0, max_len + 1, m_RP1.GetViewport().Height());
-
- TModelRect rc3(0, 0, max_len + 1, m_RP2.GetViewport().Height());
-
- TModelRect rc4(0, m_FP2.GetViewport().Height(), max_len + 1, 0);
-
- TModelRect rcc(0, m_CP.GetViewport().Height(), max_len + 1, 0);
-
- m_RulerPanel1.SetRange(0, m_SeqLength1, 0, false);
- m_RulerPanel2.SetRange(0, m_SeqLength2, 0, false);
-
- m_FP1.SetModelLimitsRect(rc1);
- m_FP1.SetVisibleRect (rc1);
-
- m_RP1.SetModelLimitsRect(rc2);
- m_RP1.SetVisibleRect (rc2);
-
- m_CP.SetModelLimitsRect(rcc);
- m_CP.SetVisibleRect (rcc);
- m_RP2.SetModelLimitsRect(rc3);
- m_RP2.SetVisibleRect (rc3);
- m_FP2.SetModelLimitsRect(rc4);
- m_FP2.SetVisibleRect (rc4);
-
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::draw()
- {
- glClearColor(1.0f, 1.0f, 0.95f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- if ( !m_DS ) return;
-
- TModelRect rcVF1 = m_FP1.GetVisibleRect();
- TModelRect rcVF2 = m_FP2.GetVisibleRect();
-
- TModelRect& rcVR1 = m_RP1.GetVisibleRect();
- TModelRect& rcVR2 = m_RP2.GetVisibleRect();
- TModelRect& rcM1 = m_FP1.GetModelLimitsRect();
- TModelRect& rcM2 = m_FP2.GetModelLimitsRect();
- TModelRect tmp_rc;
- tmp_rc.SetLeft(0);
-
- // trick the feature panels that the model space begins with 0
- // (that will be moved to the feature panel later)
- if (m_Offset2 < 0) {
- rcVF1.Offset(+m_Offset2, 0);
- rcVR1.Offset(+m_Offset2, 0);
- tmp_rc.SetRight(m_SeqLength1);
- tmp_rc.SetTop(rcVF1.Top());
- tmp_rc.SetBottom(rcVF1.Bottom());
- TModelRect inrc = tmp_rc.IntersectWith(rcVF1);
- inrc.SetTop(rcVF1.Top());
- inrc.SetBottom(rcVF1.Bottom());
-
- m_FP1.SetVisibleRect(inrc);
- } else {
- rcVF2.Offset(-m_Offset2, 0);
- rcVR2.Offset(-m_Offset2, 0);
-
- tmp_rc.SetRight(m_SeqLength2);
-
- TModelRect inrc = tmp_rc.IntersectWith(rcVF2);
- inrc.SetTop(rcVF2.Top());
- inrc.SetBottom(rcVF2.Bottom());
-
- m_FP2.SetVisibleRect(inrc);
- }
-
- // retrieve and count data. This is temporary.
- TModelUnit rows1 = 0, rows2 = 0;
-
- if (m_FP1.GetVisibleRect().Width() != 0)
- rows1 = m_FeatPanel1.GetHeight(m_FP1);
- if (m_FP2.GetVisibleRect().Width() != 0)
- rows2 = m_FeatPanel2.GetHeight(m_FP2);
-
- // We have a "floating" model space. So, adjust the limits
- rcM1.SetTop(rows1);
- m_FP1.SetModelLimitsRect(rcM1);
- m_FP1.SetVisibleRect(rcVF1);
- rcM2.SetBottom(rows2);
- m_FP2.SetModelLimitsRect(rcM2);
- m_FP2.SetVisibleRect(rcVF2);
-
- // Finally, draw all panels
- for (size_t idx = 0; idx != m_AllRenderers.size(); idx++) {
- m_AllRenderers[idx]->Render( *m_AllPanes[idx] );
- }
-
-
- // Now set model space back to normal
- if (m_Offset2 < 0) {
- rcVF1.Offset(-m_Offset2, 0);
- rcVR1.Offset(-m_Offset2, 0);
-
- m_FP1.SetVisibleRect(rcVF1);
- m_RP1.SetVisibleRect(rcVR1);
- } else {
- rcVF2.Offset(+m_Offset2, 0);
- rcVR2.Offset(+m_Offset2, 0);
-
- m_FP2.SetVisibleRect(rcVF2);
- m_RP2.SetVisibleRect(rcVR2);
- }
- CGlUtils::CheckGlError();
- }
- void CCrossAlnRenderer::resize(const TVPRect& rc)
- {
- x_SetupViewPorts(rc);
-
- // prevent Y from resizing in feature panel
- TModelRect& rcV1 = m_FP1.GetVisibleRect();
- rcV1.SetTop(m_FP1.GetViewport().Height());
- rcV1.SetBottom(0);
- m_FP1.SetVisibleRect(rcV1);
- TModelRect& rcV2 = m_FP2.GetVisibleRect();
- rcV2.SetTop(0);
- rcV2.SetBottom( m_FP2.GetViewport().Height() );
- m_FP2.SetVisibleRect(rcV2);
-
- m_MaxZoomX = log(m_FP1.GetModelLimitsRect().Width() / rc.Width());
- }
- // this function takes an absolute mouse coordinate and determines if any
- // features lie underneath the mouse position
- // x & y are GL coordinates
- const CLayoutObject* CCrossAlnRenderer::HitTest(int x, int y)
- {
- // Main Feature Panel
- if (PanelHitTest(x, y) == eFeatures1) {
- return m_FeatPanel1.HitTest(m_FP1, x, y);
- }
- if (PanelHitTest(x, y) == eFeatures2) {
- return m_FeatPanel2.HitTest(m_FP2, x, y);
- }
- return NULL;
- }
- CCrossAlnRenderer::TRendererPanel
- CCrossAlnRenderer::PanelHitTest(int x, int y) const
- {
- if (m_FP1.GetViewport().PtInRect(x, y))
- return eFeatures1;
- if (m_FP2.GetViewport().PtInRect(x, y))
- return eFeatures2;
- if (m_CP.GetViewport().PtInRect(x, y))
- return eCross;
- return eNone;
- }
- CGlPane*
- CCrossAlnRenderer::PaneHitTest(int x, int y)
- {
- if (m_FP1.GetViewport().PtInRect(x, y))
- return &m_FP1;
- if (m_FP2.GetViewport().PtInRect(x, y))
- return &m_FP2;
- if (m_CP.GetViewport().PtInRect(x, y))
- return &m_CP;
- return NULL;
- }
- void CCrossAlnRenderer::GetTooltip(int x, int y, string* title)
- {
- *title = "";
-
- const CLayoutObject* obj = HitTest(x, y);
- if (!obj) return;
-
- TRendererPanel pan = PanelHitTest(x, y);
- if (pan == eFeatures1)
- m_FeatPanel1.GetTooltip(obj, title);
- if (pan == eFeatures2)
- m_FeatPanel2.GetTooltip(obj, title);
- }
- void CCrossAlnRenderer::SelectObject(const CObject* obj)
- {
- m_SelectedObjects.push_back(
- CRef<CObject>(const_cast<CObject*>(obj)));
- }
- float CCrossAlnRenderer::GetZoomX(void) const
- {
- TModelUnit scale_x = log(m_FP1.GetScaleX());
- return 1.0f - (scale_x - m_MinZoomX) / (m_MaxZoomX - m_MinZoomX);
- }
- void CCrossAlnRenderer::SetZoomX(float value)
- {
- // slider is set up from 0 to 1. Convert to our units:
- TModelUnit scale = m_MinZoomX + (m_MaxZoomX - m_MinZoomX) * (1.0f - value);
- NON_CONST_ITERATE(TGlPanes, iter, m_ScrollXPanes1) {
- CGlPane& pane = **iter;
- pane.SetScale(exp(scale), pane.GetScaleY(),
- pane.GetVisibleRect().CenterPoint() );
- }
- }
- void CCrossAlnRenderer::ZoomInCenter()
- {
- ITERATE(TGlPanes, iter, m_ScrollXPanes1) {
- (*iter)->ZoomInCenter();
- }
- }
- void CCrossAlnRenderer::ZoomOutCenter()
- {
- ITERATE(TGlPanes, iter, m_ScrollXPanes1) {
- (*iter)->ZoomOutCenter();
- }
- }
- void CCrossAlnRenderer::x_AdjustCrossPane()
- {
- TModelUnit p_scale = m_CP.GetScaleX() / m_FP2.GetScaleX();
- m_CrossPanel.SetProportions(p_scale, m_Offset2);
- m_CrossPanel.SetShifts(m_FP1.GetVisibleRect().Left(),
- m_FP2.GetVisibleRect().Left());
- }
- void CCrossAlnRenderer::SetScaleRef1(TModelUnit scale_x, TModelUnit scale_y,
- const TModelPoint& point)
- {
- if(scale_x > m_FP1.GetMinScaleX())
- {
- ITERATE(TGlPanes, iter, m_ScrollXPanes1) {
- TModelPoint ref_p(point.X(), (*iter)->GetVisibleRect().Top());
- (*iter)->SetScaleRefPoint(scale_x, *iter == &m_CP ? -1 : 1, ref_p);
- }
- }
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::SetScaleRef2(TModelUnit scale_x, TModelUnit scale_y,
- const TModelPoint& point)
- {
- if(scale_x > m_FP2.GetMinScaleX())
- {
- ITERATE(TGlPanes, iter, m_ScrollXPanes2) {
- TModelPoint ref_p(point.X(), (*iter)->GetVisibleRect().Top());
- (*iter)->SetScaleRefPoint(scale_x, *iter == &m_RP2 ? 1 : -1, ref_p);
- }
- }
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::SetScaleRefC(TModelUnit scale_x, TModelUnit scale_y,
- const TModelPoint& point)
- {
- if(scale_x > m_CP.GetMinScaleX())
- {
- ITERATE(TGlPanes, iter, m_AllPanes) {
- TModelPoint ref_p(point.X(), (*iter)->GetVisibleRect().Top());
- (*iter)->SetScaleRefPoint(scale_x,
- (*iter == &m_CP || *iter == &m_FP2) ? -1 : 1, ref_p);
- }
- }
-
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::ZoomOnObject(const CLayoutObject* obj)
- {
- if (!obj)
- return;
-
- TSeqRange range = obj->GetLocation().GetTotalRange();
- ZoomOnRange(range);
- }
- void CCrossAlnRenderer::ZoomOnRange(const TSeqRange& range)
- {
- ITERATE(TGlPanes, iter, m_AllPanes) {
- TModelRect rc = (*iter)->GetVisibleRect();
- rc.SetLeft (range.GetFrom());
- rc.SetRight (range.GetTo());
- (*iter)->ZoomRect(rc);
- }
- x_AdjustCrossPane();
- }
- void CCrossAlnRenderer::ZoomOnAlignment()
- {
- const TSeqRange& range = m_DS->GetTotalRange();
- ZoomOnRange(range);
- }
- void CCrossAlnRenderer::FitToWindow(void)
- {
- // FixMe
- }
- void CCrossAlnRenderer::ZoomToSequence(void)
- {
- // FixMe
- }
- CGlPane& CCrossAlnRenderer::GetFeatGlPane1()
- {
- return m_FP1;
- }
- CGlPane& CCrossAlnRenderer::GetFeatGlPane2()
- {
- return m_FP2;
- }
- CGlPane& CCrossAlnRenderer::GetCrossGlPane()
- {
- return m_CP;
- }
-
- void CCrossAlnRenderer::Scroll(TModelUnit x1, TModelUnit y1,
- TModelUnit x2, TModelUnit y2)
- {
- const TModelRect& rc1 = m_FP1.GetVisibleRect();
- const TModelRect& rc2 = m_FP2.GetVisibleRect();
-
- double dX1 = x1 - rc1.Left();
- double dY1 = y1 - rc1.Bottom();
- double dX2 = x2 - rc2.Left();
- double dY2 = y2 - rc2.Top();
-
- // Handle horizintal scrollbar
- ITERATE(TGlPanes, iter, m_ScrollXPanes1)
- (*iter)->Scroll(dX1, 0.0f);
-
- ITERATE(TGlPanes, iter, m_ScrollXPanes2)
- (*iter)->Scroll(dX2, 0.0f);
-
- m_FP1.Scroll(0.0f, dY1); // Handle vertical scrollbar 1
- m_FP2.Scroll(0.0f, dY2); // Handle vertical scrollbar 2
- x_AdjustCrossPane();
- }
- TModelUnit CCrossAlnRenderer::GetScrollLineSize1()
- {
- m_FP1.OpenOrtho();
- TModelUnit value = m_FP1.UnProjectWidth(kMaxPixelsBase);
- m_FP1.Close();
-
- return value;
- }
- TModelUnit CCrossAlnRenderer::GetScrollLineSize2()
- {
- m_FP2.OpenOrtho();
- TModelUnit value = m_FP2.UnProjectWidth(kMaxPixelsBase);
- m_FP2.Close();
-
- return value;
- }
-
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: cross_aln_render.cpp,v $
- * Revision 1000.2 2004/06/01 21:06:30 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
- *
- * Revision 1.13 2004/05/21 22:27:52 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.12 2004/05/14 15:57:18 lebedev
- * Optional argument to specify the type of title/tooltip added
- *
- * Revision 1.11 2004/04/16 12:44:37 lebedev
- * Use default layout policy for both feature panels.
- *
- * Revision 1.10 2004/03/11 17:50:41 dicuccio
- * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange
- * instead of TRange
- *
- * Revision 1.9 2004/02/13 19:00:07 lebedev
- * Do not use EnableViewOption in graphical widget any more
- *
- * Revision 1.8 2004/01/30 17:18:47 dicuccio
- * Use CBioseq_Handle::GetBioseqLength() instead of creating a CSeqVector
- *
- * Revision 1.7 2004/01/27 16:20:41 lebedev
- * Changed stored selection from CLayoutObject to CObject
- *
- * Revision 1.6 2004/01/20 18:19:53 dicuccio
- * Minot code rearrangement
- *
- * Revision 1.5 2004/01/16 19:17:06 tereshko
- * Removed const modifyer for GetTooltip method
- *
- * Revision 1.4 2004/01/16 13:40:39 lebedev
- * Tooltips added
- *
- * Revision 1.3 2003/12/22 19:37:43 dicuccio
- * Fixed compiler warnings about double -> float conversion
- *
- * Revision 1.2 2003/12/22 16:51:32 lebedev
- * Use CHitElemDataAdapter to get start/length from datasource
- *
- * Revision 1.1 2003/12/22 13:12:33 lebedev
- * Initial revision
- *
- * ===========================================================================
- */