glpane.cpp

来自「ncbi源码」· C++ 代码 · 共 767 行 · 第 1/2 页

CPP
767
字号
/* * =========================================================================== * PRODUCTION $Log: glpane.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 20:50:55  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11 * PRODUCTION * =========================================================================== *//*  $Id: glpane.cpp,v 1000.3 2004/06/01 20:50:55 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 <gui/opengl/glpane.hpp>#include <gui/opengl/glutils.hpp>#include <math.h>BEGIN_NCBI_SCOPE////////////////////////////////////////////////////////////////////////////////// CGlPaneCGlPane::CGlPane(EProjMatrixPolicy policy): m_prcClip(NULL),  m_Mode(eNone),  m_MatrixPolicy(policy),  m_AdjustX(fAdjustAll),  m_AdjustY(fAdjustAll),  m_bEnableOffset(false),  m_bZoomEnX(true),  m_bZoomEnY(true),  m_ZoomFactor(2.0),  m_bProportionalMode(false),  m_TypeX(eOriginLeft), m_TypeY(eOriginBottom),  m_MinScaleX(0), m_MinScaleY(0){}CGlPane::~CGlPane(){   // _ASSERT(m_Mode == eNone); // should be closed first}void    CGlPane::SetViewport(const TVPRect& r){    m_rcVP = r;        // applying constraints    x_CorrectScale(m_rcOrigVisible.CenterPoint());    x_ScaleToFitLimits();    x_ShiftToFitLimits();    x_AdjustVisibleRect();}void    CGlPane::SetVisibleRect(const TModelRect& r){    m_rcVisible = m_rcOrigVisible = r;}TModelUnit  CGlPane::GetScaleX(void) const{    return m_rcVisible.Width() / m_rcVP.Width();}TModelUnit  CGlPane::GetScaleY(void) const{    return m_rcVisible.Height() / m_rcVP.Height();}TModelUnit    CGlPane::GetZoomAllScaleX(void) const{    return m_rcLimits.Width() / m_rcVP.Width();}TModelUnit    CGlPane::GetZoomAllScaleY(void) const{    return m_rcLimits.Height() / m_rcVP.Height();}inline void    CGlPane::x_AssertNotOpen(void) const{    _ASSERT(GetProjMode() == eNone);}inline void    CGlPane::x_AssertOrtho(void) const{    _ASSERT(GetProjMode() == eOrtho);}           bool    CGlPane::Open(EProjectionMode mode){        _ASSERT(mode != eNone);    _ASSERT(m_Mode == eNone); //should not be already open     bool ok = false;    if (mode != m_Mode) {        switch (mode) {        case eOrtho: {            ok = x_OpenOrtho();            break;        }        case ePixels: {            ok = x_OpenPixels();            break;        }        default: _ASSERT(false); //other modes are unsupported        } //switch    }     if (ok) {        m_Mode = mode;    }    return ok;}void    CGlPane::Close(void){    _ASSERT(m_Mode != eNone); // should be open    if(m_Mode != eNone)    {        glMatrixMode(GL_PROJECTION);        //glPopMatrix();        glDisable(GL_SCISSOR_TEST);        m_Mode = eNone;    }}inline void    CGlPane::x_Open_SetViewport(){    _ASSERT(m_rcVP.Width()  &&  m_rcVP.Height());        glViewport(m_rcVP.Left(), m_rcVP.Bottom(), m_rcVP.Width(), m_rcVP.Height());    // setup clipping    glEnable(GL_SCISSOR_TEST);    TVPRect rc_cl(m_rcVP);    if(m_prcClip) { //additional clip rect has been provided        rc_cl.IntersectWith(*m_prcClip);    }    glScissor(rc_cl.Left(), rc_cl.Bottom(), rc_cl.Width(), rc_cl.Height());}bool    CGlPane::x_OpenOrtho(){    x_Open_SetViewport();    glMatrixMode(GL_PROJECTION);    //glPushMatrix();    glLoadIdentity();    TModelUnit half_pix_w = m_rcVisible.Width() / (2 * m_rcVP.Width());    TModelUnit half_pix_h = m_rcVisible.Height() / (2 * m_rcVP.Height());        TModelUnit left, right, top, bottom;    if(m_bEnableOffset) {        left = bottom = 0.0;        right = m_rcVisible.Width();        top = m_rcVisible.Height();    } else {        left = m_rcVisible.Left();        right = m_rcVisible.Right();        bottom = m_rcVisible.Bottom();        top = m_rcVisible.Top();    }    gluOrtho2D( left - half_pix_w, right + half_pix_w,                 bottom - half_pix_h, top + half_pix_h);                glMatrixMode(GL_MODELVIEW);    switch(m_MatrixPolicy)  {    case eNeverUpdate: break;    case eAlwaysUpdate:  x_UpdateProjectMatrices(); break;    }            return true;}bool    CGlPane::x_OpenPixels(){    x_Open_SetViewport();            glMatrixMode(GL_PROJECTION);    //glPushMatrix();    glLoadIdentity();    glOrtho(m_rcVP.Left() - 0.5, m_rcVP.Right() + 0.5, m_rcVP.Bottom() - 0.5, m_rcVP.Top() + 0.5,            -1, 1);    glMatrixMode(GL_MODELVIEW);    return true;}void    CGlPane::x_UpdateProjectMatrices(void){    glGetIntegerv(GL_VIEWPORT, m_mxVP);    glGetDoublev(GL_PROJECTION_MATRIX, m_mxProjection);    glGetDoublev(GL_MODELVIEW_MATRIX, m_mxModelView);}////////////////////////////////////////////////////////////////////////////////// Zoom fucntionsbool    CGlPane::IsZoomInAvaiable(){            return m_bZoomEnX || m_bZoomEnY;}bool    CGlPane::IsZoomOutAvaiable(void){    bool    av_x = ::fabs(m_rcVisible.Right() - m_rcVisible.Left())                     < ::fabs(m_rcLimits.Right() - m_rcLimits.Left());        bool    av_y = ::fabs(m_rcVisible.Top() - m_rcVisible.Bottom())                     < ::fabs(m_rcLimits.Top() - m_rcLimits.Bottom());        return (m_bZoomEnX && av_x) || (m_bZoomEnY && av_y);}void    CGlPane::ZoomAll(int options){    if((options & fZoomX)  && (m_bZoomEnX  ||  (options & fForce)))  {        m_rcVisible.SetLeft(m_rcLimits.Left());        m_rcVisible.SetRight(m_rcLimits.Right());                m_rcOrigVisible.SetLeft(m_rcLimits.Left());            m_rcOrigVisible.SetRight(m_rcLimits.Right());    }    if((options & fZoomY)  && (m_bZoomEnY  ||  (options & fForce)))  {        m_rcVisible.SetBottom(m_rcLimits.Bottom());        m_rcVisible.SetTop(m_rcLimits.Top());                m_rcOrigVisible.SetBottom(m_rcLimits.Bottom());            m_rcOrigVisible.SetTop(m_rcLimits.Top());    }    // applying constraints    x_CorrectScale(m_rcOrigVisible.CenterPoint());    x_AdjustVisibleRect();}void    CGlPane::ZoomPoint(TModelUnit x, TModelUnit y, TModelUnit factor, int options){    _ASSERT(factor > 0.01  && factor < 100); // keep it reasonable    m_rcOrigVisible = m_rcVisible;    if ((options & fZoomX)  &&  m_bZoomEnX) {        TModelUnit new_w = m_rcVisible.Width() / factor;        TModelUnit left = x - new_w / 2;        m_rcOrigVisible.SetLeft(left);        m_rcOrigVisible.SetRight(left + new_w);    }    if ((options & fZoomY)  &&  m_bZoomEnY) {        TModelUnit new_h = m_rcVisible.Height() / factor;        TModelUnit bottom = y - new_h / 2;        m_rcOrigVisible.SetBottom(bottom);        m_rcOrigVisible.SetTop(bottom + new_h);    }        m_rcVisible = m_rcOrigVisible;            // applying constraints    x_CorrectScale(m_rcOrigVisible.CenterPoint());    x_ScaleToFitLimits();    x_ShiftToFitLimits();    x_AdjustVisibleRect();}void    CGlPane::ZoomInCenter(int options){    ZoomIn(m_rcVisible.CenterPoint(), options);}void    CGlPane::ZoomOutCenter(int options){    ZoomOut(m_rcVisible.CenterPoint(), options);}void    CGlPane::ZoomRect(const TModelRect& r){    SetVisibleRect(r);    TModelPoint p_center = m_rcVisible.CenterPoint();        x_CorrectScale(p_center);    x_ScaleToFitLimits(); //### merege with CorrectScale    x_ShiftToFitLimits();    x_AdjustVisibleRect();}void    CGlPane::SetScale(TModelUnit scale_x, TModelUnit scale_y, TModelPoint p_center){    TModelUnit new_w = ::abs(m_rcVP.Width()) * scale_x;    TModelUnit left = p_center.X() - new_w / 2;    m_rcOrigVisible.SetLeft(left);    m_rcOrigVisible.SetRight(left + new_w);        TModelUnit new_h = ::abs(m_rcVP.Height()) * scale_y;    TModelUnit bottom = p_center.Y() - new_h / 2;    m_rcOrigVisible.SetBottom(bottom);    m_rcOrigVisible.SetTop(bottom + new_h);     m_rcVisible = m_rcOrigVisible;    x_CorrectScale(p_center);    x_ScaleToFitLimits();     x_ShiftToFitLimits();    x_AdjustVisibleRect();}void    CGlPane::SetScaleRefPoint(TModelUnit scale_x, TModelUnit scale_y,                             TModelPoint p_ref){    TModelUnit new_w = ::abs(m_rcVP.Width()) * scale_x;        TModelUnit left_ratio = (p_ref.X() - m_rcVisible.Left()) / m_rcVisible.Width();    TModelUnit left = p_ref.X() - new_w * left_ratio;    m_rcOrigVisible.SetLeft(left);    m_rcOrigVisible.SetRight(left + new_w);    TModelUnit new_h = ::abs(m_rcVP.Height()) * scale_y;    TModelUnit bottom_ratio = (p_ref.Y() - m_rcVisible.Bottom()) / m_rcVisible.Height();    TModelUnit bottom = p_ref.Y() - new_h * bottom_ratio;    m_rcOrigVisible.SetBottom(bottom);    m_rcOrigVisible.SetTop(bottom + new_h);     m_rcVisible = m_rcOrigVisible;    x_CorrectScale(m_rcVisible.CenterPoint());    x_ScaleToFitLimits();     x_ShiftToFitLimits();    x_AdjustVisibleRect();}void    CGlPane::SetScale(TModelUnit scale_x, TModelUnit scale_y){    SetScale(scale_x, scale_y, m_rcVisible.CenterPoint());}// constraints forced by x_CorrectScale() may be conflicting with other constraints// in that case x_CorrectScale() has the lowerest priority// does not work on negative scalesvoid    CGlPane::x_CorrectScale(TModelPoint p_center){        if(m_MinScaleX != 0)    {        TModelUnit scale_x = GetScaleX();        if(scale_x < m_MinScaleX)   {            scale_x = m_MinScaleX;                    TModelUnit new_w = m_rcVP.Width() * scale_x;            TModelUnit left = p_center.X() - new_w / 2;            m_rcOrigVisible.SetLeft(left);            m_rcOrigVisible.SetRight(left + new_w);        }    }

⌨️ 快捷键说明

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