nux-1.14.0
InputArea.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 
00023 #include <sigc++/trackable.h>
00024 #include <sigc++/signal.h>
00025 #include <sigc++/functors/ptr_fun.h>
00026 #include <sigc++/functors/mem_fun.h>
00027 
00028 #include "NuxCore/Logger.h"
00029 
00030 #include "Nux.h"
00031 #include "InputArea.h"
00032 #include "NuxGraphics/GraphicsEngine.h"
00033 #include "WindowCompositor.h"
00034 
00035 namespace nux
00036 {
00037 namespace {
00038 logging::Logger logger("nux.inputarea");
00039 }
00040 
00041   NUX_IMPLEMENT_OBJECT_TYPE (InputArea);
00042 
00043   InputArea::InputArea (NUX_FILE_LINE_DECL)
00044     :   Area (NUX_FILE_LINE_PARAM)
00045     ,   m_AreaColor (color::Green)
00046   {
00047     SetGeometry(0, 0, 1, 1);
00048     _has_keyboard_focus = false;
00049 
00050     _capture_mouse_down_any_where_else = false;
00051     _double_click = false;
00052 
00053     _dnd_enabled_as_source = false;
00054     _dnd_enabled_as_target = false;
00055     _dnd_safety_x = 0;
00056     _dnd_safety_y = 0;
00057 
00058     _keyboard_receiver_ignore_mouse_down_outside = false;
00059   }
00060 
00061   InputArea::~InputArea()
00062   {
00063   }
00064 
00065   // TODO: DEPRECATED
00066   bool InputArea::ForceStartFocus (int x, int y)
00067   {
00068     return false;
00069   }
00070 
00071   // TODO: DEPRECATED
00072   void InputArea::ForceStopFocus (int x, int y)
00073   {
00074   }
00075 
00076   // TODO: DEPRECATED
00077   long InputArea::OnEvent (Event &event, long TraverseInfo, long ProcessEventInfo)
00078   {
00079     return 0;
00080   }
00081 
00082   void InputArea::OnDraw (GraphicsEngine &GfxContext, bool force_draw)
00083   {
00084     GfxContext.QRP_Color (GetBaseX(), GetBaseY(), GetBaseWidth(), GetBaseHeight(), m_AreaColor);
00085   }
00086 
00087   void InputArea::SetBaseString (const TCHAR *Caption)
00088   {
00089     Area::SetBaseString (Caption);
00090   }
00091 
00092   bool InputArea::HasKeyboardFocus()
00093   {
00094     return GetWindowCompositor ().GetKeyFocusArea () == this;
00095   }
00096 
00097   void InputArea::SetKeyboardFocus (bool b)
00098   {
00099     _has_keyboard_focus = b;
00100   }
00101 
00102   int InputArea::GetMouseX()
00103   {
00104     return _event_processor._mouse_positionx - GetRootX();
00105   }
00106 
00107   int InputArea::GetMouseY()
00108   {
00109     return _event_processor._mouse_positiony - GetRootY();
00110   }
00111 
00112   bool InputArea::IsMouseInside()
00113   {
00114     return _event_processor.MouseIn();
00115   }
00116 
00117   bool InputArea::HasMouseFocus()
00118   {
00119     return (_event_processor._state & AREA_MOUSE_STATUS_FOCUS ? true : false);
00120   }
00121 
00122   // TODO: DEPRECATED
00123   bool InputArea::MouseFocusOnOtherArea()
00124   {
00125     return false;
00126   }
00127 
00128   void InputArea::CaptureMouseDownAnyWhereElse (bool b)
00129   {
00130     _capture_mouse_down_any_where_else = b;
00131   }
00132 
00133   bool InputArea::IsCaptureMouseDownAnyWhereElse() const
00134   {
00135     return _capture_mouse_down_any_where_else;
00136   }
00137 
00138   void InputArea::EnableDoubleClick (bool double_click)
00139   {
00140     _double_click = double_click;
00141   }
00142 
00143   bool InputArea::DoubleClickEnabled() const
00144   {
00145     return _double_click;
00146   }
00147 
00148   void InputArea::SetKeyboardReceiverIgnoreMouseDownOutside(bool ignore_mouse_down_outside)
00149   {
00150     _keyboard_receiver_ignore_mouse_down_outside = ignore_mouse_down_outside;
00151   }
00152 
00153   bool InputArea::KeyboardReceiverIgnoreMouseDownOutside()
00154   {
00155     return _keyboard_receiver_ignore_mouse_down_outside;
00156   }
00157 
00158   void InputArea::SetAreaMousePosition (int x, int y)
00159   {
00160     _event_processor._mouse_positionx = x;
00161     _event_processor._mouse_positiony = y;
00162   }
00163 
00164   void InputArea::HandleDndMove (Event &event)
00165   {
00166 #if defined (NUX_OS_LINUX)
00167     std::list<char *> mimes;
00168 
00169     mimes = GetWindow ().GetDndMimeTypes ();
00170     std::list<char *>::iterator it;
00171     ProcessDndMove (event.e_x, event.e_y, mimes);
00172 
00173     for (it = mimes.begin (); it != mimes.end (); it++)
00174       g_free (*it);
00175 #endif
00176   }
00177 
00178   void InputArea::HandleDndDrop (Event &event)
00179   {
00180 #if defined (NUX_OS_LINUX)
00181     ProcessDndDrop (event.e_x, event.e_y);
00182 #endif
00183   }
00184 
00185 #if defined (NUX_OS_LINUX)
00186   void InputArea::SendDndStatus (bool accept, DndAction action, Geometry region)
00187   {
00188     GetWindow ().SendDndStatus (accept, action, Rect (region.x, region.y, region.width, region.height));
00189   }
00190 
00191   void InputArea::SendDndFinished (bool accepted, DndAction action)
00192   {
00193     GetWindow ().SendDndFinished (accepted, action);
00194   }
00195 
00196   void InputArea::ProcessDndMove (int x, int y, std::list<char *>mimes)
00197   {
00198     // must learn to deal with x/y offsets
00199     Area *parent = GetToplevel ();
00200 
00201     if (parent)
00202     {
00203       x += parent->GetGeometry ().x;
00204       y += parent->GetGeometry ().y;
00205     }
00206 
00207     SendDndStatus (false, DNDACTION_NONE, Geometry (x, y, GetGeometry ().width, GetGeometry ().height));
00208   }
00209 
00210   void InputArea::ProcessDndDrop (int x, int y)
00211   {
00212     SendDndFinished (false, DNDACTION_NONE);
00213   }
00214 
00215   void InputArea::ProcessDndEnter ()
00216   {
00217   }
00218 
00219   void InputArea::ProcessDndLeave ()
00220   {
00221   }
00222   
00223   void InputArea::SetDndEnabled (bool as_source, bool as_target)
00224   {
00225     _dnd_enabled_as_source = as_source;
00226     _dnd_enabled_as_target = as_target;
00227   }
00228   
00229   bool InputArea::DndSourceDragBegin ()
00230   {
00231     return false;
00232   }
00233   
00234   NBitmapData * InputArea::DndSourceGetDragImage ()
00235   {
00236     return 0;
00237   }
00238   
00239   std::list<const char *> InputArea::DndSourceGetDragTypes()
00240   {
00241     std::list<const char *> types;
00242     types.push_back ("text/plain;charset=utf-8");
00243     types.push_back ("UTF8_STRING");
00244     return types;
00245   }
00246     
00247   const char * InputArea::DndSourceGetDataForType(const char *type, int *size, int *format)
00248   {
00249     *format = 8;
00250 
00251     if (g_str_equal (type, "text/plain;charset=utf-8") || g_str_equal (type, "UTF8_STRING"))
00252     {
00253       *size = (int) strlen ("this is just a test");
00254       return "this is just a test";
00255     }
00256     
00257     *size = 0;
00258     return 0;
00259   }
00260   
00261   void InputArea::InnerDndSourceDragFinished(DndAction result, void *data) 
00262   { 
00263     InputArea *self = static_cast<InputArea *> (data);
00264     self->DndSourceDragFinished (result);
00265   }
00266   
00267   void InputArea::DndSourceDragFinished(DndAction result)
00268   {
00269   
00270   }
00271   
00272   void InputArea::StartDragAsSource()
00273   {
00274     GraphicsDisplay::DndSourceFuncs funcs;
00275     
00276     funcs.get_drag_image = &InputArea::InnerDndSourceGetDragImage;
00277     funcs.get_drag_types = &InputArea::InnerDndSourceGetDragTypes;
00278     funcs.get_data_for_type = &InputArea::InnerDndSourceGetDataForType;
00279     funcs.drag_finished = &InputArea::InnerDndSourceDragFinished;
00280     
00281     if (DndSourceDragBegin())
00282       GetWindow().StartDndDrag(funcs, this);
00283   }
00284 #endif
00285 
00286   void InputArea::DoSetFocused(bool focused)
00287   {
00288     Area::DoSetFocused(focused);
00289     SetKeyboardFocus(focused);
00290   }
00291   
00292   void InputArea::GrabPointer()
00293   {
00294     GetWindowCompositor().GrabPointerAdd (this);
00295   }
00296   
00297   void InputArea::UnGrabPointer()
00298   {
00299     GetWindowCompositor ().GrabPointerRemove (this);
00300   }
00301 
00302   void InputArea::GrabKeyboard()
00303   {
00304     GetWindowCompositor().GrabKeyboardAdd (this);
00305   }
00306   
00307   void InputArea::UnGrabKeyboard()
00308   {
00309     GetWindowCompositor().GrabKeyboardRemove (this);
00310   }
00311   
00312   bool InputArea::OwnsPointerGrab()
00313   {
00314     return GetWindowCompositor().GetPointerGrabArea() == this;
00315   }
00316   
00317   bool InputArea::OwnsKeyboardGrab ()
00318   {
00319     return GetWindowCompositor ().GetKeyboardGrabArea() == this;
00320   }
00321 
00322   bool InputArea::IsMouseOwner()
00323   {
00324     return (GetWindowCompositor().GetMouseOwnerArea() == this);
00325   }
00326 
00327   // == Signals with 1 to 1 mapping to input device ==
00328   void InputArea::EmitMouseDownSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00329   {
00330     mouse_down.emit(x, y, mouse_button_state, special_keys_state);
00331   }
00332 
00333   void InputArea::EmitMouseUpSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00334   {
00335     mouse_up.emit(x, y, mouse_button_state, special_keys_state);
00336   }
00337 
00338   void InputArea::EmitMouseMoveSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state)
00339   {
00340     mouse_move.emit(x, y, dx, dy, mouse_button_state, special_keys_state);
00341   }
00342 
00343   void InputArea::EmitMouseWheelSignal(int x, int y, int wheel_delta, unsigned long mouse_button_state, unsigned long special_keys_state)
00344   {
00345     mouse_wheel.emit(x, y, wheel_delta, mouse_button_state, special_keys_state);
00346   }
00347 
00348   void InputArea::EmitKeyDownSignal(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
00349   {
00350     //OnKeyPressed.emit(key_symbol, x11_key_code, special_keys_state);
00351   }
00352 
00353   void InputArea::EmitKeyUpSignal(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
00354   {
00355     key_up.emit(key_symbol, x11_key_code, special_keys_state);
00356   }
00357 
00358   void InputArea::EmitKeyEventSignal(unsigned long event_type,
00359     unsigned int key_sym,
00360     unsigned long special_keys_state,
00361     const char* text,
00362     int key_repeat_count)
00363   {
00364     key_down.emit(
00365       event_type,
00366       key_sym,
00367       special_keys_state,
00368       text,
00369       key_repeat_count);
00370   }
00371 
00372   void InputArea::EmitMouseDragSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state)
00373   {
00374     mouse_drag.emit(x, y, dx, dy, mouse_button_state, special_keys_state);
00375   }
00376 
00377   void InputArea::EmitMouseEnterSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00378   {
00379     _event_processor._current_mouse_in = true;
00380     mouse_enter.emit(x, y, mouse_button_state, special_keys_state);
00381   }
00382 
00383   void InputArea::EmitMouseLeaveSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00384   {
00385     _event_processor._current_mouse_in = false;
00386     mouse_leave.emit(x, y, mouse_button_state, special_keys_state);
00387   }
00388 
00389   void InputArea::EmitMouseClickSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00390   {
00391     mouse_click.emit(x, y, mouse_button_state, special_keys_state);
00392   }
00393 
00394   void InputArea::EmitMouseDoubleClickSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00395   {
00396     mouse_double_click.emit(x, y, mouse_button_state, special_keys_state);
00397   }
00398 
00399 
00400   void InputArea::EmitStartKeyboardFocus()
00401   {
00402     begin_key_focus.emit();
00403   }
00404 
00405   void InputArea::EmitEndKeyboardFocus()
00406   {
00407     end_key_focus.emit();
00408   }
00409 
00410   void InputArea::EmitMouseDownOutsideArea(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
00411   {
00412     mouse_down_outside_pointer_grab_area.emit(x, y, mouse_button_state, special_keys_state);
00413   }
00414 
00415   Area* InputArea::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type)
00416   {
00417     if(TestMousePointerInclusion(mouse_position, event_type))
00418     {
00419       return this;
00420     }
00421     return NULL;
00422   }
00423 
00424   Area* InputArea::FindKeyFocusArea(unsigned int key_symbol,
00425                           unsigned long x11_key_code,
00426                           unsigned long special_keys_state)
00427   {
00428     if (has_key_focus_)
00429     {
00430       return this;
00431     }
00432     else if (next_object_to_key_focus_area_)
00433     {
00434       return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
00435     }
00436     return NULL;
00437   }
00438 
00439   bool InputArea::AcceptKeyNavFocus()
00440   {
00441     return false;
00442   }
00443 }
00444 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends