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