nux-1.14.0
HSplitter.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 "Nux.h"
00024 #include "HSplitter.h"
00025 
00026 #include "NuxGraphics/GLTextureResourceManager.h"
00027 
00028 #include "WindowCompositor.h"
00029 #include "Layout.h"
00030 #include "HLayout.h"
00031 #include "VLayout.h"
00032 
00033 namespace nux
00034 {
00035 
00036   NUX_IMPLEMENT_OBJECT_TYPE (HSplitter);
00037   static const t_s32 HSPLITTERHEIGHT = 5;
00038   static const t_s32 HSTICK_SIZE = 5;
00039 
00040   HSplitter::HSplitter (NUX_FILE_LINE_DECL)
00041     :   View (NUX_FILE_LINE_PARAM)
00042   {
00043     new_addition                = false;
00044     m_initial_config            = true;
00045     m_focus_splitter_index      = -1;
00046     m_ResizeOnSplitterRelease   = true;
00047 
00048     mvt_dx = 0;
00049     mvt_dy = 0;
00050     m_current_x = 0;
00051     m_current_y = 0;
00052     m_current_width = 200;
00053     m_current_height = 200;
00054 
00055     //SetMinimumSize(200,200);
00056     SetGeometry (Geometry (m_current_x, m_current_y, m_current_width, m_current_height) );
00057   }
00058 
00059   HSplitter::~HSplitter()
00060   {
00061     std::vector< Area* >::iterator it0;
00062     for (it0 = m_InterfaceObject.begin(); it0 != m_InterfaceObject.end(); it0++)
00063     {
00064       (*it0)->UnParentObject();
00065     }
00066     m_InterfaceObject.clear();
00067 
00068     std::vector< MySplitter* >::iterator it2;
00069     for (it2 = m_SplitterObject.begin(); it2 != m_SplitterObject.end(); it2++)
00070     {
00071       (*it2)->UnParentObject();
00072     }
00073     m_SplitterObject.clear();
00074 
00075     m_SplitConfig.clear();
00076   }
00077 
00078   void HSplitter::Draw (GraphicsEngine &GfxContext, bool force_draw)
00079   {
00080     GfxContext.PushClippingRectangle (GetGeometry() );
00081     Geometry base = GetGeometry();
00082 //    std::vector<View*>::iterator it;
00083 //    for(it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++)
00084 //    {
00085 //        (*it)->ProcessDraw(force_draw);
00086 //    }
00087 
00088     GetPainter().PaintBackground (GfxContext, base);
00089     std::vector<MySplitter *>::iterator it_splitter;
00090 
00091     for (it_splitter = m_SplitterObject.begin(); it_splitter != m_SplitterObject.end(); it_splitter++)
00092     {
00093       Geometry geo = (*it_splitter)->GetGeometry();
00094       Geometry grip_geo;
00095       t_s32 w = 20;
00096 
00097       if (geo.GetWidth() > w)
00098       {
00099         grip_geo.SetX (geo.x + (geo.GetWidth() - w) / 2);
00100         grip_geo.SetY (geo.y);
00101         grip_geo.SetWidth (w);
00102         grip_geo.SetHeight (geo.GetHeight() );
00103       }
00104       else
00105       {
00106         grip_geo.SetX (geo.x - (w - geo.GetWidth() ) / 2);
00107         grip_geo.SetY (geo.y);
00108         grip_geo.SetWidth (w);
00109         grip_geo.SetHeight (geo.GetHeight() );
00110       }
00111 
00112       GetPainter().Draw2DLine (GfxContext, grip_geo.x, grip_geo.y + 1, grip_geo.x + grip_geo.GetWidth(), grip_geo.y + 1, Color (0xFF111111) );
00113       GetPainter().Draw2DLine (GfxContext, grip_geo.x, grip_geo.y + 3, grip_geo.x + grip_geo.GetWidth(), grip_geo.y + 3, Color (0xFF111111) );
00114     }
00115 
00116     GfxContext.PopClippingRectangle();
00117   }
00118 
00119   void HSplitter::DrawContent (GraphicsEngine &GfxContext, bool force_draw)
00120   {
00121     Geometry base = GetGeometry();
00122     GfxContext.PushClippingRectangle (base);
00123     bool need_redraw = IsRedrawNeeded();
00124 
00125     std::vector<MySplitter *>::iterator it_splitter;
00126     std::vector<Area *>::iterator it;
00127 
00128     //for(it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++)
00129     for (it = m_InterfaceObject.begin(), it_splitter = m_SplitterObject.begin();
00130          it != m_InterfaceObject.end();
00131          it++, it_splitter++)
00132     {
00133       Geometry sgeo = (*it_splitter)->GetGeometry();
00134       GfxContext.PushClippingRectangle (Rect (
00135                                           base.x, base.y, base.GetWidth(), sgeo.y - base.y) );
00136 
00137       base.SetY (sgeo.y + sgeo.GetHeight() );
00138 
00139       if (force_draw || need_redraw)
00140       {
00141         if ( (*it)->Type().IsDerivedFromType (View::StaticObjectType) )
00142         {
00143           View *ic = static_cast<View *>(*it);
00144           ic->ProcessDraw (GfxContext, true);
00145         }
00146         else if ( (*it)->Type().IsObjectType (InputArea::StaticObjectType) )
00147         {
00148           InputArea *base_area = static_cast<InputArea *>(*it);
00149           base_area->OnDraw (GfxContext, true);
00150         }
00151         else if ( (*it)->Type().IsObjectType (HLayout::StaticObjectType) )
00152         {
00153           HLayout *layout = static_cast<HLayout *>(*it);
00154           layout->ProcessDraw (GfxContext, true);
00155         }
00156         else if ( (*it)->Type().IsObjectType (VLayout::StaticObjectType) )
00157         {
00158           VLayout *layout = static_cast<VLayout *>(*it);
00159           layout->ProcessDraw (GfxContext, true);
00160         }
00161       }
00162       else
00163       {
00164         if ( (*it)->Type().IsDerivedFromType (View::StaticObjectType) )
00165         {
00166           View *ic = static_cast<View *>(*it);
00167           ic->ProcessDraw (GfxContext, false);
00168         }
00169         else if ( (*it)->Type().IsObjectType (InputArea::StaticObjectType) )
00170         {
00171           InputArea *base_area = static_cast<InputArea *>(*it);
00172           base_area->OnDraw (GfxContext, false);
00173         }
00174         else if ( (*it)->Type().IsObjectType (HLayout::StaticObjectType) )
00175         {
00176           HLayout *layout = static_cast<HLayout *>(*it);
00177           layout->ProcessDraw (GfxContext, false);
00178         }
00179         else if ( (*it)->Type().IsObjectType (VLayout::StaticObjectType) )
00180         {
00181           VLayout *layout = static_cast<VLayout *>(*it);
00182           layout->ProcessDraw (GfxContext, false);
00183         }
00184       }
00185 
00186       GfxContext.PopClippingRectangle();
00187     }
00188 
00189     GfxContext.PopClippingRectangle();
00190   }
00191 
00192   void HSplitter::PostDraw (GraphicsEngine &GfxContext, bool force_draw)
00193   {
00194 
00195   }
00196 
00197   void HSplitter::OverlayDrawing (GraphicsEngine &GfxContext)
00198   {
00199     t_u32 num_element = (t_u32) m_SplitterObject.size();
00200 
00201     Geometry base = GetGeometry();
00202 
00203     if (m_focus_splitter_index >= 0)
00204     {
00205       Geometry geo = m_SplitterObject[m_focus_splitter_index]->GetGeometry();
00206       geo.OffsetPosition (mvt_dx, mvt_dy);
00207 
00208       if (m_focus_splitter_index == 0 && num_element > 1)
00209       {
00210         if (geo.y < base.y)
00211         {
00212           geo.SetY (base.y);
00213         }
00214 
00215         if (geo.y  + HSPLITTERHEIGHT > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y)
00216         {
00217           geo.SetY (m_SplitterObject[m_focus_splitter_index+1]->GetGeometry().y - HSPLITTERHEIGHT);
00218         }
00219       }
00220 
00221       if ( (m_focus_splitter_index > 0) && (m_focus_splitter_index < (t_s32) num_element - 1) )
00222       {
00223         if (geo.y < m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().y + HSPLITTERHEIGHT)
00224         {
00225           geo.SetY (m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().y + HSPLITTERHEIGHT);
00226         }
00227 
00228         if (geo.y + HSPLITTERHEIGHT > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y)
00229         {
00230           geo.SetY (m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y - HSPLITTERHEIGHT);
00231         }
00232       }
00233 
00234       GfxContext.GetRenderStates().SetBlend (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00235       {
00236         GetPainter().Paint2DQuadColor (GfxContext, geo, Color (0xBB868686) );
00237       }
00238       GfxContext.GetRenderStates().SetBlend (false);
00239     }
00240   }
00241 
00242   void HSplitter::AddWidget (Area *ic, float stretchfactor)
00243   {
00244     if (ic)
00245     {
00246       MySplitter *splitter = new MySplitter;
00247       splitter->SetParentObject(this);
00248       //splitter->SinkReference();
00249 
00250       t_u32 no = (t_u32) m_InterfaceObject.size();
00251       splitter->mouse_down.connect (sigc::bind ( sigc::mem_fun (this, &HSplitter::OnSplitterMouseDown), no) );
00252       splitter->mouse_drag.connect (sigc::bind ( sigc::mem_fun (this, &HSplitter::OnSplitterMouseDrag), no) );
00253       splitter->mouse_up.connect (sigc::bind ( sigc::mem_fun (this, &HSplitter::OnSplitterMouseUp), no) );
00254 
00255       ic->SetParentObject (this);
00256       m_InterfaceObject.push_back (ic);
00257       m_SplitterObject.push_back (splitter);
00258       m_SplitConfig.push_back (stretchfactor);
00259 
00260       new_addition = true;
00261       ComputeChildLayout();
00262     }
00263   }
00264 
00265   void HSplitter::clearContent()
00266   {
00267     m_InterfaceObject.clear();
00268   }
00269 
00270   long HSplitter::ComputeChildLayout()
00271   {
00272     t_u32 num_element = (t_u32) m_InterfaceObject.size();
00273     t_s32 x = GetBaseX();
00274     t_s32 y = GetBaseY();
00275     t_s32 w = GetBaseWidth();
00276     t_s32 h = GetBaseHeight();
00277 
00278     if ( (w == 0) || (h == 0) )
00279     {
00280       return eCompliantHeight | eCompliantWidth;
00281     }
00282 
00283     if (num_element < 1)
00284     {
00285       m_current_height = h;
00286       m_current_width = w;
00287       m_current_x = x;
00288       m_current_y = y;
00289 
00290       new_addition = false;
00291       return eCompliantHeight | eCompliantWidth;
00292     }
00293 
00294     std::vector<Area *>::iterator it;
00295     std::vector<MySplitter *>::iterator it_splitter;
00296 
00297     if (new_addition)
00298     {
00299       ResetSplitConfig();
00300       new_addition = false;
00301     }
00302 
00303     if (m_current_width != w)
00304     {
00305       for (t_u32 i = 0; i < num_element; i++)
00306       {
00307         Geometry splitter_geo = m_SplitterObject[i]->GetGeometry();
00308         splitter_geo.SetWidth (w);
00309         splitter_geo.SetX (x);
00310 
00311         m_SplitterObject[i]->SetGeometry (splitter_geo);
00312       }
00313     }
00314 
00315     if (m_current_height != h)
00316     {
00317       t_s32 size_to_distribute = h - num_element * HSPLITTERHEIGHT;
00318       t_s32 previous_spliter_end = m_current_y;
00319       t_s32 new_spliter_end = y;
00320 
00321       for (t_u32 i = 0; i < num_element; i++)
00322       {
00323         Geometry splitter_geo = m_SplitterObject[i]->GetGeometry();
00324         // compute percentage of space occupied by the element i;
00325         // width of element i = m_SplitterObject[i]->GetY() - previous_splliter_end
00326         t_s32 splitter_start = m_SplitterObject[i]->GetBaseY();
00327         float percent = float (splitter_start - previous_spliter_end) / float (m_current_height - num_element * HSPLITTERHEIGHT);
00328 
00329         if (percent > 1.0f)
00330           percent = 1.0f;
00331 
00332         splitter_geo.SetY (new_spliter_end + size_to_distribute * percent);
00333         previous_spliter_end = splitter_start + HSPLITTERHEIGHT;
00334         new_spliter_end = new_spliter_end + size_to_distribute * percent + HSPLITTERHEIGHT;
00335         m_SplitterObject[i]->SetGeometry (splitter_geo);
00336       }
00337 
00338       if (m_SplitterObject[0]->GetBaseY() < y)
00339       {
00340         m_SplitterObject[0]->SetBaseY (y);
00341       }
00342 
00343       m_SplitterObject[num_element-1]->SetBaseY (y + h - HSPLITTERHEIGHT);
00344     }
00345 
00346     t_s32 accheight = y;
00347 
00348     for (t_u32 i = 0; i < num_element; i++)
00349     {
00350       Geometry splitter_geo = m_SplitterObject[i]->GetGeometry();
00351 
00352       //m_InterfaceObject[i]->SetGeometry(Geometry(x, accheight, w, splitter_geo.y - accheight));
00353 
00354       if (m_InterfaceObject[i]->Type().IsDerivedFromType (View::StaticObjectType) )
00355       {
00356         View *ic = static_cast<View *>(m_InterfaceObject[i]);
00357         ic->SetGeometry (Geometry (x, accheight, w, splitter_geo.y - accheight) );
00358         // if we are already computing the layout from the main window down, we need to call
00359         // ComputeElementLayout to force the computing of this element layout.
00360         GetWindowThread ()->ComputeElementLayout (ic);
00361       }
00362       else if (m_InterfaceObject[i]->Type().IsObjectType (InputArea::StaticObjectType) )
00363       {
00364         InputArea *base_area = static_cast<InputArea *>(m_InterfaceObject[i]);
00365         base_area->SetGeometry (Geometry (x, accheight, w, splitter_geo.y - accheight) );
00366       }
00367       else if (m_InterfaceObject[i]->Type().IsDerivedFromType (Layout::StaticObjectType) )
00368       {
00369         Layout *layout = static_cast<Layout *>(m_InterfaceObject[i]);
00370         layout->SetGeometry (Geometry (x, accheight, w, splitter_geo.y - accheight) );
00371         // if we are already computing the layout from the main window down, we need to call
00372         // ComputeElementLayout to force the computing of this element layout.
00373         GetWindowThread ()->ComputeElementLayout (layout);
00374       }
00375 
00376       accheight += splitter_geo.y - accheight + HSPLITTERHEIGHT;
00377     }
00378 
00379     m_current_height = h;
00380     m_current_width = w;
00381     m_current_x = x;
00382     m_current_y = y;
00383 
00384     return eCompliantHeight | eCompliantWidth;
00385   }
00386 
00387   void HSplitter::ResetSplitConfig()
00388   {
00389 
00390     t_s32 x = GetBaseX();
00391     t_s32 y = GetBaseY();
00392     t_s32 w = GetBaseWidth();
00393     t_s32 h = GetBaseHeight();
00394     t_u32 num_element = (t_u32) m_InterfaceObject.size();
00395 
00396     if (num_element < 1)
00397     {
00398       return;
00399     }
00400 
00401     float max_stretch = 0.0f;
00402     float stretchfactor;
00403 
00404     for (t_u32 i = 0; i < (t_u32) m_SplitConfig.size(); i++)
00405     {
00406       stretchfactor = m_SplitConfig[i];
00407 
00408       if (max_stretch < stretchfactor)
00409       {
00410         max_stretch = stretchfactor;
00411       }
00412     }
00413 
00414     float total = 0;
00415 
00416     for (t_u32 i = 0; i < (t_u32) m_SplitConfig.size(); i++)
00417     {
00418       stretchfactor = m_SplitConfig[i];
00419       total += stretchfactor / max_stretch;
00420     }
00421 
00422     t_s32 availableheight = (h - num_element * HSPLITTERHEIGHT);
00423     float max_size = float (availableheight) / total;
00424 
00425     for (t_u32 i = 0; i < (t_u32) m_SplitConfig.size(); i++)
00426     {
00427       stretchfactor = m_SplitConfig[i];
00428       y += stretchfactor * max_size / max_stretch;
00429       Geometry geo (x, y, w, HSPLITTERHEIGHT);
00430       m_SplitterObject[i]->SetGeometry (geo);
00431     }
00432 
00433     m_SplitterObject[num_element-1]->SetBaseX (y + h - HSPLITTERHEIGHT);
00434 
00435     m_initial_config = true;
00436   }
00437 
00438   void HSplitter::OnSplitterMouseDown (t_s32 x, t_s32 y, unsigned long button_flags, unsigned long key_flags, t_s32 header_pos)
00439   {
00440     m_point = Point(x, y);
00441 
00442     m_focus_splitter_index = header_pos;
00443     GetWindowCompositor().SetWidgetDrawingOverlay (this, GetWindowCompositor ().GetProcessingTopView () );
00444 
00445 
00446     // Hint for the window to initiate a redraw
00447     GetWindowThread ()->RequestRedraw();
00448   }
00449 
00450   void HSplitter::OnSplitterMouseUp (t_s32 x, t_s32 y, unsigned long button_flags, unsigned long key_flags, t_s32 header_pos)
00451   {
00452     if (mvt_dy)
00453     {
00454       Geometry geo = m_SplitterObject[header_pos]->GetGeometry();
00455       geo.OffsetPosition (0, mvt_dy);
00456 
00457       t_u32 num_element = (t_u32) m_SplitterObject.size();
00458 
00459       if (header_pos < (t_s32) num_element - 1)
00460       {
00461         // Make the splitter bar stick to the next one if the distance between them is less than HSTICK_SIZE.
00462         if (m_SplitterObject[header_pos + 1]->GetGeometry().y - geo.y - HSPLITTERHEIGHT < HSTICK_SIZE)
00463           geo.SetY ( m_SplitterObject[header_pos + 1]->GetGeometry().y - HSPLITTERHEIGHT );
00464       }
00465 
00466       m_SplitterObject[header_pos]->SetGeometry (geo);
00467       ResizeSplitter (header_pos);
00468     }
00469 
00470     m_focus_splitter_index = -1;
00471     mvt_dx = 0;
00472     mvt_dy = 0;
00473 
00474     // End overlay drawing;
00475     GetWindowCompositor().SetWidgetDrawingOverlay (0, GetWindowCompositor().GetProcessingTopView() );
00476     // Hint for the window to initiate a redraw
00477     GetWindowThread ()->RequestRedraw();
00478   }
00479 
00480   void HSplitter::OnSplitterMouseDrag (t_s32 x, t_s32 y, t_s32 dx, t_s32 dy, unsigned long button_flags, unsigned long key_flags, t_s32 header_pos)
00481   {
00482     Geometry geo = m_SplitterObject[header_pos]->GetGeometry();
00483     t_s32 num_element = (t_s32) m_SplitterObject.size();
00484 
00485     if (header_pos == num_element - 1)
00486     {
00487       // The last splitter cannot be moved
00488       return;
00489     }
00490 
00491     mvt_dx = 0;
00492     mvt_dy = (y - m_point.y);
00493 
00494     if (m_ResizeOnSplitterRelease == false)
00495     {
00496       // Continuously redraw resize and redraw the 2 parts of the widget.
00497       // This is slow.
00498       geo.OffsetPosition (mvt_dx, mvt_dy);
00499       m_SplitterObject[header_pos]->SetGeometry (geo);
00500       ResizeSplitter (header_pos);
00501 
00502       mvt_dx = 0;
00503       mvt_dy = 0;
00504     }
00505 
00506     // Hint for the window to initiate a redraw
00507     GetWindowThread ()->RequestRedraw();
00508   }
00509 
00510   void HSplitter::ResizeSplitter (t_s32 header_pos)
00511   {
00512     Geometry geo = m_SplitterObject[header_pos]->GetGeometry();
00513     t_s32 num_element = (t_s32) m_SplitterObject.size();
00514 
00515     if ( (header_pos == 0) && (m_SplitterObject[header_pos]->GetBaseY() < GetBaseY() ) )
00516     {
00517       m_SplitterObject[header_pos]->SetBaseY (GetBaseY() );
00518     }
00519 
00520     if ( (header_pos == num_element - 1) && (m_SplitterObject[header_pos]->GetBaseY() > GetBaseY() + GetBaseHeight() - HSPLITTERHEIGHT) )
00521     {
00522       m_SplitterObject[header_pos]->SetBaseY (GetBaseY() + GetBaseHeight() - HSPLITTERHEIGHT);
00523     }
00524 
00525     if (header_pos < (t_s32) num_element - 1)
00526     {
00527       t_s32 posy0, posy1;
00528       posy0 = m_SplitterObject[header_pos]->GetBaseY();
00529       posy1 = m_SplitterObject[header_pos + 1]->GetBaseY();
00530 
00531       if (posy0 > posy1 - HSPLITTERHEIGHT)
00532       {
00533         posy0 = posy1 - HSPLITTERHEIGHT;
00534         m_SplitterObject[header_pos]->SetBaseY (posy0);
00535       }
00536     }
00537 
00538     if (0 < header_pos)
00539     {
00540       t_s32 posy0, posy1;
00541       posy0 = m_SplitterObject[header_pos]->GetBaseY();
00542       posy1 = m_SplitterObject[header_pos - 1]->GetBaseY();
00543 
00544       if (posy0 < posy1 + HSPLITTERHEIGHT)
00545       {
00546         posy0 = posy1 + HSPLITTERHEIGHT;
00547         m_SplitterObject[header_pos]->SetBaseY (posy0);
00548       }
00549     }
00550 
00551     ComputeChildLayout();
00552     QueueDraw();
00553   }
00554 
00555 // HSplitter need to re implement DoneRedraw because it does not
00556 // have a m_compositionlayout where its child are located;
00557   void HSplitter::DoneRedraw()
00558   {
00559     std::vector<Area *>::iterator it;
00560 
00561     for(it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++)
00562     {
00563       //(*it)->DoneRedraw();
00564       if((*it)->Type().IsDerivedFromType (View::StaticObjectType))
00565       {
00566         View *ic = static_cast<View *>(*it);
00567         ic->DoneRedraw();
00568       }
00569 
00570       else if((*it)->Type().IsObjectType (InputArea::StaticObjectType))
00571       {
00572         //InputArea* base_area = NUX_STATIC_CAST(InputArea*, (*it));
00573       }
00574     }
00575   }
00576 
00577   Area* HSplitter::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type)
00578   {
00579     bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
00580 
00581     if(mouse_inside == false)
00582       return NULL;
00583 
00584     std::vector<MySplitter*>::iterator splitter_it;
00585     for (splitter_it = m_SplitterObject.begin(); splitter_it != m_SplitterObject.end(); splitter_it++)
00586     {
00587       Area* found_area = (*splitter_it)->FindAreaUnderMouse(mouse_position, event_type);
00588       if(found_area)
00589         return found_area;
00590     }
00591 
00592     std::vector<Area *>::iterator it;
00593     for(it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++)
00594     {
00595       Area* found_area = (*it)->FindAreaUnderMouse(mouse_position, event_type);
00596 
00597       if(found_area)
00598         return found_area;
00599     }
00600 
00601     if((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent()))
00602       return NULL;
00603     return this;
00604   }
00605 
00606   bool HSplitter::AcceptKeyNavFocus()
00607   {
00608     return false;
00609   }
00610 
00611   Area* HSplitter::KeyNavIteration(KeyNavDirection direction)
00612   {
00613     if (m_InterfaceObject.size() == 0)
00614       return NULL;
00615 
00616     if (next_object_to_key_focus_area_)
00617     {
00618       if ((direction == KEY_NAV_LEFT) || (direction == KEY_NAV_RIGHT))
00619       {
00620         // Don't know what to do with this
00621         return NULL;
00622       }
00623       std::vector<Area*>::iterator it;
00624       std::vector<Area*>::iterator it_next;
00625       it = std::find (m_InterfaceObject.begin(), m_InterfaceObject.end(), next_object_to_key_focus_area_);
00626 
00627       if (it == m_InterfaceObject.end())
00628       {
00629         // Should never happen
00630         nuxAssert (0);
00631         return NULL;
00632       }
00633 
00634       it_next = it;
00635       ++it_next;
00636 
00637       if ((direction == KEY_NAV_UP) && (it == m_InterfaceObject.begin()))
00638       {
00639         // can't go further
00640         return NULL;
00641       }
00642 
00643       if ((direction == KEY_NAV_DOWN) && (it_next == m_InterfaceObject.end()))
00644       {
00645         // can't go further
00646         return NULL;
00647       }
00648 
00649       if ((direction == KEY_NAV_UP))
00650       {
00651         --it;
00652         Area* key_nav_focus = (*it)->KeyNavIteration(direction);
00653 
00654         while (key_nav_focus == NULL)
00655         {
00656           if (it == m_InterfaceObject.begin())
00657             break;
00658 
00659           --it;
00660           key_nav_focus = (*it)->KeyNavIteration(direction);
00661         }
00662 
00663         return key_nav_focus;
00664       }
00665 
00666       if ((direction == KEY_NAV_DOWN))
00667       {
00668         ++it;
00669         Area* key_nav_focus = (*it)->KeyNavIteration(direction);
00670 
00671         while (key_nav_focus == NULL)
00672         {
00673           ++it;
00674           if (it == m_InterfaceObject.end())
00675             break;
00676 
00677           key_nav_focus = (*it)->KeyNavIteration(direction);
00678         }
00679 
00680         return key_nav_focus;
00681       }
00682     }
00683     else
00684     {
00685       Area* key_nav_focus = NULL;
00686       if (direction == KEY_NAV_UP)
00687       {
00688         std::vector<Area*>::reverse_iterator it = m_InterfaceObject.rbegin();
00689         key_nav_focus = (*it)->KeyNavIteration(direction);
00690 
00691         while (key_nav_focus == NULL)
00692         {
00693           ++it;
00694           if (it == m_InterfaceObject.rend())
00695             break;
00696 
00697           key_nav_focus = (*it)->KeyNavIteration(direction);
00698         }
00699       }
00700       else
00701       {
00702         std::vector<Area*>::iterator it = m_InterfaceObject.begin();
00703         key_nav_focus = (*it)->KeyNavIteration(direction);
00704 
00705         while (key_nav_focus == NULL)
00706         {
00707           ++it;
00708           if (it == m_InterfaceObject.end())
00709             break;
00710 
00711           key_nav_focus = (*it)->KeyNavIteration(direction);
00712         }
00713       }
00714       return key_nav_focus;
00715     }
00716 
00717     return NULL;
00718   }
00719 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends