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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: gui_event.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:04:59  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: gui_event.cpp,v 1000.1 2004/06/01 21:04:59 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:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *    Generic FLTK utilities.
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/utils/fltk_utils.hpp>
  41. #include <FL/Fl.H>
  42. #include <FL/fl_draw.H>
  43. #include <FL/Fl_Window.H>
  44. BEGIN_NCBI_SCOPE
  45. CFltkEvent::TEvent CFltkEvent::GetEvent(void)
  46. {
  47.     TEvent state = 0;
  48.     //
  49.     // raw state processing
  50.     //
  51.     if (Fl::event_button1()) {
  52.         state |= fLeftMouse;
  53.     }
  54.     
  55.     if (Fl::event_button2()) {
  56.         state |= fMiddleMouse;
  57.     }
  58.     if (Fl::event_button3()) {
  59.         state |= fRightMouse;
  60.     }
  61.     if (Fl::event_shift()) {
  62.         state |= fShift;
  63.     }
  64.     
  65.     if (Fl::event_ctrl()) {
  66.         state |= fCtrl;
  67.     }
  68.     
  69.     if (Fl::event_alt()) {
  70.         state |= fAlt;
  71.     }
  72.     
  73.     if ( (Fl::event_key() == FL_Meta_R  &&  Fl::event_key(FL_Meta_R))  ||
  74.          (Fl::event_key() == FL_Meta_L  &&  Fl::event_key(FL_Meta_L)) ) {
  75.         state |= fMeta;
  76.     }
  77.     
  78.     return state;
  79. }
  80. CFltkEvent::EEvent CFltkEvent::GetProcessedEvent()
  81. {
  82.     TEvent state = GetEvent();
  83.     TEventMap::const_iterator iter = sm_EventMap.find(state);
  84.     if (iter != sm_EventMap.end()) {
  85.         return iter->second;
  86.     }
  87.     return eNoState;
  88. }
  89. void CFltkEvent::SetState(EEvent state, TEvent key_combo)
  90. {
  91.     sm_EventMap[key_combo] = state;
  92. }
  93. CFltkEvent::TEvent CFltkEvent::GetState(EEvent state)
  94. {
  95.     ITERATE (TEventMap, iter, sm_EventMap) {
  96.         if (iter->second == state) {
  97.             return iter->first;
  98.         }
  99.     }
  100.     return 0;
  101. }
  102. //
  103. // set our default interaction modes
  104. // this is operating-system dependent
  105. //
  106. void CFltkEvent::SetOSDefaults()
  107. {
  108. #if   defined(NCBI_OS_MAC)  ||  defined(NCBI_OS_DARWIN)
  109.     CFltkEvent::SetState(CFltkEvent::eSelectState,
  110.                          CFltkEvent::fLeftMouse);
  111.     CFltkEvent::SetState(CFltkEvent::eMultiSelectState,
  112.                          CFltkEvent::fShiftLeftMouse);
  113.     CFltkEvent::SetState(CFltkEvent::ePopupState,
  114.                          CFltkEvent::fCtrlLeftMouse);
  115.     CFltkEvent::SetState(CFltkEvent::ePanState,
  116.                          CFltkEvent::fMetaLeftMouse);
  117.     CFltkEvent::SetState(CFltkEvent::eZoomState,
  118.                          CFltkEvent::fAltLeftMouse);
  119. #elif defined(NCBI_OS_UNIX)
  120.     // select = left mouse click
  121.     CFltkEvent::SetState(CFltkEvent::eSelectState,
  122.                          CFltkEvent::fLeftMouse);
  123.     // multiple select = shift left mouse click
  124.     CFltkEvent::SetState(CFltkEvent::eMultiSelectState,
  125.                          CFltkEvent::fShiftLeftMouse);
  126.     // pop-up = right mouse button
  127.     CFltkEvent::SetState(CFltkEvent::ePopupState,
  128.                          CFltkEvent::fRightMouse);
  129.     // pan    = middle mouse
  130.     CFltkEvent::SetState(CFltkEvent::ePanState,
  131.                          CFltkEvent::fMiddleMouse);
  132.     // zoom in = alt left mouse
  133.     CFltkEvent::SetState(CFltkEvent::eZoomState,
  134.                          CFltkEvent::fCtrlLeftMouse);
  135. #elif defined(NCBI_OS_MSWIN)
  136.     // select = left mouse click
  137.     CFltkEvent::SetState(CFltkEvent::eSelectState,
  138.                          CFltkEvent::fLeftMouse);
  139.     // multiple select = shift left mouse click
  140.     CFltkEvent::SetState(CFltkEvent::eMultiSelectState,
  141.                          CFltkEvent::fShiftLeftMouse);
  142.     // pop-up = right mouse button
  143.     CFltkEvent::SetState(CFltkEvent::ePopupState,
  144.                          CFltkEvent::fRightMouse);
  145.     // pan    = control left mouse
  146.     CFltkEvent::SetState(CFltkEvent::ePanState,
  147.                          CFltkEvent::fCtrlLeftMouse);
  148.     // zoom in = alt left mouse
  149.     CFltkEvent::SetState(CFltkEvent::eZoomState,
  150.                          CFltkEvent::fAltLeftMouse);
  151. #endif
  152. }
  153. CGUIEvent::CGUIEvent()
  154.     : m_LastFLTKEvent(0),
  155.       m_Modifiers(0)
  156. {
  157. }
  158. int CGUIEvent::GetFLTKEvent() const
  159. {
  160.     return m_LastFLTKEvent;
  161. }
  162. void CGUIEvent::OnFLTKEvent(int event)
  163. {
  164.     m_LastFLTKEvent = event;
  165.     m_MouseEvent = eNone;
  166.     m_GUISignal = eDefaultSignal;
  167.     switch(event)   {
  168.     case FL_KEYDOWN: x_OnKeyPressed();  break;
  169.     case FL_KEYUP: x_OnKeyReleased();   break;
  170.     case FL_UNFOCUS:
  171.         {{
  172.             m_stPressedKeys.clear();
  173.             m_Modifiers = 0;
  174.         }}
  175.         break;
  176.     
  177.     case FL_MOVE: m_MouseEvent = eMouseMove; break;
  178.     case FL_PUSH:
  179.         switch(Fl::event_button())  {
  180.         case FL_LEFT_MOUSE: m_MouseEvent = eLeftMousePush; break;
  181.         case FL_MIDDLE_MOUSE: m_MouseEvent = eMiddleMousePush; break;
  182.         case FL_RIGHT_MOUSE: m_MouseEvent = eRightMousePush; break;
  183.         }
  184.         x_UpdateEventState();
  185.             // generate signal for requesting focus
  186.         break;
  187.     case FL_DRAG:
  188.         switch(Fl::event_button())  {
  189.         case FL_LEFT_MOUSE: m_MouseEvent = eLeftMouseDrag; break;
  190.         case FL_MIDDLE_MOUSE: m_MouseEvent = eMiddleMouseDrag; break;
  191.         case FL_RIGHT_MOUSE: m_MouseEvent = eRightMouseDrag; break;
  192.         }
  193.         x_UpdateEventState();
  194.         break;
  195.     case FL_RELEASE:
  196.         switch(Fl::event_button())  {
  197.         case FL_LEFT_MOUSE: m_MouseEvent = eLeftMouseRelease; break;
  198.         case FL_MIDDLE_MOUSE: m_MouseEvent = eMiddleMouseRelease; break;
  199.         case FL_RIGHT_MOUSE: m_MouseEvent = eRightMouseRelease; break;
  200.         }
  201.         x_UpdateEventState();
  202.         break;
  203.     //case FL_MOUSEWHEEL: res = x_HandleMouseWheel(event); break;
  204.     default:
  205.         break;
  206.     }   
  207.     
  208.     // currently we support only one generic key hold at a time
  209.     int key = (m_stPressedKeys.size() == 1) ? *m_stPressedKeys.begin() : 0;
  210.     
  211.    
  212.     // shortcuts have priority
  213.     TShortcutTemplate sh_templ = x_EncodeShortcutTemplate(m_Modifiers, key);
  214.     TTemplToShortcut::const_iterator it = m_TemplToShortcut.find(sh_templ);
  215.     if(it != m_TemplToShortcut.end())  {
  216.         m_GUISignal = it->second;
  217.     }
  218.     else    { // handling mouse states/signals
  219.         TModTemplate templ = x_EncodeModTemplate(m_Modifiers, key);
  220.         TTemplToState::const_iterator it = m_TemplToState.find(templ);
  221.         m_GUIState = (it != m_TemplToState.end()) ? it->second : eDefaultState;
  222.         TEventTemplate e_templ= x_EncodeEventTemplate(m_GUIState, m_MouseEvent);
  223.         TTemplToSignal::const_iterator it1 = m_TemplToSignal.find(e_templ);
  224.         if(it1 != m_TemplToSignal.end())    {
  225.             m_GUISignal =  it1->second;
  226.         } else {
  227.             switch(m_MouseEvent)    {
  228.             case eMouseMove:   m_GUISignal = eDefaultSignal; break;
  229.             case eLeftMousePush:    
  230.             case eMiddleMousePush:    
  231.             case eRightMousePush:    m_GUISignal = ePush; break;
  232.             case eLeftMouseDrag:
  233.             case eMiddleMouseDrag:
  234.             case eRightMouseDrag:    m_GUISignal = eDrag; break;
  235.             case eLeftMouseRelease:
  236.             case eMiddleMouseRelease:
  237.             case eRightMouseRelease:    m_GUISignal = eRelease; break;
  238.             }
  239.         }
  240.     }
  241.     //cout << "nState " << m_GUIState << "    Signal " << m_GUISignal;
  242. }
  243. CGUIEvent::EGUIState    CGUIEvent::GetGUIState() const
  244. {
  245.     return m_GUIState;
  246. }
  247. CGUIEvent::EGUISignal   CGUIEvent::GetGUISignal() const
  248. {
  249.     return m_GUISignal;
  250. }
  251. void    CGUIEvent::RegisterState(EGUIState state, int mod_flags, int key)
  252. {
  253.     TModTemplate templ = x_EncodeModTemplate(mod_flags, key);
  254.     m_TemplToState[templ] = state;
  255. }
  256. void    CGUIEvent::RegisterSignal(EGUISignal signal, EGUIState state, EMouseEvent event)
  257. {
  258.     TEventTemplate  templ = x_EncodeEventTemplate(state, event);
  259.     m_TemplToSignal[templ] = signal;
  260. }
  261. void    CGUIEvent::RegisterShortcut(EGUISignal signal, int mod_flags, int key)
  262. {
  263.    TShortcutTemplate  templ = x_EncodeShortcutTemplate(mod_flags, key);
  264.    m_TemplToShortcut[templ] = signal;
  265. }
  266. void    CGUIEvent::StandardConfig()
  267. {
  268.     RegisterState(CGUIEvent::eSelectState, 0, 0);
  269.     RegisterState(CGUIEvent::eSelectExtState, CGUIEvent::fShift, 0);        
  270.     // OS-specific settings
  271. #if   defined(NCBI_OS_MAC)  ||  defined(NCBI_OS_DARWIN)
  272.     RegisterState(CGUIEvent::eSelectIncState, CGUIEvent::fShift, 0);
  273.     RegisterState(CGUIEvent::eSelectIncState, CGUIEvent::fMeta, 0);
  274.     RegisterState(CGUIEvent::ePopupState, CGUIEvent::fCtrl, 0);
  275.     RegisterSignal(CGUIEvent::ePopupSignal, CGUIEvent::ePopupState, CGUIEvent::eLeftMousePush);    
  276. #elif defined(NCBI_OS_UNIX)
  277.     RegisterState(CGUIEvent::eSelectIncState, CGUIEvent::fCtrl, 0);
  278.     RegisterState(CGUIEvent::eSelectExtState, CGUIEvent::fShift | CGUIEvent::fCtrl, 0);        
  279.     
  280.     RegisterSignal(CGUIEvent::ePopupSignal, CGUIEvent::eSelectState, CGUIEvent::eRightMouseRelease);    
  281. #elif defined(NCBI_OS_MSWIN)
  282.     RegisterState(CGUIEvent::eSelectIncState, CGUIEvent::fCtrl, 0);        
  283.     RegisterState(CGUIEvent::eSelectExtState, CGUIEvent::fShift | CGUIEvent::fCtrl, 0);        
  284.     RegisterSignal(CGUIEvent::ePopupSignal, CGUIEvent::eSelectState, CGUIEvent::eRightMouseRelease);    
  285.     RegisterSignal(CGUIEvent::eSelectSignal, CGUIEvent::eSelectState, CGUIEvent::eRightMousePush);    
  286. #endif
  287.     RegisterState(CGUIEvent::eSelectAltState, CGUIEvent::fAlt, 0);
  288.    
  289.     RegisterSignal(CGUIEvent::eSelectSignal, CGUIEvent::eSelectState, CGUIEvent::eLeftMousePush);    
  290.     RegisterSignal(CGUIEvent::eSelectSignal, CGUIEvent::eSelectIncState, CGUIEvent::eLeftMousePush);
  291.     RegisterSignal(CGUIEvent::eSelectSignal, CGUIEvent::eSelectAltState, CGUIEvent::eLeftMousePush);
  292.     RegisterSignal(CGUIEvent::eSelectSignal, CGUIEvent::eSelectExtState, CGUIEvent::eLeftMousePush);
  293.     
  294.     RegisterState(CGUIEvent::eZoomState,     0, 'z');
  295.     RegisterState(CGUIEvent::eZoomRectState, 0, 'r');
  296.     RegisterState(CGUIEvent::eMarkState,     0, 'm');
  297.     RegisterState(CGUIEvent::ePanState,      0, 'p');
  298.     // ### these signals below should be registered as Shortcuts !
  299.     RegisterState(CGUIEvent::eSelectAllState, CGUIEvent::fCtrl, 'a');
  300.     RegisterState(CGUIEvent::eCopyState,      CGUIEvent::fCtrl, 'c');
  301.     RegisterState(CGUIEvent::eCutState,       CGUIEvent::fCtrl, 'x');
  302.     RegisterState(CGUIEvent::ePasteState,     CGUIEvent::fCtrl, 'v');
  303.     RegisterState(CGUIEvent::eUndoState,      CGUIEvent::fCtrl, 'z');
  304.     RegisterState(CGUIEvent::eRedoState,      CGUIEvent::fCtrl, 'y');
  305.     RegisterState(CGUIEvent::eDeleteState,    0, FL_Delete);
  306.     
  307.     RegisterShortcut(eMenuActivateSignal, 0, FL_F + 10);
  308.     RegisterShortcut(eZoomInSignal, 0, FL_KP + '+'); // gray +
  309.     RegisterShortcut(eZoomInSignal, 0, '=');         // '+'
  310.     RegisterShortcut(eZoomOutSignal, 0, FL_KP + '-'); // gray -
  311.     RegisterShortcut(eZoomOutSignal, 0, '-');    
  312.     
  313.     RegisterShortcut(eZoomAllSignal, 0, FL_KP + '*'); // gray * 
  314.     RegisterShortcut(eZoomAllSignal, 0, '8'); // '*'    
  315. }
  316. int     CGUIEvent::GetAccelByEvent()
  317. {
  318.     int accel = 0;
  319.     if(m_stPressedKeys.size() == 1) {
  320.         int key = *m_stPressedKeys.begin();
  321.         accel = toupper(key);
  322.         
  323.         if(m_Modifiers & fShift)    {
  324.             accel |= FL_SHIFT;
  325.         }
  326.         if(m_Modifiers & fCtrl)    {
  327.             accel |= FL_CTRL;
  328.         }
  329.         if(m_Modifiers & fAlt)    {
  330.             accel |= FL_ALT;
  331.         }
  332.         if(m_Modifiers & fMeta)    {
  333.             accel |= FL_META;
  334.         }
  335.     }
  336.     return accel;
  337. }
  338. CGUIEvent::TModTemplate   CGUIEvent::x_EncodeModTemplate(int mod_flags, int key) const
  339. {
  340.     return (mod_flags << 16) | key;
  341. }
  342. CGUIEvent::TEventTemplate   CGUIEvent::x_EncodeEventTemplate(EGUIState state, EMouseEvent event) const
  343. {
  344.     return (state << 16) | (0xFFFF & event);
  345. }
  346. CGUIEvent::TModTemplate   CGUIEvent::x_EncodeShortcutTemplate(int mod_flags, int key) const
  347. {
  348.     return (mod_flags << 16) | key;
  349. }
  350. void    CGUIEvent::x_UpdateEventState()
  351. {
  352.     int new_state = 0;
  353.     int fl_state = Fl::event_state();
  354.     
  355.     if(fl_state & FL_SHIFT) {
  356.         new_state |= fShift;
  357.     } 
  358.     if(fl_state & FL_CTRL) {
  359.         new_state |= fCtrl;
  360.     }
  361.     if(fl_state & FL_ALT) {
  362.         new_state |= fAlt;
  363.     }
  364.     if(fl_state & FL_META) {
  365.         new_state |= fMeta;
  366.     }    
  367.     m_Modifiers = new_state;
  368. }
  369. void    CGUIEvent::x_OnKeyPressed()
  370. {
  371.     int key = Fl::event_key();
  372.     //cout << "nCGUIEvent::x_OnKeyPressed() " << key;
  373.         
  374.     switch(key)
  375.     {
  376.     case FL_Shift_L:
  377.     case FL_Shift_R: m_Modifiers |= fShift; break;
  378.     case FL_Control_L:
  379.     case FL_Control_R: m_Modifiers |= fCtrl; break;
  380.     case FL_Alt_L:
  381.     case FL_Alt_R: m_Modifiers |= fAlt; break;
  382.     case FL_Meta_L:
  383.     case FL_Meta_R: m_Modifiers |= fMeta; break;
  384.     default: m_stPressedKeys.insert(key); break;
  385.     }
  386. }
  387. void    CGUIEvent::x_OnKeyReleased()
  388. {
  389.     int key = Fl::event_key();
  390.     //cout << "nCGUIEvent::x_OnKeyReleased() " << key;
  391.     
  392.     switch(key)
  393.     {
  394.     case FL_Shift_L:
  395.     case FL_Shift_R: m_Modifiers &= ~fShift; break;
  396.     case FL_Control_L:
  397.     case FL_Control_R: m_Modifiers &= ~fCtrl; break;
  398.     case FL_Alt_L:
  399.     case FL_Alt_R: m_Modifiers &= ~fAlt; break;
  400.     case FL_Meta_L:
  401.     case FL_Meta_R: m_Modifiers &= ~fMeta; break;
  402.     default: m_stPressedKeys.erase(key); break;
  403.     }
  404. }
  405. END_NCBI_SCOPE
  406. /*
  407.  * ===========================================================================
  408.  * $Log: gui_event.cpp,v $
  409.  * Revision 1000.1  2004/06/01 21:04:59  gouriano
  410.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  411.  *
  412.  * Revision 1.6  2004/05/27 17:19:52  johnson
  413.  * Add right mouse select signal to StandardConfig on mswin
  414.  *
  415.  * Revision 1.5  2004/05/21 22:27:51  gorelenk
  416.  * Added PCH ncbi_pch.hpp
  417.  *
  418.  * Revision 1.4  2004/05/13 17:18:12  yazhuk
  419.  * Added support for accelerators
  420.  *
  421.  * Revision 1.3  2004/04/05 14:39:36  yazhuk
  422.  * Implemented support for Shortcuts
  423.  *
  424.  * Revision 1.2  2004/03/23 13:39:54  dicuccio
  425.  * Added new event (eDeleteState)
  426.  *
  427.  * Revision 1.1  2004/03/17 19:51:59  yazhuk
  428.  * Moved Event classes from fltk_utils.cpp
  429.  *
  430.  * ===========================================================================
  431.  */