glpane_widget.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:13k
- /*
- * ===========================================================================
- * PRODUCTION $Log: glpane_widget.cpp,v $
- * PRODUCTION Revision 1000.3 2004/06/01 21:10:34 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: glpane_widget.cpp,v 1000.3 2004/06/01 21:10:34 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/glfont.hpp>
- #include <gui/widgets/gl/glpane_widget.hpp>
- #include <gui/types.hpp>
- #include <list>
- #include <FL/Fl.H>
- BEGIN_NCBI_SCOPE
- CGlPaneWidgetChild::CGlPaneWidgetChild(int PosX, int PosY, int Width, int Height, const char* Label)
- : CGlCanvas2d(PosX, PosY, Width, Height, Label),
- m_pCurrHandlerRec(NULL)
- {
- }
- CGlPaneWidgetChild::~CGlPaneWidgetChild()
- {
- }
- void CGlPaneWidgetChild::draw()
- {
- x_Render();
- }
- int CGlPaneWidgetChild::handle(int event)
- {
- m_Event.OnFLTKEvent(event);
-
- int res = 0;
- switch(event) {
- case FL_FOCUS:
- case FL_UNFOCUS: {
- x_HandleKeyEvent();
- redraw();
- return 1;
- }
- case FL_KEYDOWN:
- case FL_KEYUP: res = x_HandleKeyEvent(); break;
- case FL_MOVE: res = x_HandleMouseMove(); break;
- case FL_PUSH: {
- if(Fl::focus() != static_cast<Fl_Widget*>(this)) {
- take_focus();
- }
- res = x_HandleMousePush();
- }; break;
- case FL_DRAG: res = x_HandleMouseDrag(); break;
- case FL_RELEASE: res = x_HandleMouseRelease(); break;
- case FL_MOUSEWHEEL: res = x_HandleMouseWheel(); break;
- default: res = CGlCanvas2d::handle(event);
- }
- return res;
- }
- int CGlPaneWidgetChild::x_HandleKeyEvent()
- {
- int res = x_Handlers_handle(m_Event, 0xFFFFFFFF, false);
- return res;
- }
- int CGlPaneWidgetChild::x_HandleMouseMove()
- {
- int area = x_GetAreaByMousePos();
- int res = x_Handlers_handle(m_Event, area);
- if(res ==0)
- fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
- x_SetCurrHandler(NULL);
- return res;
- }
- int CGlPaneWidgetChild::x_HandleMousePush()
- {
- if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal) {
- x_OnShowPopup();
- return 1;
- } else {
- int area = x_GetAreaByMousePos();
- int res = x_Handlers_handle(m_Event, area);
- if(res ==0)
- fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
- return res;
- }
- }
- int CGlPaneWidgetChild::x_HandleMouseDrag()
- {
- int res = 0;
- if(m_pCurrHandlerRec) {
- IEventHandler* handler = m_pCurrHandlerRec->m_pHandler;
- res = handler->handle(m_Event, *m_pCurrHandlerRec->m_pPane);
- }
- if(res == 0)
- fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
- return res;
- }
- int CGlPaneWidgetChild::x_HandleMouseRelease()
- {
- int res = 0;
- if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal) {
- x_OnShowPopup();
- res = 1;
- } else {
- if(m_pCurrHandlerRec) {
- IEventHandler* handler = m_pCurrHandlerRec->m_pHandler;
- res = handler->handle(m_Event, *m_pCurrHandlerRec->m_pPane);
- }
- if(res == 0)
- fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
- }
- return res;
- }
- int CGlPaneWidgetChild::x_HandleMouseWheel()
- {
- int res = x_Handlers_handle(m_Event, 0xFFFFFFFF, false);
- return res;
- }
- // default implementation, to be overriden on derived classes
- int CGlPaneWidgetChild::x_GetAreaByMousePos()
- {
- return 0xFFFFFFFF;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Handlers management
- bool CGlPaneWidgetChild::x_RegisterHandler(IEventHandler* handler, int area, CGlPane* pane)
- {
- _ASSERT(handler && area);
- ITERATE(THandlerRecList, it, m_lsHandlerRecs) {
- if(it->m_pHandler == handler)
- return false; // already registered
- }
- SHandlerRec rec;
- rec.m_pHandler = handler;
- rec.m_Area = area;
- rec.m_pPane = pane;
- m_lsHandlerRecs.push_back(rec);
- return true;
- }
- bool CGlPaneWidgetChild::x_UnregisterHandler(IEventHandler* handler)
- {
- NON_CONST_ITERATE(THandlerRecList, it, m_lsHandlerRecs) {
- if(it->m_pHandler == handler) {
- m_lsHandlerRecs.erase(it);
- if(m_pCurrHandlerRec && m_pCurrHandlerRec->m_pHandler == handler)
- m_pCurrHandlerRec = NULL;
- return true;
- }
- }
- return false; // not registered
- }
- void CGlPaneWidgetChild::x_SetCurrHandler(SHandlerRec* rec)
- {
- m_pCurrHandlerRec = rec;
- }
- int CGlPaneWidgetChild::x_Handlers_handle(CGUIEvent& event, int area, bool ignore_curr)
- {
- int res = 0;
-
- SHandlerRec* p_first = ignore_curr ? NULL : m_pCurrHandlerRec;
- if(p_first) {
- IEventHandler* handler = p_first->m_pHandler;
- res = handler->handle(m_Event, *p_first->m_pPane);
- if(res) {
- x_SetCurrHandler(p_first);
- return res;
- }
- }
-
- if(res == 0) {
- // event was not handled by current handler - iterate through over handlers
- NON_CONST_ITERATE(THandlerRecList, it, m_lsHandlerRecs) {
- IEventHandler* handler = it->m_pHandler;
- if((it->m_Area & area)
- && (p_first == NULL || handler != p_first->m_pHandler) ) {
- res = handler->handle(m_Event, *it->m_pPane);
- if(res) {
- x_SetCurrHandler(&(*it));
- return res;
- }
- }
- }
- }
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- /// class CGlPaneWidget
- CGlPaneWidget::CGlPaneWidget(int PosX, int PosY, int Width, int Height, const char* label)
- : Fl_Group(PosX, PosY, Width, Height, label),
- m_pScrollX(NULL), m_pScrollY(NULL)
- {
- }
- CGlPaneWidget::~CGlPaneWidget()
- {
- }
- void CGlPaneWidget::Create()
- {
- x_CreateControls();
- end();
- TVPPoint size = x_GetPane()->GetPortSize();
- TVPRect rcVP(0, 0, size.X(), size.Y());
- m_Port.SetViewport(rcVP);
- x_SetPortLimits();
- }
- BEGIN_CMD_MAP(CGlPaneWidget, CCommandTarget)
- ON_COMMAND(eCmdZoomIn, &CGlPaneWidget::OnZoomIn)
- ON_COMMAND(eCmdZoomInX, &CGlPaneWidget::OnZoomInX)
- ON_COMMAND(eCmdZoomInY, &CGlPaneWidget::OnZoomInY)
- ON_COMMAND(eCmdZoomOut, &CGlPaneWidget::OnZoomOut)
- ON_COMMAND(eCmdZoomOutX, &CGlPaneWidget::OnZoomOutX)
- ON_COMMAND(eCmdZoomOutY, &CGlPaneWidget::OnZoomOutY)
- ON_COMMAND(eCmdZoomAll, &CGlPaneWidget::OnZoomAll)
- ON_COMMAND(eCmdZoomAllX, &CGlPaneWidget::OnZoomAllX)
- ON_COMMAND(eCmdZoomAllY, &CGlPaneWidget::OnZoomAllY)
- END_CMD_MAP()
- const CGlPane& CGlPaneWidget::x_GetPort() const
- {
- return m_Port;
- }
- void CGlPaneWidget::resize(int x, int y, int w, int h)
- {
- Fl_Group::resize(x, y, w, h);
- x_OnResize();
- }
- void CGlPaneWidget::OnZoomIn()
- {
- x_ZoomIn(CGlPane::fZoomXY);
- }
- void CGlPaneWidget::OnZoomInX()
- {
- x_ZoomIn(CGlPane::fZoomX);
- }
- void CGlPaneWidget::OnZoomInY()
- {
- x_ZoomIn(CGlPane::fZoomY);
- }
- void CGlPaneWidget::OnZoomOut()
- {
- x_ZoomOut(CGlPane::fZoomXY);
- }
- void CGlPaneWidget::OnZoomOutX()
- {
- x_ZoomOut(CGlPane::fZoomX);
- }
- void CGlPaneWidget::OnZoomOutY()
- {
- x_ZoomOut(CGlPane::fZoomY);
- }
- void CGlPaneWidget::OnZoomAll()
- {
- x_ZoomAll(CGlPane::fZoomXY);
- }
- void CGlPaneWidget::OnZoomAllX()
- {
- x_ZoomAll(CGlPane::fZoomX);
- }
- void CGlPaneWidget::OnZoomAllY()
- {
- x_ZoomAll(CGlPane::fZoomY);
- }
- void CGlPaneWidget::ZoomRect(const TModelRect& rc)
- {
- m_Port.ZoomRect(rc);
- x_UpdateOnZoom();
- }
- void CGlPaneWidget::Scroll(TModelUnit d_x, TModelUnit d_y)
- {
- m_Port.Scroll(d_x, d_y);
- x_UpdateOnZoom();
- }
- void CGlPaneWidget::x_ZoomIn(int options)
- {
- if(m_Port.IsZoomInAvaiable()) { //### options
- m_Port.ZoomInCenter(options);
- x_UpdateOnZoom();
- }
- }
- void CGlPaneWidget::x_ZoomOut(int options)
- {
- if(m_Port.IsZoomOutAvaiable()) {
- m_Port.ZoomOutCenter(options);
- x_UpdateOnZoom();
- }
- }
- void CGlPaneWidget::x_ZoomAll(int options)
- {
- if(m_Port.IsZoomOutAvaiable()) {
- m_Port.ZoomAll(options);
- x_UpdateOnZoom();
- }
- }
- const int kScrollbarSize = 15;
- void CGlPaneWidget::x_CreateControls()
- {
- _ASSERT(! x_GetPane() && ! m_pScrollX && ! m_pScrollY);
- int client_w = w() - kScrollbarSize;
- int client_h = h() - kScrollbarSize;
- x_CreatePane();
- x_GetPane()->resize(x(), y(), client_w, client_h);
-
- // scrollbars
- m_pScrollX = new Fl_Scrollbar(x(), y() + client_h, client_w, kScrollbarSize);
- m_pScrollX->type(FL_HORIZONTAL);
- m_pScrollX->callback(&CGlPaneWidget::x_OnScrollX, this );
-
- m_pScrollY = new Fl_Scrollbar(x() + client_w, y(), kScrollbarSize, client_h);
- m_pScrollY->type(FL_VERTICAL);
- m_pScrollY->callback(&CGlPaneWidget::x_OnScrollY, this );
-
- resizable(x_GetPane());
- end();
- }
- void CGlPaneWidget::x_OnResize()
- {
- TVPPoint size = x_GetPane()->GetPortSize();
- TVPRect rcVP(0, 0, size.X(), size.Y());
- m_Port.SetViewport(rcVP);
-
- m_Port.AdjustToLimits();
- x_UpdateScrollbars();
- }
- void CGlPaneWidget::x_RedrawControls()
- {
- x_GetPane()->redraw();
- }
- ////////////////////////////////////////////////////////////////////////////////
- /// Update handlers
- void CGlPaneWidget::x_Update()
- {
- /// Update data strutures
- /// update m_Port (x_SetPortLimits)
- /// update visible rect in m_Port
- /// x_UpdateScrollbars() if necessary
- /// x_UpdatePanes() ?
- /// x_RedrawControls()
- }
- void CGlPaneWidget::x_UpdateOnZoom()
- {
- x_UpdateScrollbars();
- x_RedrawControls();
- }
- ////////////////////////////////////////////////////////////////////////////////
- /// Scrollbars handling
- void CGlPaneWidget::x_OnScrollX(Fl_Widget* pW, void* pData)
- {
- CGlPaneWidget* pCont = reinterpret_cast<CGlPaneWidget*>(pData);
- pCont->x_OnScrollX();
- }
- void CGlPaneWidget::x_OnScrollY(Fl_Widget* pW, void* pData)
- {
- CGlPaneWidget* pCont = reinterpret_cast<CGlPaneWidget*>(pData);
- pCont->x_OnScrollY();
- }
- /*void CGlPaneWidget::x_ZoomToRange(TSeqPos from, TSeqPos to)
- {
- _ASSERT(from < to);
- TModelRect rcV = m_Port.GetVisibleRect();
- rcV.SetLeft(from);
- rcV.SetRight(to + 1);
- m_Port.ZoomRect(rcV);
-
- x_UpdateOnZoom();
- }
- void CGlPaneWidget::x_MakeVisibleHorz(TSeqPos pos)
- {
- x_MakeVisibleHorz(pos, pos);
- }
- void CGlPaneWidget::x_MakeVisibleHorz(TSeqPos from, TSeqPos to)
- {
- TModelRect rcV = m_Port.GetVisibleRect();
- TModelUnit sh_left = from - rcV.Left();
- TModelUnit sh_right = to + 1 - rcV.Right();
-
- TModelUnit sh = 0;
- if(sh_left < 0) { // shift left
- sh = sh_left;
- } else if(sh_right > 0) {
- TModelUnit sh = min(sh_right, sh_left);
- }
- if(sh != 0) {
- m_Port.Scroll(sh, 0);
-
- x_UpdateOnZoom();
- }
- }
- */
- /*void CGlPaneWidget::OnSetScaleX(TModelUnit scale_x)
- {
- m_Port.SetScale(scale_x, m_Port.GetScaleY());
-
- x_UpdateOnZoom();
- }
- */
- // dummy event handler
- void CGlPaneWidget::OnAllEvents(CViewEvent::TEventObject evt)
- {
- _TRACE("unhandled event: CGlPaneWidget:OnViewEvent()");
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: glpane_widget.cpp,v $
- * Revision 1000.3 2004/06/01 21:10:34 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
- *
- * Revision 1.9 2004/05/21 22:27:54 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.8 2004/03/30 17:10:45 tereshko
- * Added support for events broadcasting
- *
- * Revision 1.7 2004/03/23 14:07:37 dicuccio
- * Fixed compiler warnings
- *
- * Revision 1.6 2004/02/13 21:22:51 tereshko
- * Fixed problem with removing current event handler from list
- *
- * Revision 1.5 2004/02/12 21:00:12 yazhuk
- * Implemented support for popup menus
- *
- * Revision 1.4 2003/12/09 13:17:04 ucko
- * Explicitly use & when passing member functions as arguments.
- *
- * Revision 1.3 2003/12/08 15:13:16 yazhuk
- * Implemented support for handlers deactivation on FL_UNFOCUS.
- *
- * Revision 1.2 2003/12/01 16:39:51 yazhuk
- * Refactored event handling - introduced CGUIEvent, implement new
- * IMouseZoomHandlerHost functions
- *
- * Revision 1.1 2003/11/17 20:24:32 yazhuk
- * Initial revision
- *
- * ===========================================================================
- */