nux-1.14.0
MouseHandler.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 #include "Nux.h"
00023 #include "MouseHandler.h"
00024 
00025 namespace nux
00026 {
00027 //extern bool gMouseOwned;
00028   AreaEventProcessor *gFocusMouseHandler = 0; // put this is the GfxServer class
00029 
00030 // static void SetMouseFocusOwner(AreaEventProcessor* ptr)
00031 // {
00032 //     gFocusMouseHandler = ptr;
00033 //     if(ptr)
00034 //         gMouseOwned = true;
00035 //     else
00036 //         gMouseOwned = false;
00037 // }
00038 //
00039 // static AreaEventProcessor* GetMouseFocusOwner()
00040 // {
00041 //     return gFocusMouseHandler;
00042 // }
00043 
00044   AreaEventProcessor::AreaEventProcessor()
00045   {
00046     ResetState ();
00047   }
00048 
00049   AreaEventProcessor::~AreaEventProcessor()
00050   {
00051 
00052   }
00053 
00054   void AreaEventProcessor::ResetState ()
00055   {
00056     _initial_state      = true;
00057     _has_mouse_focus    = false;
00058     _current_mouse_in   = false;
00059     _previous_mouse_in  = false;
00060     _state              = 0;
00061   }
00062 
00063   unsigned int AreaEventProcessor::EventProcessor (Event &event, const Geometry &geo, bool process_mouse_focus)
00064   {
00065     // preserve mouse focus state.
00066     bool has_mouse_focus = ((_state & AREA_MOUSE_STATUS_FOCUS) != 0) ? true : false;
00067 
00068     _state = AREA_MOUSE_STATUS_NONE;
00069 
00070     if (has_mouse_focus)
00071       _state |= AREA_MOUSE_STATUS_FOCUS;
00072 
00073     if (event.e_event == NUX_NO_EVENT)
00074       return _state;
00075 
00076     _previous_mouse_in = _current_mouse_in;
00077 
00078     int x, y, lo_x, hi_x, lo_y, hi_y;
00079     // Usually (e_x_root, e_y_root) is equal to (0, 0). In that case, (x, y) is the mouse coordinate
00080     // that refers to the top-left corner of the window.
00081     // If (e_x_root, e_y_root) is equal to the top left corner of this area in the window,
00082     // then (x, y) represent the coordinate of the mouse based on the top-left corner of this area.
00083     x = event.e_x - event.e_x_root;
00084     y = event.e_y - event.e_y_root;
00085 
00086     lo_x = geo.x;
00087     hi_x = geo.x + geo.GetWidth() - 1;
00088     lo_y = geo.y;
00089     hi_y = geo.y + geo.GetHeight() - 1;
00090 
00091     if ((event.e_x == -1) && (event.e_y == -1))
00092     {
00093       // e_x == -1 and e_y == -1 are associated with some specific window events that have the mouse outside of any widget.
00094       // See WM_SETFOCUS, WM_KILLFOCUS, NUX_WINDOW_MOUSELEAVE
00095       _current_mouse_in = false;
00096     }
00097     else
00098     {
00099       _current_mouse_in = PT_IN_BOX (x, y, lo_x, hi_x, lo_y, hi_y);
00100     }
00101 
00102 
00103     if (_initial_state)
00104     {
00105       _initial_state = false;
00106     }
00107     else
00108     {
00109       if ( (_previous_mouse_in == true) && (_current_mouse_in == false) )
00110       {
00111         _state |= AREA_MOUSE_STATUS_LEAVE;
00112       }
00113 
00114       if ( (_previous_mouse_in == false) && (_current_mouse_in == true) )
00115       {
00116         _state |= AREA_MOUSE_STATUS_ENTER;
00117       }
00118     }
00119     
00120     if (_state & AREA_MOUSE_STATUS_ENTER)
00121     {
00122       _mouse_deltax = 0;
00123       _mouse_deltay = 0;
00124     }
00125     else
00126     {
00127       _mouse_deltax = x - _mouse_positionx;
00128       _mouse_deltay = y - _mouse_positiony;
00129     }
00130     
00131     _mouse_positionx = x;
00132     _mouse_positiony = y;
00133 
00134     if ((_current_mouse_in == false) && !(_state & AREA_MOUSE_STATUS_FOCUS))
00135     {
00136       return _state;
00137     }
00138 
00139     if (process_mouse_focus == false)
00140     {
00141       return _state;
00142     }
00143 
00144     switch (event.e_event)
00145     {
00146       case NUX_MOUSE_PRESSED:
00147       case NUX_MOUSE_DOUBLECLICK:
00148       {
00149         if (_current_mouse_in)
00150         {
00151           _state |= AREA_MOUSE_STATUS_DOWN;
00152           _state |= AREA_MOUSE_STATUS_FOCUS;
00153           //SetMouseFocus (true);
00154         }
00155       }
00156       break;
00157 
00158       case NUX_MOUSE_RELEASED:
00159       {
00160         if (_state & AREA_MOUSE_STATUS_FOCUS)
00161         {
00162           _state |= AREA_MOUSE_STATUS_UP;
00163           _state &= ~AREA_MOUSE_STATUS_FOCUS;
00164           //SetMouseFocus (false);
00165         }
00166       }
00167       break;
00168 
00169       case NUX_MOUSE_MOVE:
00170       {
00171         _state |= AREA_MOUSE_STATUS_MOVE;
00172       }
00173       break;
00174 
00175       default:
00176       break;
00177     }
00178 
00179     return _state;
00180   }
00181 
00182 //   void AreaEventProcessor::SetMouseFocus (bool focus)
00183 //   {
00184 //     if (focus)
00185 //     {
00186 //       _has_mouse_focus = true;
00187 //     }
00188 //     else
00189 //     {
00190 //       _has_mouse_focus = false;
00191 //     }
00192 //   }
00193 
00194 //   bool AreaEventProcessor::ReleaseMouseFocus()
00195 //   {
00196 //     SetMouseFocus (false);
00197 //     return true;
00198 //   }
00199 
00200 //   bool AreaEventProcessor::IsMouseOwner()
00201 //   {
00202 //     return _has_mouse_focus;
00203 //   }
00204 
00205   bool AreaEventProcessor::MouseIn()
00206   {
00207     return _current_mouse_in;
00208   }
00209 
00210   void AreaEventProcessor::ForceMouseFocus (int x, int y, const Geometry &g)
00211   {
00212     int lo_x, hi_x, lo_y, hi_y;
00213     lo_x = g.x;
00214     hi_x = g.x + g.GetWidth() - 1;
00215     lo_y = g.y;
00216     hi_y = g.y + g.GetHeight() - 1;
00217 
00218     bool isIn = PT_IN_BOX ( x, y, lo_x, hi_x, lo_y, hi_y );
00219 
00220     if (isIn)
00221     {
00222       _previous_mouse_in = _current_mouse_in = true;
00223     }
00224     else
00225     {
00226       _previous_mouse_in = _current_mouse_in = false;
00227     }
00228 
00229     _state |= AREA_MOUSE_STATUS_DOWN;
00230     _has_mouse_focus = true;
00231   }
00232 
00233   void AreaEventProcessor::StopMouseFocus (int x, int y, const Geometry &g)
00234   {
00235     _has_mouse_focus = false;
00236   }
00237 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends