mouse_zoom_handler.cpp
来自「ncbi源码」· C++ 代码 · 共 691 行 · 第 1/2 页
CPP
691 行
/* * =========================================================================== * PRODUCTION $Log: mouse_zoom_handler.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 21:10:40 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10 * PRODUCTION * =========================================================================== *//* $Id: mouse_zoom_handler.cpp,v 1000.3 2004/06/01 21:10:40 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 <gui/opengl/glhelpers.hpp>#include <gui/widgets/gl/mouse_zoom_handler.hpp>#include <math.h>#include <FL/Fl.H>BEGIN_NCBI_SCOPE/////////////////////////////////////////////////////////////////////////////////// class CMouseZoomHandlerCMouseZoomHandler::CMouseZoomHandler(): m_pHost(NULL), m_State(eIdle), m_PixPerNorm(50), m_MouseStartX(0), m_MouseStartY(0), m_CurrPosX(0), m_CurrPosY(0), m_ScaleColor(0.0f, 0.5f, 0.0f, 0.5f), m_TickColor(1.0f, 1.0f, 1.0f), m_RectColor(0.0f, 0.5f, 0.0f, 0.25f){}CMouseZoomHandler::~CMouseZoomHandler(){}void CMouseZoomHandler::SetHost(IMouseZoomHandlerHost* pHost){ m_pHost = pHost;}static int kMarkerSize = 20;static int kMarkerOffset = 10;static int kGaugeW = 60;static int kEndTickW = 20;static int kMajorTickW = 14;static int kMinorTickW = 8;static int kCenterOffset = 4;void CMouseZoomHandler::Render(CGlPane& pane){ CGlAttrGuard AttrGuard(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_HINT_BIT); switch(m_State) { case eReadyScale: case eScale: x_RenderScale(pane); break; case eZoomRect: x_RenderZoomRect(pane); break; //case ePan: x_RenderPan(pane); break; // temporary disabled default: break; }}void CMouseZoomHandler::x_RenderScale(CGlPane& pane){ pane.OpenPixels(); int base_x = m_MarkerPosX; int down_y = x_NormToPixels(m_CurrNorm); int top_y = x_NormToPixels(m_MinNorm); int bottom_y = x_NormToPixels(m_MaxNorm); glColorC(m_ScaleColor); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //drawing "gauge box" glRectd(base_x - kGaugeW / 2, bottom_y - kCenterOffset, base_x + kGaugeW / 2, top_y + kCenterOffset); // drawing Markers int half = kMarkerSize / 2; x_DrawMarker(base_x - kGaugeW / 2 - kMarkerOffset, down_y, half); x_DrawMarker(base_x + kGaugeW / 2 + kMarkerOffset, down_y, -half); glColorC(m_TickColor); glLineWidth(1.0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //drawing "gauge box" glRectd(base_x - kGaugeW / 2, bottom_y - kCenterOffset, base_x + kGaugeW / 2, top_y + kCenterOffset); // drawing Markers x_DrawMarker(base_x - kGaugeW / 2 - kMarkerOffset, down_y, half); x_DrawMarker(base_x + kGaugeW / 2 + kMarkerOffset, down_y, -half); // draw Scale - lines and ticks glColorC(m_TickColor); int x1 = base_x - kCenterOffset; int x2 = base_x + kCenterOffset; glBegin(GL_LINES); // draw vertical lines glVertex2d(x1, top_y); glVertex2d(x1, bottom_y); glVertex2d(x2, top_y); glVertex2d(x2, bottom_y); // draw min-max ticks x_DrawTicks(base_x, top_y, kEndTickW); x_DrawTicks(base_x, bottom_y, kEndTickW); // draw minor ticks every 0.2 of norm value int start_i = (int) ceil(m_MinNorm * 5); int end_i = (int) floor(m_MaxNorm * 5); // draw regular ticks for( int i = start_i; i <= end_i; i++ ) { TModelUnit norm = 0.2 * i; int y = x_NormToPixels(norm); int width = ((i - start_i) % 5) ? kMinorTickW : kMajorTickW; x_DrawTicks(base_x, y, width); } glEnd(); pane.Close();}void CMouseZoomHandler::x_RenderZoomRect(CGlPane& pane){ pane.OpenPixels(); int x1 = m_MouseStartX; int y1 = m_pHost->MZHH_GetVPPosByY(m_MouseStartY); int x2 = m_CurrPosX; int y2 = m_pHost->MZHH_GetVPPosByY(m_CurrPosY); if(x2 < x1) swap(x1, x2); if(y2 < y1) swap(y1, y2); glLineWidth(1.0f); glColorC(m_ScaleColor); glLineStipple(1, 0x0F0F); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex2d(x1, y2); glVertex2d(x2, y2); glVertex2d(x2, y2); glVertex2d(x2, y1); glVertex2d(x1, y2); glVertex2d(x1, y1); glVertex2d(x1, y1); glVertex2d(x2, y1); glEnd(); glDisable(GL_LINE_STIPPLE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColorC(m_RectColor); glRectd(x1, y1, x2, y2); pane.Close();}static const int kArrowBodyW = 10;static const int kArrowHeadW = 20;static const int kArrowHeadL = 20;void CMouseZoomHandler::x_RenderPan(CGlPane& pane){ pane.OpenPixels(); glLineWidth(1.0f); glColorC(m_ScaleColor); glEnable(GL_POLYGON_SMOOTH); glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); int x1 = m_MouseStartX; int y1 = m_pHost->MZHH_GetVPPosByY(m_MouseStartY); int x2 = m_CurrPosX; int y2 = m_pHost->MZHH_GetVPPosByY(m_CurrPosY); double d_x = x2 - x1; double d_y = y2 - y1; double angle = 90.0 * atan2(d_y, d_x) / atan2(1.0, 0.0); double hyp = sqrt(d_x * d_x + d_y * d_y); // move and rotate origin and then draw arrow horizontally glTranslated(x1, y1, 0); glRotated(angle, 0.0, 0.0, 1.0); glBegin(GL_QUADS); if(hyp > kArrowHeadL) { // draw full arrow glVertex2d(0, kArrowBodyW); glVertex2d(hyp - kArrowHeadL, kArrowBodyW); glVertex2d(hyp - kArrowHeadL, -kArrowBodyW); glVertex2d(0, -kArrowBodyW); glVertex2d(hyp - kArrowHeadL, 0); glVertex2d(hyp - kArrowHeadL, kArrowHeadW); glVertex2d(hyp, 0); glVertex2d(hyp - kArrowHeadL, -kArrowHeadW); } else { // draw simplified arrow glVertex2d(0, 0); glVertex2d(0, kArrowHeadW); glVertex2d(hyp, 0); glVertex2d(0, -kArrowHeadW); } glEnd(); glRotated(-angle, 0.0, 0.0, 1.0); glTranslated(-x1, -y1, 0); //glDisable(GL_POLYGON_SMOOTH); pane.Close();}void CMouseZoomHandler::x_DrawMarker(int x_c, int y_c, int half){ glBegin(GL_POLYGON); glVertex2d(x_c + half, y_c); glVertex2d(x_c, y_c - half); glVertex2d(x_c - half, y_c - half); glVertex2d(x_c - half, y_c + half); glVertex2d(x_c, y_c + half); glEnd();}void CMouseZoomHandler::x_DrawTicks(int center_x, int y, int tick_w){ int x1 = center_x - kCenterOffset; int x2 = center_x + kCenterOffset; glVertex2d(x1 - tick_w, y); glVertex2d(x1, y); glVertex2d(x2, y); glVertex2d(x2 + tick_w, y);}int CMouseZoomHandler::x_NormToPixels(TModelUnit norm) const{ int y = m_pHost->MZHH_GetVPPosByY(m_CurrPosY); return y - (int) ((norm - m_CurrNorm) * m_PixPerNorm);}int CMouseZoomHandler::handle(CGUIEvent& event, CGlPane& Pane){ m_pPane = &Pane; int res = 0; switch(event.GetFLTKEvent()) { case FL_PUSH: res = x_OnMousePush(event); break; case FL_DRAG: res = x_OnMouseDrag(event); break; case FL_RELEASE: res = x_OnMouseRelease(event); break; case FL_MOVE: res = x_OnMouseMove(); break; case FL_MOUSEWHEEL: res = x_OnMouseWheel(event); break; case FL_KEYDOWN: res = x_OnKeyDown(event); break; case FL_UNFOCUS: case FL_KEYUP: res = x_OnKeyUp(event); break; } m_pPane = 0; return res;}/////////////////////////////////////////////////////////////////////////////////// event handlersint CMouseZoomHandler::x_OnMousePush(CGUIEvent& event){ if(event.GetGUISignal() == CGUIEvent::ePush && Fl::event_clicks() == 0) { CGUIEvent::EGUIState state = event.GetGUIState(); EState ready_st = eIdle, active_st = eIdle; switch(state) { case CGUIEvent::eZoomState: { ready_st = eReadyScale; active_st = eScale; }; break; case CGUIEvent::eZoomRectState: { ready_st = eReadyZoomRect; active_st = eZoomRect; x_OnSelectCursor(); }; break; case CGUIEvent::ePanState: { ready_st = eReadyPan; active_st = ePan; }; break; default: break; } if(ready_st != eIdle) { x_SwitchToReadyState(ready_st, Fl::event_x(), Fl::event_y()); x_SwithToActiveState(active_st, Fl::event_x(), Fl::event_y()); x_OnSelectCursor(); } return 1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?