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