glpane_widget.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:13k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: glpane_widget.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 21:10:34  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: glpane_widget.cpp,v 1000.3 2004/06/01 21:10:34 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  * 
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/opengl/glfont.hpp>
  41. #include <gui/widgets/gl/glpane_widget.hpp>
  42. #include <gui/types.hpp>
  43. #include <list>
  44. #include <FL/Fl.H>
  45. BEGIN_NCBI_SCOPE
  46. CGlPaneWidgetChild::CGlPaneWidgetChild(int PosX, int PosY, int Width, int Height, const char* Label)
  47. : CGlCanvas2d(PosX, PosY, Width, Height, Label),
  48.   m_pCurrHandlerRec(NULL)
  49. {
  50. }
  51. CGlPaneWidgetChild::~CGlPaneWidgetChild()
  52. {
  53. }
  54. void    CGlPaneWidgetChild::draw()   
  55. {
  56.     x_Render();
  57. }
  58. int  CGlPaneWidgetChild::handle(int event)
  59. {
  60.     m_Event.OnFLTKEvent(event);
  61.     
  62.     int res = 0;
  63.     switch(event)   {
  64.     case FL_FOCUS: 
  65.     case FL_UNFOCUS:    {
  66.         x_HandleKeyEvent();
  67.         redraw();   
  68.         return 1;
  69.     }
  70.     case FL_KEYDOWN:
  71.     case FL_KEYUP:  res = x_HandleKeyEvent(); break;
  72.     case FL_MOVE:   res = x_HandleMouseMove(); break;
  73.     case FL_PUSH:  {
  74.         if(Fl::focus() != static_cast<Fl_Widget*>(this))    {
  75.             take_focus();
  76.         }
  77.         res = x_HandleMousePush();
  78.     };  break;
  79.     case FL_DRAG: res = x_HandleMouseDrag(); break;
  80.     case FL_RELEASE: res = x_HandleMouseRelease(); break;
  81.     case FL_MOUSEWHEEL: res = x_HandleMouseWheel(); break;
  82.     default: res = CGlCanvas2d::handle(event);
  83.     }       
  84.     return res;
  85. }
  86. int    CGlPaneWidgetChild::x_HandleKeyEvent()
  87. {
  88.     int res = x_Handlers_handle(m_Event, 0xFFFFFFFF, false);    
  89.     return res;
  90. }
  91. int    CGlPaneWidgetChild::x_HandleMouseMove()
  92. {
  93.     int area = x_GetAreaByMousePos();
  94.     int res = x_Handlers_handle(m_Event, area);
  95.     if(res ==0)
  96.         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); 
  97.     x_SetCurrHandler(NULL);
  98.     return res;
  99. }
  100. int    CGlPaneWidgetChild::x_HandleMousePush()
  101. {
  102.     if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal)   {
  103.         x_OnShowPopup();
  104.         return 1;
  105.     } else {
  106.         int area = x_GetAreaByMousePos();
  107.         int res = x_Handlers_handle(m_Event, area);
  108.         if(res ==0)
  109.             fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);     
  110.         return res;
  111.     }
  112. }
  113. int    CGlPaneWidgetChild::x_HandleMouseDrag()
  114. {
  115.     int res = 0;
  116.     if(m_pCurrHandlerRec)  {
  117.         IEventHandler* handler = m_pCurrHandlerRec->m_pHandler;
  118.         res = handler->handle(m_Event, *m_pCurrHandlerRec->m_pPane);
  119.     }
  120.     if(res == 0)
  121.         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); 
  122.     return res;
  123. }
  124. int    CGlPaneWidgetChild::x_HandleMouseRelease()
  125. {
  126.     int res = 0;
  127.     if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal)   {
  128.         x_OnShowPopup();
  129.         res = 1;
  130.     } else {
  131.         if(m_pCurrHandlerRec)  {
  132.             IEventHandler* handler = m_pCurrHandlerRec->m_pHandler;
  133.             res = handler->handle(m_Event, *m_pCurrHandlerRec->m_pPane);
  134.         }
  135.         if(res == 0)
  136.             fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); 
  137.     }
  138.     return res;
  139. }
  140. int    CGlPaneWidgetChild::x_HandleMouseWheel()
  141. {
  142.     int res = x_Handlers_handle(m_Event, 0xFFFFFFFF, false);    
  143.     return res;
  144. }
  145. // default implementation, to be overriden on derived classes
  146. int     CGlPaneWidgetChild::x_GetAreaByMousePos()
  147. {
  148.     return 0xFFFFFFFF;
  149. }
  150. ///////////////////////////////////////////////////////////////////////////////
  151. // Handlers management
  152. bool    CGlPaneWidgetChild::x_RegisterHandler(IEventHandler* handler, int area, CGlPane* pane)
  153. {
  154.     _ASSERT(handler  &&  area);
  155.     ITERATE(THandlerRecList, it, m_lsHandlerRecs)    {
  156.         if(it->m_pHandler == handler)
  157.             return false; // already registered
  158.     }    
  159.     SHandlerRec rec;
  160.     rec.m_pHandler = handler;
  161.     rec.m_Area = area;
  162.     rec.m_pPane = pane;
  163.     m_lsHandlerRecs.push_back(rec);
  164.     return true;
  165. }
  166. bool    CGlPaneWidgetChild::x_UnregisterHandler(IEventHandler* handler)
  167. {
  168.     NON_CONST_ITERATE(THandlerRecList, it, m_lsHandlerRecs)    {
  169.         if(it->m_pHandler == handler)   {
  170.             m_lsHandlerRecs.erase(it);
  171.             if(m_pCurrHandlerRec  &&  m_pCurrHandlerRec->m_pHandler == handler)
  172.                 m_pCurrHandlerRec = NULL;
  173.             return true;
  174.         }            
  175.     }
  176.     return false; // not registered
  177. }
  178. void    CGlPaneWidgetChild::x_SetCurrHandler(SHandlerRec* rec)
  179. {
  180.     m_pCurrHandlerRec = rec;
  181. }
  182. int CGlPaneWidgetChild::x_Handlers_handle(CGUIEvent& event, int area, bool ignore_curr)
  183. {    
  184.     int res = 0;
  185.  
  186.     SHandlerRec* p_first = ignore_curr ? NULL : m_pCurrHandlerRec;
  187.     if(p_first)  {
  188.         IEventHandler* handler = p_first->m_pHandler;
  189.         res = handler->handle(m_Event, *p_first->m_pPane);
  190.         if(res) {
  191.             x_SetCurrHandler(p_first);
  192.             return res;                
  193.         }
  194.     }
  195.     
  196.     if(res == 0)    { 
  197.     // event was not handled by current handler - iterate through over handlers
  198.         NON_CONST_ITERATE(THandlerRecList, it, m_lsHandlerRecs) {
  199.             IEventHandler* handler = it->m_pHandler;
  200.             if((it->m_Area & area)  
  201.                     &&  (p_first == NULL || handler != p_first->m_pHandler) )    {
  202.                 res = handler->handle(m_Event, *it->m_pPane);
  203.                 if(res) {
  204.                     x_SetCurrHandler(&(*it));
  205.                     return res;                
  206.                 }
  207.             }
  208.         }
  209.     }
  210.     return 0;
  211. }
  212. ////////////////////////////////////////////////////////////////////////////////
  213. /// class CGlPaneWidget
  214. CGlPaneWidget::CGlPaneWidget(int PosX, int PosY, int Width, int Height, const char* label)
  215. : Fl_Group(PosX, PosY, Width, Height, label),
  216.   m_pScrollX(NULL), m_pScrollY(NULL)
  217. {           
  218. }
  219. CGlPaneWidget::~CGlPaneWidget()
  220. {
  221. }
  222. void    CGlPaneWidget::Create()
  223. {
  224.     x_CreateControls();
  225.     end(); 
  226.     TVPPoint size = x_GetPane()->GetPortSize();
  227.     TVPRect rcVP(0, 0, size.X(), size.Y());
  228.     m_Port.SetViewport(rcVP);
  229.     x_SetPortLimits();
  230. }
  231. BEGIN_CMD_MAP(CGlPaneWidget, CCommandTarget)
  232.     ON_COMMAND(eCmdZoomIn,  &CGlPaneWidget::OnZoomIn)
  233.     ON_COMMAND(eCmdZoomInX,  &CGlPaneWidget::OnZoomInX)
  234.     ON_COMMAND(eCmdZoomInY,  &CGlPaneWidget::OnZoomInY)
  235.     ON_COMMAND(eCmdZoomOut,  &CGlPaneWidget::OnZoomOut)
  236.     ON_COMMAND(eCmdZoomOutX,  &CGlPaneWidget::OnZoomOutX)
  237.     ON_COMMAND(eCmdZoomOutY,  &CGlPaneWidget::OnZoomOutY)
  238.     ON_COMMAND(eCmdZoomAll,  &CGlPaneWidget::OnZoomAll)
  239.     ON_COMMAND(eCmdZoomAllX,  &CGlPaneWidget::OnZoomAllX)
  240.     ON_COMMAND(eCmdZoomAllY,  &CGlPaneWidget::OnZoomAllY)
  241. END_CMD_MAP()
  242. const CGlPane& CGlPaneWidget::x_GetPort() const
  243. {
  244.     return m_Port;
  245. }
  246. void CGlPaneWidget::resize(int x, int y, int w, int h)
  247. {
  248.     Fl_Group::resize(x, y, w, h); 
  249.     x_OnResize();
  250. }
  251. void CGlPaneWidget::OnZoomIn()
  252. {
  253.     x_ZoomIn(CGlPane::fZoomXY);
  254. }
  255. void CGlPaneWidget::OnZoomInX()
  256. {
  257.     x_ZoomIn(CGlPane::fZoomX);
  258. }
  259. void CGlPaneWidget::OnZoomInY()
  260. {
  261.     x_ZoomIn(CGlPane::fZoomY);
  262. }
  263. void CGlPaneWidget::OnZoomOut()
  264. {
  265.     x_ZoomOut(CGlPane::fZoomXY);
  266. }
  267. void CGlPaneWidget::OnZoomOutX()
  268. {
  269.     x_ZoomOut(CGlPane::fZoomX);
  270. }
  271. void CGlPaneWidget::OnZoomOutY()
  272. {
  273.     x_ZoomOut(CGlPane::fZoomY);
  274. }
  275. void CGlPaneWidget::OnZoomAll()
  276. {
  277.     x_ZoomAll(CGlPane::fZoomXY);
  278. }
  279. void CGlPaneWidget::OnZoomAllX()
  280. {
  281.     x_ZoomAll(CGlPane::fZoomX);
  282. }
  283. void CGlPaneWidget::OnZoomAllY()
  284. {
  285.     x_ZoomAll(CGlPane::fZoomY);
  286. }
  287. void    CGlPaneWidget::ZoomRect(const TModelRect&  rc)
  288. {
  289.    m_Port.ZoomRect(rc);
  290.    x_UpdateOnZoom();
  291. }
  292. void    CGlPaneWidget::Scroll(TModelUnit d_x, TModelUnit d_y)
  293. {
  294.     m_Port.Scroll(d_x, d_y);
  295.     x_UpdateOnZoom();
  296. }
  297. void    CGlPaneWidget::x_ZoomIn(int options)
  298. {
  299.     if(m_Port.IsZoomInAvaiable())  { //### options
  300.         m_Port.ZoomInCenter(options);        
  301.         x_UpdateOnZoom();
  302.     }
  303. }
  304. void CGlPaneWidget::x_ZoomOut(int options)
  305. {
  306.     if(m_Port.IsZoomOutAvaiable())  {
  307.         m_Port.ZoomOutCenter(options);
  308.         x_UpdateOnZoom();
  309.     }
  310. }
  311. void CGlPaneWidget::x_ZoomAll(int options)
  312. {  
  313.     if(m_Port.IsZoomOutAvaiable())  {
  314.         m_Port.ZoomAll(options);
  315.         x_UpdateOnZoom();
  316.     }
  317. }
  318. const int kScrollbarSize = 15;
  319. void CGlPaneWidget::x_CreateControls()
  320. {
  321.     _ASSERT(! x_GetPane()  && ! m_pScrollX  && ! m_pScrollY);
  322.     int client_w = w() - kScrollbarSize;
  323.     int client_h = h() - kScrollbarSize;
  324.     x_CreatePane();
  325.     x_GetPane()->resize(x(), y(), client_w, client_h);
  326.     
  327.     // scrollbars
  328.     m_pScrollX = new Fl_Scrollbar(x(), y() + client_h, client_w, kScrollbarSize);
  329.     m_pScrollX->type(FL_HORIZONTAL);
  330.     m_pScrollX->callback(&CGlPaneWidget::x_OnScrollX, this );
  331.     
  332.     m_pScrollY = new Fl_Scrollbar(x() + client_w, y(), kScrollbarSize, client_h);
  333.     m_pScrollY->type(FL_VERTICAL);
  334.     m_pScrollY->callback(&CGlPaneWidget::x_OnScrollY, this );
  335.     
  336.     resizable(x_GetPane());
  337.     end();
  338. }
  339. void CGlPaneWidget::x_OnResize()
  340. {
  341.     TVPPoint size = x_GetPane()->GetPortSize();
  342.     TVPRect rcVP(0, 0, size.X(), size.Y());
  343.     m_Port.SetViewport(rcVP);
  344.     
  345.     m_Port.AdjustToLimits();
  346.     x_UpdateScrollbars();
  347. }
  348. void CGlPaneWidget::x_RedrawControls()
  349. {
  350.     x_GetPane()->redraw();
  351. }
  352. ////////////////////////////////////////////////////////////////////////////////
  353. /// Update handlers
  354. void CGlPaneWidget::x_Update()
  355. {
  356.     /// Update data strutures
  357.     /// update m_Port (x_SetPortLimits)
  358.     /// update visible rect in m_Port
  359.     /// x_UpdateScrollbars() if necessary
  360.     /// x_UpdatePanes() ?
  361.     /// x_RedrawControls()
  362. }
  363. void CGlPaneWidget::x_UpdateOnZoom()
  364. {
  365.     x_UpdateScrollbars(); 
  366.     x_RedrawControls();
  367. }
  368. ////////////////////////////////////////////////////////////////////////////////
  369. /// Scrollbars handling
  370. void CGlPaneWidget::x_OnScrollX(Fl_Widget* pW, void* pData)
  371. {
  372.     CGlPaneWidget* pCont = reinterpret_cast<CGlPaneWidget*>(pData);
  373.     pCont->x_OnScrollX();
  374. }
  375. void CGlPaneWidget::x_OnScrollY(Fl_Widget* pW, void* pData)
  376. {
  377.     CGlPaneWidget* pCont = reinterpret_cast<CGlPaneWidget*>(pData);
  378.     pCont->x_OnScrollY();
  379. }
  380. /*void    CGlPaneWidget::x_ZoomToRange(TSeqPos from, TSeqPos to)
  381. {
  382.     _ASSERT(from < to);
  383.     TModelRect rcV = m_Port.GetVisibleRect();
  384.     rcV.SetLeft(from);
  385.     rcV.SetRight(to + 1);
  386.     m_Port.ZoomRect(rcV);
  387.     
  388.     x_UpdateOnZoom();
  389. }
  390. void    CGlPaneWidget::x_MakeVisibleHorz(TSeqPos pos)
  391. {
  392.     x_MakeVisibleHorz(pos, pos);
  393. }
  394. void    CGlPaneWidget::x_MakeVisibleHorz(TSeqPos from, TSeqPos to)
  395. {
  396.     TModelRect rcV = m_Port.GetVisibleRect();
  397.     TModelUnit sh_left = from - rcV.Left();
  398.     TModelUnit sh_right = to + 1 - rcV.Right();
  399.     
  400.     TModelUnit sh = 0;
  401.     if(sh_left < 0) { // shift left 
  402.         sh = sh_left;
  403.     } else if(sh_right > 0) {
  404.         TModelUnit sh = min(sh_right, sh_left);
  405.     }
  406.     if(sh != 0) {
  407.         m_Port.Scroll(sh, 0);
  408.     
  409.         x_UpdateOnZoom();
  410.     }
  411. }
  412. */
  413. /*void    CGlPaneWidget::OnSetScaleX(TModelUnit scale_x)
  414. {
  415.     m_Port.SetScale(scale_x, m_Port.GetScaleY());
  416.     
  417.     x_UpdateOnZoom();
  418. }
  419. */
  420. // dummy event handler
  421. void CGlPaneWidget::OnAllEvents(CViewEvent::TEventObject  evt)
  422. {
  423.     _TRACE("unhandled event: CGlPaneWidget:OnViewEvent()");
  424. }
  425. END_NCBI_SCOPE
  426. /*
  427.  * ===========================================================================
  428.  * $Log: glpane_widget.cpp,v $
  429.  * Revision 1000.3  2004/06/01 21:10:34  gouriano
  430.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  431.  *
  432.  * Revision 1.9  2004/05/21 22:27:54  gorelenk
  433.  * Added PCH ncbi_pch.hpp
  434.  *
  435.  * Revision 1.8  2004/03/30 17:10:45  tereshko
  436.  * Added support for events broadcasting
  437.  *
  438.  * Revision 1.7  2004/03/23 14:07:37  dicuccio
  439.  * Fixed compiler warnings
  440.  *
  441.  * Revision 1.6  2004/02/13 21:22:51  tereshko
  442.  * Fixed problem with removing current event handler from list
  443.  *
  444.  * Revision 1.5  2004/02/12 21:00:12  yazhuk
  445.  * Implemented support for popup menus
  446.  *
  447.  * Revision 1.4  2003/12/09 13:17:04  ucko
  448.  * Explicitly use & when passing member functions as arguments.
  449.  *
  450.  * Revision 1.3  2003/12/08 15:13:16  yazhuk
  451.  * Implemented support for handlers deactivation on FL_UNFOCUS.
  452.  *
  453.  * Revision 1.2  2003/12/01 16:39:51  yazhuk
  454.  * Refactored event handling - introduced CGUIEvent, implement new
  455.  * IMouseZoomHandlerHost functions
  456.  *
  457.  * Revision 1.1  2003/11/17 20:24:32  yazhuk
  458.  * Initial revision
  459.  *
  460.  * ===========================================================================
  461.  */