Back to index

nux  3.0.0
Area.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 "Nux.h"
00024 #include "Area.h"
00025 #include "NuxGraphics/GraphicsEngine.h"
00026 #include "Layout.h"
00027 #include "VSplitter.h"
00028 #include "HSplitter.h"
00029 #include "BaseWindow.h"
00030 #include "MenuPage.h"
00031 
00032 namespace nux
00033 {
00034 
00035   NUX_IMPLEMENT_OBJECT_TYPE(Area);
00036 
00037   Area::Area(NUX_FILE_LINE_DECL)
00038     :   InitiallyUnownedObject(NUX_FILE_LINE_PARAM)
00039     ,   geometry_(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)
00040     ,   min_size_(AREA_MIN_WIDTH, AREA_MIN_HEIGHT)
00041     ,   max_size_(AREA_MAX_WIDTH, AREA_MAX_HEIGHT)
00042     ,   layout_done_(true)
00043   {
00044     window_thread_ = GetWindowThread();
00045     visible_ = true;
00046     view_enabled_ = true;
00047     parent_area_ = NULL;
00048 
00049     next_object_to_key_focus_area_ = NULL;
00050     has_key_focus_ = false;
00051 
00052     scale_factor_ = 1;
00053     sensitive_ = true;
00054 
00055     on_geometry_change_reconfigure_parent_layout_ = true;
00056     accept_mouse_wheel_event_ = false;
00057     accept_keyboard_event_ = false;
00058 
00059     _2d_xform.Identity();
00060     _3d_xform.Identity();
00061     _3d_area = false;
00062   }
00063 
00064 
00065   Area::~Area()
00066   {
00067   }
00068 
00069   const NString &Area::GetBaseString() const
00070   {
00071     return _base_string;
00072   }
00073 
00074   void Area::SetBaseString(const char *Caption)
00075   {
00076     _base_string = Caption;
00077   }
00078 
00079   void Area::CheckMinSize()
00080   {
00081     int w = min_size_.width;
00082     w = Max<int>(AREA_MIN_WIDTH, w);
00083     int h = min_size_.height;
00084     h = Max<int>(AREA_MIN_HEIGHT, h);
00085 
00086     min_size_ = Size(w, h);
00087 
00088     if (min_size_.width > max_size_.width)
00089     {
00090       max_size_.width = min_size_.width;
00091     }
00092 
00093     if (min_size_.height > max_size_.height)
00094     {
00095       max_size_.height = min_size_.height;
00096     }
00097 
00098     if (geometry_.width < min_size_.width)
00099     {
00100       geometry_.width = min_size_.width;
00101     }
00102 
00103     if (geometry_.height < min_size_.height )
00104     {
00105       geometry_.height = min_size_.height;
00106     }
00107   }
00108 
00109   void Area::CheckMaxSize()
00110   {
00111     int w = max_size_.width;
00112     w = w <= AREA_MAX_WIDTH ? w : AREA_MAX_WIDTH;
00113     int h = max_size_.height;
00114     h = h <= AREA_MAX_HEIGHT ? h: AREA_MAX_HEIGHT;
00115 
00116     max_size_ = Size(w, h);
00117 
00118     if (min_size_.width > max_size_.width)
00119     {
00120       min_size_.width = max_size_.width;
00121     }
00122 
00123     if (min_size_.height > max_size_.height)
00124     {
00125       min_size_.height = max_size_.height;
00126     }
00127 
00128     if (geometry_.width > max_size_.width)
00129     {
00130       geometry_.width = max_size_.width;
00131     }
00132 
00133     if (geometry_.height > max_size_.height)
00134     {
00135       geometry_.height = max_size_.height;
00136     }
00137   }
00138 
00139   void Area::SetMinimumSize(int w, int h)
00140   {
00141     nuxAssert(w >= 0);
00142     nuxAssert(h >= 0);
00143     min_size_ = Size(w, h);
00144 
00145     CheckMinSize();
00146 
00147     ReconfigureParentLayout();
00148   }
00149 
00150   void Area::SetMaximumSize(int w, int h)
00151   {
00152     nuxAssert(w >= 0);
00153     nuxAssert(h >= 0);
00154     max_size_ = Size(w, h);
00155 
00156     CheckMaxSize();
00157 
00158     ReconfigureParentLayout();
00159   }
00160 
00161   void Area::SetMinMaxSize(int w, int h)
00162   {
00163     nuxAssert(w >= 0);
00164     nuxAssert(h >= 0);
00165     SetMinimumSize(w, h);
00166     SetMaximumSize(w, h);
00167 
00168     //ReconfigureParentLayout();
00169   }
00170 
00171   void Area::ApplyMinWidth()
00172   {
00173     geometry_.width = min_size_.width;
00174 
00175     ReconfigureParentLayout();
00176   }
00177 
00178   void Area::ApplyMinHeight()
00179   {
00180     geometry_.height = min_size_.height;
00181 
00182     ReconfigureParentLayout();
00183   }
00184 
00185   void Area::ApplyMaxWidth()
00186   {
00187     geometry_.width = max_size_.width;
00188 
00189     ReconfigureParentLayout();
00190   }
00191 
00192   void Area::ApplyMaxHeight()
00193   {
00194     geometry_.height = max_size_.height;
00195 
00196     ReconfigureParentLayout();
00197   }
00198 
00199   Size Area::GetMinimumSize() const
00200   {
00201     return min_size_;
00202   }
00203 
00204   Size Area::GetMaximumSize() const
00205   {
00206     return max_size_;
00207   }
00208 
00209   void Area::SetMinimumWidth(int w)
00210   {
00211     nuxAssert(w >= 0);
00212     min_size_.width = w;
00213     CheckMinSize();
00214     ReconfigureParentLayout();
00215   }
00216 
00217   void Area::SetMaximumWidth(int w)
00218   {
00219     nuxAssert(w >= 0);
00220     max_size_.width = w;
00221     CheckMaxSize();
00222     ReconfigureParentLayout();
00223   }
00224 
00225   void Area::SetMinimumHeight(int h)
00226   {
00227     nuxAssert(h >= 0);
00228     min_size_.height = h;
00229     CheckMinSize();
00230     ReconfigureParentLayout();
00231   }
00232 
00233   void Area::SetMaximumHeight(int h)
00234   {
00235     nuxAssert(h >= 0);
00236     max_size_.height = h;
00237     CheckMaxSize();
00238     ReconfigureParentLayout();
00239   }
00240 
00241   int Area::GetMinimumWidth() const
00242   {
00243     return min_size_.width;
00244   }
00245 
00246   int Area::GetMaximumWidth() const
00247   {
00248     return max_size_.width;
00249   }
00250 
00251   int Area::GetMinimumHeight() const
00252   {
00253     return min_size_.height;
00254   }
00255 
00256   int Area::GetMaximumHeight() const
00257   {
00258     return max_size_.height;
00259   }
00260 
00261   unsigned int Area::GetScaleFactor()
00262   {
00263     return scale_factor_;
00264   }
00265 
00266   void Area::SetScaleFactor(unsigned int sf)
00267   {
00268     // re implemented by Layout
00269     scale_factor_ = sf;
00270   }
00271 
00272   bool Area::SetParentObject(Area *parent)
00273   {
00274     if (parent == 0)
00275     {
00276       nuxAssertMsg(0, "[Area::SetParentObject] Invalid parent obejct.");
00277       return false;
00278     }
00279 
00280     if (parent_area_ && (parent_area_ != parent))
00281     {
00282       nuxAssertMsg(0, "[Area::SetParentObject] Object already has a parent. You must UnParent the object before you can parenting again.");
00283       return false;
00284     }
00285 
00286     if (parent_area_)
00287     {
00288       // Already parented to the same area. Return.
00289       return true;
00290     }
00291 
00292     parent_area_ = parent;
00293     Reference();
00294 
00295     return true;
00296   }
00297 
00298   void Area::UnParentObject()
00299   {
00300     // If the area is on the path to the key focus area, or has focus, reset it.
00301     if (has_key_focus_ || next_object_to_key_focus_area_)
00302     {
00303       GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(NULL, KEY_NAV_NONE);
00304     }
00305 
00306     if (parent_area_)
00307     {
00308       parent_area_ = 0;
00309       UnReference();
00310     }
00311   }
00312 
00313   Area *Area::GetParentObject() const
00314   {
00315     return parent_area_;
00316   }
00317 
00318   int Area::GetBaseX     () const
00319   {
00320     return geometry_.x;
00321   }
00322 
00323   int Area::GetBaseY     () const
00324   {
00325     return geometry_.y;
00326   }
00327 
00328   int Area::GetBaseWidth    () const
00329   {
00330     return geometry_.width;
00331   }
00332 
00333   int Area::GetBaseHeight   () const
00334   {
00335     return geometry_.height;
00336   }
00337 
00338   void Area::SetGeometry(int x, int y, int w, int h)
00339   {
00340     h = nux::Clamp<int> (h, min_size_.height, max_size_.height);
00341     w = nux::Clamp<int> (w, min_size_.width, max_size_.width);
00342 
00343     nux::Geometry geometry(x, y, w, h);
00344     if (geometry_ == geometry)
00345       return;
00346 
00347     GeometryChangePending();
00348     geometry_ = geometry;
00349     ReconfigureParentLayout();
00350     GeometryChanged();
00351 
00352     OnGeometryChanged.emit(this, geometry_);
00353   }
00354 
00355   void Area::SetGeometry(const Geometry &geo)
00356   {
00357     SetGeometry(geo.x, geo.y, geo.width, geo.height);
00358   }
00359 
00360   Geometry const& Area::GetGeometry() const
00361   {
00362     return geometry_;
00363   }
00364 
00365   void Area::SetBaseX(int x)
00366   {
00367     SetGeometry(x, geometry_.y, geometry_.width, geometry_.height);
00368   }
00369 
00370   void Area::SetBaseY    (int y)
00371   {
00372     SetGeometry(geometry_.x, y, geometry_.width, geometry_.height);
00373   }
00374 
00375   void Area::SetBaseXY    (int x, int y)
00376   {
00377     SetGeometry(x, y, geometry_.width, geometry_.height);
00378   }
00379 
00380   void Area::SetBaseSize(int w, int h)
00381   {
00382     SetGeometry(geometry_.x, geometry_.y, w, h);
00383   }
00384 
00385   void Area::SetBaseWidth(int w)
00386   {
00387     SetGeometry(geometry_.x, geometry_.y, w, geometry_.height);
00388   }
00389 
00390   void Area::SetBaseHeight(int h)
00391   {
00392     SetGeometry(geometry_.x, geometry_.y, geometry_.width, h);
00393   }
00394 
00395   void Area::IncreaseSize(int x, int y)
00396   {
00397     geometry_.OffsetPosition(x, y);
00398     OnResize.emit(geometry_.x, geometry_.y, geometry_.width, geometry_.height );
00399   }
00400 
00401   long Area::ComputeContentSize()
00402   {
00403     return (eCompliantWidth | eCompliantHeight);
00404   }
00405 
00406   void Area::ComputeContentPosition(float offsetX, float offsetY)
00407   {
00408 
00409   }
00410 
00411   void Area::SetReconfigureParentLayoutOnGeometryChange(bool reconfigure_parent_layout)
00412   {
00413     on_geometry_change_reconfigure_parent_layout_ = reconfigure_parent_layout;
00414   }
00415   
00416   bool Area::ReconfigureParentLayoutOnGeometryChange()
00417   {
00418     return on_geometry_change_reconfigure_parent_layout_;
00419   }
00420 
00421   void Area::ReconfigureParentLayout(Area *child)
00422   {
00423     if (on_geometry_change_reconfigure_parent_layout_ == false)
00424       return;
00425 
00426     if (window_thread_ && window_thread_->IsComputingLayout())
00427     {
00428       // there is no need to do the following while we are already computing the layout.
00429       // If we do, we will end up in an infinite loop.
00430       return;
00431     }
00432 
00433     if (this->Type().IsDerivedFromType(View::StaticObjectType))
00434     {
00435       // The object that is being resized is a View object and it has a parent.
00436       if (this->OwnsTheReference() == false && this->GetParentObject())
00437       {
00438         // Only reference parented areas.
00439         this->Reference();
00440       }
00441 
00442       View *ic = static_cast<View *>(this);
00443 
00444       if (ic->CanBreakLayout())
00445       {
00446 
00447         if ((child != 0) &&
00448              (ic->Type().IsObjectType(VSplitter::StaticObjectType) || ic->Type().IsObjectType(HSplitter::StaticObjectType)))
00449         {
00450           // If this element is a Splitter, then we submit its child to the refresh list. We don't want to submit the
00451           // splitter because this will cause a redraw of all parts of the splitter(costly and unnecessary).
00452           window_thread_->QueueObjectLayout(child);
00453         }
00454         else
00455         {
00456           window_thread_->QueueObjectLayout(ic);
00457         }
00458       }
00459       else if (ic->parent_area_)
00460         ic->parent_area_->ReconfigureParentLayout(this);
00461       else
00462       {
00463         window_thread_->QueueObjectLayout(ic);
00464       }
00465     }
00466     else if (this->Type().IsDerivedFromType(Layout::StaticObjectType))
00467     {
00468       // The object that is being resized is a View object and it has a parent.
00469       if (this->OwnsTheReference() == false && this->GetParentObject())
00470       {
00471         // Only reference parented areas.
00472         this->Reference();
00473       }
00474 
00475       Layout *layout = static_cast<Layout *>(this);
00476 
00477       if (layout->parent_area_)
00478       {
00479         if (layout->parent_area_->Type().IsDerivedFromType(View::StaticObjectType))
00480         {
00481           View *ic = (View *) (layout->parent_area_);
00482 
00483           if (ic->CanBreakLayout())
00484           {
00485             if ((child != 0) &&
00486                  (ic->Type().IsObjectType(VSplitter::StaticObjectType) || ic->Type().IsObjectType(HSplitter::StaticObjectType)))
00487             {
00488               // If the parent of this element is a splitter, then we submit its child to the refresh list. We don't want to submit the
00489               // splitter because this will cause a redraw of all parts of the splitter(costly and unnecessary).
00490               window_thread_->QueueObjectLayout(this);
00491             }
00492             else
00493             {
00494               window_thread_->QueueObjectLayout(ic);
00495             }
00496           }
00497           else
00498           {
00499             // The parent object of an object of type View is a Layout object type.
00500             layout->parent_area_->ReconfigureParentLayout(this);
00501           }
00502         }
00503         else
00504         {
00505           layout->parent_area_->ReconfigureParentLayout(this);
00506         }
00507       }
00508       else
00509       {
00510         // This is possibly the Main layout or the layout of a floating object(popup for example) unless the layout is not part of the object tree.
00511         window_thread_->QueueObjectLayout(layout);
00512       }
00513     }
00514     else
00515     {
00516       // The object that is being resized is a InputArea object.
00517       if (this->parent_area_)
00518       {
00519         // The object that is being resized is a View object and it has a parent.
00520         if (this->OwnsTheReference() == false && this->GetParentObject())
00521         {
00522           // Only reference parented areas.
00523           this->Reference();
00524         }
00525 
00526         // The parent object of an object of type InputArea is a Layout object type.
00527         this->parent_area_->ReconfigureParentLayout(this);
00528       }
00529     }
00530   }
00531 
00532   void Area::RequestBottomUpLayoutComputation(Area *bo_initiator)
00533   {
00534     if (parent_area_ && parent_area_->IsLayout())
00535     {
00536       parent_area_->RequestBottomUpLayoutComputation(bo_initiator);
00537     }
00538   }
00539 
00540   void Area::SetVisible(bool visible)
00541   {
00542     if (IsLayout())
00543       return;
00544 
00545     if (visible_ == visible)
00546       return;
00547 
00548     visible_ = visible;
00549 
00550     OnVisibleChanged.emit(this, visible_);
00551   }
00552 
00553   bool Area::IsVisible()
00554   {
00555     return visible_;
00556   }
00557 
00558   void Area::SetSensitive(bool sensitive)
00559   {
00560     SetInputEventSensitivity(sensitive);
00561   }
00562 
00563   void Area::SetInputEventSensitivity(bool sensitive)
00564   {
00565     if (IsLayout())
00566       return;
00567 
00568     if (sensitive_ == sensitive)
00569       return;
00570 
00571     sensitive_ = sensitive;
00572 
00573     OnSensitiveChanged.emit(this, sensitive_);
00574   }
00575 
00576   bool Area::IsSensitive() const
00577   {
00578     return GetInputEventSensitivity();
00579   }
00580 
00581   bool Area::GetInputEventSensitivity() const
00582   {
00583     return sensitive_;
00584   }
00585 
00586   MinorDimensionPosition Area::GetPositioning()
00587   {
00588     return minor_axis_position_;
00589   }
00590 
00591   void Area::SetPositioning(MinorDimensionPosition p)
00592   {
00593     minor_axis_position_ = p;
00594   }
00595 
00596   MinorDimensionSize Area::GetExtend()
00597   {
00598     return minor_axis_size_;
00599   }
00600 
00601   void Area::SetExtend(MinorDimensionSize ext)
00602   {
00603     minor_axis_size_ = ext;
00604   }
00605 
00606   float Area::GetPercentage()
00607   {
00608     return minor_axis_size_scale_;
00609   }
00610 
00611   void Area::SetPercentage(float p)
00612   {
00613     minor_axis_size_scale_ = p;
00614   }
00615 
00616   bool Area::IsLayoutDone()
00617   {
00618     return layout_done_;
00619   }
00620 
00621   void Area::SetLayoutDone(bool b)
00622   {
00623     layout_done_ = b;
00624   }
00625 
00626   bool Area::IsArea() const
00627   {
00628     return this->Type().IsDerivedFromType(Area::StaticObjectType);;
00629   }
00630 
00631   bool Area::IsInputArea() const
00632   {
00633     return this->Type().IsDerivedFromType(InputArea::StaticObjectType);;
00634   }
00635 
00636   bool Area::IsView() const
00637   {
00638     return this->Type().IsDerivedFromType(View::StaticObjectType);;
00639   }
00640 
00641   bool Area::IsLayout() const
00642   {
00643     return this->Type().IsDerivedFromType(Layout::StaticObjectType);
00644   }
00645 
00646   bool Area::IsViewWindow() const
00647   {
00648     return this->Type().IsDerivedFromType(BaseWindow::StaticObjectType);
00649   }
00650 
00651   bool Area::IsSpaceLayout() const
00652   {
00653     return this->Type().IsDerivedFromType(SpaceLayout::StaticObjectType);;
00654   }
00655 
00656   void Area::Set2DMatrix(const Matrix4 &mat)
00657   {
00658     _2d_xform = mat;
00659   }
00660 
00661   void Area::Set2DTranslation(float tx, float ty, float tz)
00662   {
00663     _2d_xform.Translate(tx, ty, tz);
00664   }
00665 
00666   Matrix4 Area::Get2DMatrix() const
00667   {
00668     return _2d_xform;
00669   }
00670 
00671   Matrix4 Area::Get3DMatrix() const
00672   {
00673     return _3d_xform;
00674   }
00675 
00676   bool Area::Is3DArea() const
00677   {
00678     return _3d_area;
00679   }
00680 
00681   static void MatrixXFormGeometry(const Matrix4 &matrix, Geometry &geo)
00682   {
00683     Vector4 in(geo.x, geo.y, 0, 1);
00684     // This is mean only for translation matrices. It will not work with matrices containing rotations or scalings.
00685     Vector4 out = matrix * in;
00686     geo.x = out.x;
00687     geo.y = out.y;
00688   }
00689 
00690   void Area::InnerGetAbsoluteGeometry(Geometry &geometry)
00691   {
00692     if (this->Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout()))
00693     {
00694       geometry.OffsetPosition(geometry_.x, geometry_.y);
00695       return;
00696     }
00697 
00698     MatrixXFormGeometry(_2d_xform, geometry);
00699 
00700     Area *parent = GetParentObject();
00701     if (parent)
00702       parent->InnerGetAbsoluteGeometry(geometry);
00703   }
00704 
00705   Geometry Area::GetAbsoluteGeometry() const
00706   {
00707     if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) ||
00708       Type().IsDerivedFromType(MenuPage::StaticObjectType) ||
00709       (this == window_thread_->GetLayout()))
00710     {
00711       // Do not apply the _2D_xform matrix  to a BaseWindow or the main layout
00712       return geometry_;
00713     }
00714     else
00715     {
00716       nux::Geometry geo = geometry_;
00717       MatrixXFormGeometry(_2d_xform, geo);
00718 
00719       Area *parent = GetParentObject();
00720       if (parent)
00721         parent->InnerGetAbsoluteGeometry(geo);
00722 
00723       return geo;
00724     }
00725   }
00726 
00727   int Area::GetAbsoluteX() const
00728   {
00729     return GetAbsoluteGeometry().x;
00730   }
00731 
00732   int Area::GetAbsoluteY() const
00733   {
00734     return GetAbsoluteGeometry().y;
00735   }
00736 
00737   int Area::GetAbsoluteWidth() const
00738   {
00739     return GetAbsoluteGeometry().width;
00740   }
00741 
00742   int Area::GetAbsoluteHeight() const
00743   {
00744     return GetAbsoluteGeometry().height;
00745   }
00746 
00747   void Area::InnerGetRootGeometry(Geometry &geometry)
00748   {
00749     if (this->Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout()))
00750       return;
00751 
00752     MatrixXFormGeometry(_2d_xform, geometry);
00753 
00754     Area *parent = GetParentObject();
00755     if (parent)
00756       parent->InnerGetRootGeometry(geometry);
00757   }
00758 
00759   Geometry Area::GetRootGeometry() const
00760   {
00761     nux::Geometry geo = geometry_;
00762     MatrixXFormGeometry(_2d_xform, geo);
00763 
00764     if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout()))
00765     {
00766       return geo;
00767     }
00768     else
00769     {
00770       Area *parent = GetParentObject();
00771       if (parent)
00772         parent->InnerGetRootGeometry(geo);
00773 
00774       return geo;
00775     }
00776   }
00777 
00778   int Area::GetRootX() const
00779   {
00780     return GetRootGeometry().x;
00781   }
00782 
00783   int Area::GetRootY() const
00784   {
00785     return GetRootGeometry().y;
00786   }
00787 
00788   int Area::GetRootWidth() const
00789   {
00790     return GetRootGeometry().width;
00791   }
00792 
00793   int Area::GetRootHeight() const
00794   {
00795     return GetRootGeometry().height;
00796   }
00797 
00798   Area* Area::GetToplevel()
00799   {
00800     return GetRootParent();
00801   }
00802 
00803   Area* Area::GetRootParent()
00804   {
00805     if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout()))
00806     {
00807       return this;
00808     }
00809 
00810     Area* parent = GetParentObject();
00811     if (!parent) //we didn't find a way to salvation!
00812     {
00813       return 0;
00814     }
00815     return parent->GetRootParent();
00816   }
00817 
00818   Area* Area::GetTopLevelViewWindow()
00819   {
00820     Area* area = GetRootParent();
00821 
00822     if (area && area->IsViewWindow())
00823       return area;
00824 
00825     return NULL;
00826   }
00827 
00828   bool Area::HasTopLevelParent()
00829   {
00830     if (GetRootParent())
00831     {
00832       return true;
00833     }
00834     return false;
00835   }
00836 
00837   bool Area::IsChildOf(Area* parent)
00838   {
00839     if (this == parent)
00840       return true;
00841 
00842     if (!parent || !parent_area_)
00843       return false;
00844 
00845     return parent_area_->IsChildOf(parent);    
00846   }
00847 
00848   void Area::QueueRelayout()
00849   {
00850     window_thread_->QueueObjectLayout(this);
00851   }
00852   
00853   void Area::SetAcceptKeyboardEvent(bool accept_keyboard_event)
00854   {
00855     accept_keyboard_event_ = accept_keyboard_event;
00856   }
00857 
00858   bool Area::AcceptKeyboardEvent() const
00859   {
00860     return accept_keyboard_event_;
00861   }
00862 
00863   void Area::SetAcceptMouseWheelEvent(bool accept_mouse_wheel_event)
00864   {
00865     accept_mouse_wheel_event_ = accept_mouse_wheel_event;
00866   }
00867 
00868   bool Area::AcceptMouseWheelEvent() const
00869   {
00870     return accept_mouse_wheel_event_;
00871   }
00872 
00873    bool Area::TestMousePointerInclusion(const Point& mouse_position, NuxEventType event_type)
00874    {
00875      if ((IsLayout() == false) && ((visible_ == false) ||
00876        (sensitive_ == false) ||
00877        (view_enabled_ == false)))
00878      {
00879        // If this area is not a view and:
00880        //    - it is insensitive to input event
00881        //    - it is not enabled
00882        //    - it is not visible
00883        // then return false.
00884        return false;
00885      }
00886  
00887      bool mouse_pointer_inside_area = false;
00888  
00889      if (Type().IsDerivedFromType(MenuPage::StaticObjectType))
00890      {
00891        // A MenuPage geometry is already in absolute coordinates.
00892        mouse_pointer_inside_area = geometry_.IsInside(mouse_position);
00893      }
00894      else
00895      {
00896        mouse_pointer_inside_area = GetAbsoluteGeometry().IsInside(mouse_position);
00897      }
00898  
00899      if ((event_type == NUX_MOUSE_WHEEL) && mouse_pointer_inside_area)
00900      {
00901        if (accept_mouse_wheel_event_ == false)
00902          return NULL;
00903      }
00904  
00905      return mouse_pointer_inside_area;
00906    }
00907  
00908    bool Area::TestMousePointerInclusionFilterMouseWheel(const Point& mouse_position, NuxEventType event_type)
00909    {
00910      if ((IsLayout() == false) && ((visible_ == false) ||
00911        (sensitive_ == false) ||
00912        (view_enabled_ == false)))
00913      {
00914        // If this area is not a view and:
00915        //    - it is insensitive to input event
00916        //    - it is not enabled
00917        //    - it is not visible
00918        // then return false.
00919  
00920        return false;
00921      }
00922  
00923      bool mouse_pointer_inside_area = false;
00924  
00925      if (Type().IsDerivedFromType(MenuPage::StaticObjectType))
00926      {
00927        // A MenuPage geometry is already in absolute coordinates.
00928        mouse_pointer_inside_area = geometry_.IsInside(mouse_position);
00929      }
00930      else
00931      {
00932        mouse_pointer_inside_area = GetAbsoluteGeometry().IsInside(mouse_position);
00933      }
00934  
00935      return mouse_pointer_inside_area;
00936    }
00937 
00938   Area* Area::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type)
00939   {
00940     return NULL;
00941   }
00942   
00943   Area* Area::FindKeyFocusArea(unsigned int key_symbol,
00944    unsigned long x11_key_code,
00945    unsigned long special_keys_state)
00946   {
00947     if (has_key_focus_)
00948     {
00949       return this;
00950     }
00951     else if (next_object_to_key_focus_area_)
00952     {
00953       return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
00954     }
00955     return NULL;
00956   }
00957 
00958   void Area::SetNextObjectToKeyFocusArea(Area* area)
00959   {
00960     next_object_to_key_focus_area_ = area;
00961   }
00962 
00963   Area* Area::GetNextObjectToKeyFocusArea()
00964   {
00965     return next_object_to_key_focus_area_;
00966   }
00967 
00968   void Area::SetPathToKeyFocusArea()
00969   {
00970     has_key_focus_ = true;
00971     next_object_to_key_focus_area_ = NULL;
00972 
00973     Area* child = this;
00974     Area* parent = GetParentObject();
00975 
00976     while (parent)
00977     {
00978       parent->next_object_to_key_focus_area_ = child;
00979       parent->next_object_to_key_focus_area_->Reference();
00980       parent->has_key_focus_ = false;
00981       child = parent;
00982       parent = parent->GetParentObject();
00983     }
00984   }
00985 
00986   void Area::ResetDownwardPathToKeyFocusArea()
00987   {
00988     has_key_focus_ = false;
00989     if (next_object_to_key_focus_area_)
00990     {
00991       next_object_to_key_focus_area_->ResetDownwardPathToKeyFocusArea();
00992     }
00993     if (next_object_to_key_focus_area_)
00994       next_object_to_key_focus_area_->UnReference();
00995 
00996     next_object_to_key_focus_area_ = NULL;
00997   }
00998 
00999   void Area::ResetUpwardPathToKeyFocusArea()
01000   {
01001     has_key_focus_ = false;
01002     if (parent_area_)
01003     {
01004       parent_area_->ResetUpwardPathToKeyFocusArea();
01005     }
01006     if (next_object_to_key_focus_area_)
01007       next_object_to_key_focus_area_->UnReference();
01008 
01009     next_object_to_key_focus_area_ = NULL;
01010   }
01011 
01012   bool Area::InspectKeyEvent(unsigned int event_type,
01013     unsigned int keysym,
01014     const char* character)
01015   {
01016     return false;
01017   }
01018 
01019   Area* Area::KeyNavIteration(KeyNavDirection direction)
01020   {
01021     return NULL;
01022   }
01023 
01024   bool Area::HasKeyFocus() const
01025   {
01026     return has_key_focus_;
01027   }
01028 
01029   bool Area::IsMousePointerInside() const
01030   {
01031     Geometry geo = GetAbsoluteGeometry();
01032     Point position = GetWindowThread()->GetWindowCompositor().GetMousePosition();
01033     
01034     if (geo.IsInside(position))
01035       return true;
01036 
01037     return false;
01038   }
01039 }
01040