Back to index

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