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 "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 }