nux-1.14.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 "Layout.h" 00025 #include "View.h" 00026 00027 namespace nux 00028 { 00029 NUX_IMPLEMENT_OBJECT_TYPE(Layout); 00030 NUX_IMPLEMENT_OBJECT_TYPE(SpaceLayout); 00031 00032 Layout::Layout (NUX_FILE_LINE_DECL) 00033 : Area (NUX_FILE_LINE_PARAM) 00034 { 00035 m_h_in_margin = 0; 00036 m_h_out_margin = 0; 00037 m_v_in_margin = 0; 00038 m_v_out_margin = 0; 00039 m_contentWidth = 0; 00040 m_contentHeight = 0; 00041 m_ContentStacking = eStackExpand; 00042 _has_focus_control = false; 00043 _queued_draw = false; 00044 _ignore_focus = false; 00045 00046 SetMinimumSize(1, 1); 00047 } 00048 00049 Layout::~Layout() 00050 { 00051 // It is possible that this layout object is in the refresh list. Remove 00052 // it here before it is deleted. 00053 WindowThread* wt = GetWindowThread(); 00054 if (wt) 00055 wt->RemoveObjectFromLayoutQueue(this); 00056 00057 std::list<Area *>::iterator it; 00058 00059 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00060 { 00061 (*it)->UnParentObject(); 00062 } 00063 00064 _layout_element_list.clear(); 00065 } 00066 00067 00068 void Layout::RemoveChildObject (Area *bo) 00069 { 00070 std::list<Area *>::iterator it; 00071 it = std::find (_layout_element_list.begin(), _layout_element_list.end(), bo); 00072 00073 if (it != _layout_element_list.end()) 00074 { 00075 /* we need to emit the signal before the unparent, just in case 00076 one of the callbacks wanted to use this object */ 00077 ViewRemoved.emit (this, bo); 00078 bo->UnParentObject(); 00079 _layout_element_list.erase (it); 00080 } 00081 } 00082 00083 bool Layout::FindWidget (Area *WidgetObject) const 00084 { 00085 std::list<Area *>::const_iterator it; 00086 00087 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00088 { 00089 if ( (*it) == WidgetObject) 00090 { 00091 return true; 00092 } 00093 } 00094 00095 return false; 00096 } 00097 00098 bool Layout::IsEmpty() const 00099 { 00100 return (_layout_element_list.size() == 0); 00101 } 00102 00103 bool Layout::HasFocusableEntries () 00104 { 00105 std::list<Area *>::const_iterator it; 00106 00107 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00108 { 00109 bool can_focus = false; 00110 if ( (*it)->IsArea() ) 00111 { 00112 CoreArea *area = NUX_STATIC_CAST (CoreArea *, (*it) ); 00113 can_focus = area->CanFocus (); 00114 } 00115 else if ( (*it)->IsView() ) 00116 { 00117 View *ic = NUX_STATIC_CAST (View *, (*it) ); 00118 can_focus = ic->CanFocus (); 00119 } 00120 else if ( (*it)->IsLayout() ) 00121 { 00122 Layout *layout = NUX_STATIC_CAST (Layout *, (*it) ); 00123 can_focus = layout->CanFocus (); 00124 } 00125 00126 if (can_focus == true) 00127 return true; 00128 } 00129 00130 return false; 00131 } 00132 00133 void Layout::OnChildFocusChanged (/*Area *parent,*/ Area *child) 00134 { 00135 ChildFocusChanged.emit (/*parent,*/ child); 00136 } 00137 00138 // If(stretchfactor == 0): the WidgetLayout geometry will be set to SetGeometry(0,0,1,1); 00139 // and the children will take their natural size by expending WidgetLayout. 00140 // If the parent of WidgetLayout offers more space, it won't be used by WidgetLayout. 00141 void Layout::AddLayout (Layout *layout, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) 00142 { 00143 nuxAssertMsg (layout != 0, TEXT ("[Layout::AddView] Invalid parameter.") ); 00144 NUX_RETURN_IF_TRUE (layout == 0); 00145 // Should never happen 00146 nuxAssertMsg (layout != this, TEXT ("[Layout::AddLayout] Error: Trying to add a layout to itself.") ); 00147 NUX_RETURN_IF_FALSE (layout != 0); 00148 00149 Area *parent = layout->GetParentObject(); 00150 nuxAssertMsg (parent == 0, TEXT ("[Layout::AddLayout] Trying to add an object that already has a parent.") ); 00151 NUX_RETURN_IF_TRUE (parent != 0); 00152 00153 nuxAssertMsg (index >= 0, TEXT ("[Layout::AddLayout] Invalid index position. Adding at the beginning of the list..") ); 00154 00155 layout->SetStretchFactor (stretchFactor); 00156 layout->SetPositioning (minor_position); 00157 layout->SetExtend (minor_size); 00158 00159 if (percentage < 1.0f) 00160 { 00161 layout->SetPercentage (1.0f); 00162 } 00163 else if (percentage > 100.0f) 00164 { 00165 layout->SetPercentage (100.0f); 00166 } 00167 else 00168 { 00169 layout->SetPercentage (percentage); 00170 } 00171 00172 layout->SetParentObject (this); 00173 00174 layout->OnChildQueueDraw.connect (sigc::mem_fun (this, &Layout::ChildLayoutChildQueuedDraw)); 00175 layout->OnQueueDraw.connect (sigc::mem_fun (this, &Layout::ChildLayoutQueuedDraw)); 00176 00177 if (HasFocusControl () && HasFocusableEntries () == false) 00178 { 00179 //layout->SetFocused (true); 00180 //ChildFocusChanged (this, layout); 00181 } 00182 00183 if (index < 0) 00184 index = NUX_LAYOUT_BEGIN; 00185 00186 if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) 00187 { 00188 _layout_element_list.push_back (layout); 00189 } 00190 else 00191 { 00192 #if defined(NUX_OS_WINDOWS) && !defined(NUX_VISUAL_STUDIO_2010) 00193 std::list<Area *>::iterator pos = _layout_element_list.begin(); 00194 #else 00195 auto pos = _layout_element_list.begin(); 00196 #endif 00197 int idx = index; 00198 while (pos != _layout_element_list.end() && idx > 0) 00199 { 00200 idx--; 00201 pos++; 00202 } 00203 _layout_element_list.insert(pos, layout); 00204 } 00205 00206 _connection_map[layout] = layout->ChildFocusChanged.connect (sigc::mem_fun (this, &Layout::OnChildFocusChanged)); 00207 00208 //--->> Removed because it cause problem with The splitter widget: ComputeLayout2(); 00209 } 00210 00212 00236 void Layout::AddView (Area *bo, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) 00237 { 00238 nuxAssertMsg (bo != 0, TEXT ("[Layout::AddView] Invalid parameter.") ); 00239 NUX_RETURN_IF_TRUE (bo == 0); 00240 00241 Area *parent = bo->GetParentObject(); 00242 nuxAssertMsg (parent == 0, TEXT ("[Layout::AddView] Trying to add an object that already has a parent.") ); 00243 NUX_RETURN_IF_TRUE (parent != 0); 00244 00245 nuxAssertMsg (index >= 0, TEXT ("[Layout::AddView] Invalid index position. Adding at the beginning of the list..") ); 00246 00247 bo->SetStretchFactor (stretchFactor); 00248 bo->SetPositioning (minor_position); 00249 bo->SetExtend (minor_size); 00250 00251 if (percentage < 1.0f) 00252 { 00253 bo->SetPercentage (1.0f); 00254 } 00255 else if (percentage > 100.0f) 00256 { 00257 bo->SetPercentage (100.0f); 00258 } 00259 else 00260 { 00261 bo->SetPercentage (percentage); 00262 } 00263 00264 bo->SetParentObject (this); 00265 00266 if (bo->IsView ()) 00267 static_cast<View *> (bo)->OnQueueDraw.connect (sigc::mem_fun (this, &Layout::ChildViewQueuedDraw)); 00268 00269 //if (HasFocusControl () && HasFocusableEntries () == false) 00270 //{ 00271 //bo->SetFocused (true); 00272 //ChildFocusChanged (this, bo); 00273 //} 00274 00275 if (index < 0) 00276 index = NUX_LAYOUT_BEGIN; 00277 00278 if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) 00279 { 00280 _layout_element_list.push_back (bo); 00281 } 00282 else 00283 { 00284 #if defined(NUX_OS_WINDOWS) && !defined(NUX_VISUAL_STUDIO_2010) 00285 std::list<Area *>::iterator pos = _layout_element_list.begin(); 00286 #else 00287 auto pos = _layout_element_list.begin(); 00288 #endif 00289 int idx = index; 00290 while (pos != _layout_element_list.end() && idx > 0) 00291 { 00292 idx--; 00293 pos++; 00294 } 00295 _layout_element_list.insert(pos, bo); 00296 } 00297 00298 _connection_map[bo] = bo->ChildFocusChanged.connect (sigc::mem_fun (this, &Layout::OnChildFocusChanged)); 00299 00300 ViewAdded.emit (this, bo); 00301 //--->> Removed because it cause problem with The splitter widget: ComputeLayout2(); 00302 } 00303 00304 void Layout::AddSpace (unsigned int width, unsigned int stretchFactor, LayoutPosition index) 00305 { 00306 AddLayout (new SpaceLayout(), stretchFactor); 00307 } 00308 00309 void Layout::Clear() 00310 { 00311 std::list<Area *>::iterator it; 00312 00313 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00314 { 00315 (*it)->UnParentObject(); 00316 } 00317 00318 _layout_element_list.clear(); 00319 } 00320 00321 bool Layout::SearchInAllSubNodes (Area *bo) 00322 { 00323 std::list<Area *>::iterator it; 00324 00325 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00326 { 00327 if ( (*it) == bo) 00328 { 00329 return true; 00330 } 00331 else if ( (*it)->IsLayout() ) 00332 { 00333 Layout *layout = NUX_STATIC_CAST (Layout *, (*it) ); 00334 00335 if (layout->SearchInAllSubNodes (bo) ) 00336 { 00337 return true; 00338 } 00339 } 00340 } 00341 00342 return false; 00343 } 00344 00345 bool Layout::SearchInFirstSubNodes (Area *bo) 00346 { 00347 std::list<Area *>::iterator it; 00348 00349 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00350 { 00351 if ( (*it) == bo) 00352 { 00353 return true; 00354 } 00355 } 00356 00357 return false; 00358 } 00359 00360 unsigned int Layout::GetMaxStretchFactor() 00361 { 00362 unsigned int value = 0; 00363 unsigned int sf; 00364 std::list<Area *>::iterator it; 00365 00366 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00367 { 00368 sf = (*it)->GetStretchFactor(); 00369 00370 if (sf >= value) 00371 { 00372 value = sf; 00373 } 00374 } 00375 00376 return value; 00377 } 00378 00379 unsigned int Layout::GetMinStretchFactor() 00380 { 00381 unsigned int value = 0xFFFFFFFF; 00382 unsigned int sf; 00383 std::list<Area *>::iterator it; 00384 00385 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00386 { 00387 sf = (*it)->GetStretchFactor(); 00388 00389 if (sf <= value) 00390 { 00391 value = sf; 00392 } 00393 } 00394 00395 return value; 00396 } 00397 00398 unsigned int Layout::GetNumStretchFactor (unsigned int sf) 00399 { 00400 unsigned int count = 0; 00401 std::list<Area *>::iterator it; 00402 00403 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00404 { 00405 if ( (*it)->GetStretchFactor() == sf) 00406 { 00407 count++; 00408 } 00409 } 00410 00411 return count; 00412 } 00413 00414 void Layout::DoneRedraw() 00415 { 00416 std::list<Area *>::iterator it; 00417 00418 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00419 { 00420 if ( (*it)->IsView() ) 00421 { 00422 View *ic = NUX_STATIC_CAST (View *, (*it) ); 00423 ic->DoneRedraw(); 00424 } 00425 } 00426 } 00427 00428 void Layout::DoActivateFocus () 00429 { 00430 std::list<Area *>::const_iterator it; 00431 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00432 { 00433 if ((*it)->GetFocused ()) 00434 { 00435 (*it)->ActivateFocus (); 00436 break; 00437 } 00438 } 00439 } 00440 00441 bool Layout::FocusFirstChild () 00442 { 00443 if (_layout_element_list.empty ()) 00444 return false; 00445 00446 std::list<Area *>::const_iterator it; 00447 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00448 { 00449 if ((*it)->CanFocus ()) 00450 { 00451 (*it)->SetFocused (true); 00452 ChildFocusChanged (/*this,*/ (*it)); 00453 return true; 00454 } 00455 } 00456 00457 return false; 00458 } 00459 00460 bool Layout::FocusLastChild () 00461 { 00462 if (_layout_element_list.empty ()) 00463 return false; 00464 00465 std::list<Area *>::reverse_iterator it; 00466 for (it = _layout_element_list.rbegin(); it != _layout_element_list.rend(); it++) 00467 { 00468 if ((*it)->CanFocus ()) 00469 { 00470 (*it)->SetFocused (true); 00471 ChildFocusChanged (/*this,*/ (*it)); 00472 return true; 00473 } 00474 } 00475 00476 return false; 00477 } 00478 00479 00480 bool Layout::FocusNextChild (Area *child) 00481 { 00482 std::list<Area *>::const_iterator it; 00483 bool found_child = false; 00484 00485 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00486 { 00487 if (found_child) 00488 { 00489 if ((*it)->CanFocus ()) 00490 { 00491 (*it)->SetFocused (true); 00492 ChildFocusChanged (/*this,*/ (*it)); 00493 return true; 00494 } 00495 } 00496 00497 if ((*it) == child) 00498 { 00499 found_child = true; 00500 } 00501 } 00502 00503 return false; 00504 } 00505 00506 bool Layout::FocusPreviousChild (Area *child) 00507 { 00508 std::list<Area *>::reverse_iterator it; 00509 bool found_child = false; 00510 00511 for (it = _layout_element_list.rbegin(); it != _layout_element_list.rend(); it++) 00512 { 00513 00514 if (found_child) 00515 { 00516 if ((*it)->CanFocus ()) 00517 { 00518 (*it)->SetFocused (true); 00519 ChildFocusChanged (/*this,*/ (*it)); 00520 return true; 00521 } 00522 } 00523 00524 if ((*it) == child) 00525 { 00526 found_child = true; 00527 } 00528 } 00529 00530 return false; 00531 } 00532 00533 00534 void Layout::SetFocusControl (bool focus_control) 00535 { 00536 _has_focus_control = focus_control; 00537 } 00538 00539 bool Layout::HasFocusControl () 00540 { 00541 return _has_focus_control; 00542 } 00543 00544 00545 long Layout::SendEventToArea (Area *area, IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00546 { 00547 // if parent is null return, thats a valid usecase so no warnings. 00548 if (area == NULL) 00549 { 00550 return 0; 00551 } 00552 00553 long ret = 0; 00554 if ( area->IsView() ) 00555 { 00556 View *ic = NUX_STATIC_CAST (View *, area ); 00557 ret = ic->ProcessFocusEvent (ievent, ret, ProcessEventInfo); 00558 } 00559 else if ( area->IsLayout() ) 00560 { 00561 Layout *layout = NUX_STATIC_CAST (Layout *, area ); 00562 layout->SetFocusControl (true); 00563 SetFocusControl (false); 00564 ret = layout->ProcessFocusEvent (ievent, ret, ProcessEventInfo); 00565 } 00566 00567 return ret; 00568 } 00569 00570 Area* Layout::GetFocusedChild () 00571 { 00572 std::list<Area *>::iterator it; 00573 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00574 { 00575 if ((*it)->GetFocused ()) 00576 { 00577 return (*it); 00578 } 00579 } 00580 00581 return NULL; 00582 } 00583 00584 long Layout::DoFocusPrev (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00585 { 00586 Area *focused_child = GetFocusedChild (); 00587 if (focused_child == NULL) return ProcessEventInfo; 00588 bool success = FocusPreviousChild (focused_child); 00589 //focused_child->SetFocused (false); 00590 00591 if (success == false) 00592 { 00593 Area *parent = GetParentObject (); 00594 if (parent != NULL) 00595 return SendEventToArea (parent, ievent, TraverseInfo, ProcessEventInfo); 00596 else 00597 FocusFirstChild (); 00598 } 00599 00600 return ProcessEventInfo; 00601 } 00602 00603 long Layout::DoFocusNext (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00604 { 00605 Area *focused_child = GetFocusedChild (); 00606 if (focused_child == NULL) return ProcessEventInfo; 00607 bool success = FocusNextChild(focused_child); 00608 //focused_child->SetFocused (false); 00609 00610 if (success == false) 00611 { 00612 Area *parent = GetParentObject (); 00613 if (parent != NULL) 00614 return SendEventToArea (parent, ievent, TraverseInfo, ProcessEventInfo); 00615 else 00616 FocusFirstChild (); 00617 } 00618 00619 return ProcessEventInfo; 00620 } 00621 00622 long Layout::DoFocusUp (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00623 { 00624 return DoFocusPrev (ievent, TraverseInfo, ProcessEventInfo); 00625 } 00626 long Layout::DoFocusDown (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00627 { 00628 return DoFocusNext (ievent, TraverseInfo, ProcessEventInfo); 00629 } 00630 long Layout::DoFocusLeft (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00631 { 00632 return DoFocusPrev (ievent, TraverseInfo, ProcessEventInfo); 00633 } 00634 long Layout::DoFocusRight (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00635 { 00636 return DoFocusNext (ievent, TraverseInfo, ProcessEventInfo); 00637 } 00638 00639 00640 long Layout::ProcessFocusEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00641 { 00642 long ret = TraverseInfo; 00643 00644 00645 if (GetFocused () && (ievent.e_event == NUX_KEYDOWN)) 00646 { 00647 Area *focused_child = NULL; 00648 Area *parent = GetParentObject (); 00649 FocusDirection direction; 00650 FocusEventType type; 00651 00652 direction = FOCUS_DIRECTION_NONE; 00653 00654 type = Focusable::GetFocusableEventType (ievent.e_event, 00655 ievent.GetKeySym(), 00656 ievent.GetText(), 00657 &direction); 00658 00659 if ((type == FOCUS_EVENT_DIRECTION) && (direction != FOCUS_DIRECTION_NONE)) 00660 { 00661 focused_child = GetFocusedChild (); 00662 00663 /* if nothing is focused, focus the first child else send the event to the parent */ 00664 00665 if (focused_child == NULL) 00666 { 00667 bool have_focused_child = FocusFirstChild (); 00668 if (have_focused_child == false) 00669 { 00670 /* propagate up */ 00671 if ((parent != NULL) && parent->IsLayout ()) 00672 { 00673 ret |= SendEventToArea (parent, ievent, ret, ProcessEventInfo); 00674 } 00675 else 00676 { 00677 FocusFirstChild (); 00678 } 00679 } 00680 } 00681 else // we have a focused child 00682 { 00683 // if the focused child is the last/first handle next/prev for those 00684 if (direction == FOCUS_DIRECTION_PREV) 00685 { 00686 if (focused_child == _layout_element_list.front ()) 00687 { 00688 if (parent != NULL) 00689 { 00690 ret |= SendEventToArea (parent, ievent, ret, ProcessEventInfo); 00691 } 00692 else 00693 { 00694 FocusLastChild (); 00695 } 00696 return ret; 00697 } 00698 } 00699 else if (direction == FOCUS_DIRECTION_NEXT) 00700 { 00701 if (focused_child == _layout_element_list.back ()) 00702 { 00703 if (parent != NULL) 00704 { 00705 ret |= SendEventToArea (parent, ievent, ret, ProcessEventInfo); 00706 } 00707 else 00708 { 00709 FocusFirstChild (); 00710 } 00711 return ret; 00712 } 00713 } 00714 00715 switch (direction) 00716 { 00717 case FOCUS_DIRECTION_NEXT: 00718 ret |= DoFocusNext (ievent, ret, ProcessEventInfo); 00719 break; 00720 case FOCUS_DIRECTION_PREV: 00721 ret |= DoFocusPrev (ievent, ret, ProcessEventInfo); 00722 break; 00723 case FOCUS_DIRECTION_UP: 00724 ret |= DoFocusUp (ievent, ret, ProcessEventInfo); 00725 break; 00726 case FOCUS_DIRECTION_DOWN: 00727 ret |= DoFocusDown (ievent, ret, ProcessEventInfo); 00728 break; 00729 case FOCUS_DIRECTION_LEFT: 00730 ret |= DoFocusLeft (ievent, ret, ProcessEventInfo); 00731 break; 00732 case FOCUS_DIRECTION_RIGHT: 00733 ret |= DoFocusRight (ievent, ret, ProcessEventInfo); 00734 break; 00735 default: 00736 break; 00737 } 00738 00739 return ret; 00740 } 00741 } 00742 00743 if (type == FOCUS_EVENT_ACTIVATE) 00744 { 00745 ActivateFocus (); 00746 } 00747 } 00748 00749 return ret; 00750 } 00751 00752 Area* Layout::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) 00753 { 00754 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); 00755 00756 if(mouse_inside == false) 00757 return NULL; 00758 00759 std::list<Area *>::iterator it; 00760 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00761 { 00762 if ((*it)->IsVisible() && (*it)->IsSensitive()) 00763 { 00764 Area* hit_view = NUX_STATIC_CAST(Area*, (*it)->FindAreaUnderMouse(mouse_position, event_type)); 00765 if(hit_view) 00766 return hit_view; 00767 } 00768 } 00769 00770 return NULL; 00771 } 00772 00773 void Layout::ProcessDraw (GraphicsEngine &GfxContext, bool force_draw) 00774 { 00775 std::list<Area *>::iterator it; 00776 GfxContext.PushModelViewMatrix (Get2DMatrix ()); 00777 GfxContext.PushClippingRectangle (GetGeometry ()); 00778 00779 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00780 { 00781 if (!(*it)->IsVisible ()) 00782 continue; 00783 00784 if ((*it)->IsView ()) 00785 { 00786 View *ic = NUX_STATIC_CAST (View*, (*it)); 00787 ic->ProcessDraw (GfxContext, force_draw); 00788 } 00789 else if ((*it)->IsLayout ()) 00790 { 00791 Layout *layout = NUX_STATIC_CAST (Layout*, (*it)); 00792 layout->ProcessDraw (GfxContext, force_draw); 00793 } 00794 // InputArea should be tested last 00795 else if ((*it)->IsInputArea ()) 00796 { 00797 InputArea *input_area = NUX_STATIC_CAST (InputArea*, (*it)); 00798 input_area->OnDraw (GfxContext, force_draw); 00799 } 00800 } 00801 00802 GfxContext.PopClippingRectangle (); 00803 GfxContext.PopModelViewMatrix (); 00804 00805 //GfxContext.PopClipOffset (); 00806 00807 _queued_draw = false; 00808 } 00809 00810 void Layout::QueueDraw () 00811 { 00812 if (_queued_draw) 00813 { 00814 // A draw has already been scheduled. 00815 return; 00816 } 00817 00818 std::list<Area *>::iterator it; 00819 00820 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00821 { 00822 if ((*it)->IsView ()) 00823 { 00824 View *ic = NUX_STATIC_CAST (View *, (*it)); 00825 ic->QueueDraw (); 00826 } 00827 else if ((*it)->IsLayout ()) 00828 { 00829 Layout *layout = NUX_STATIC_CAST (Layout *, (*it)); 00830 layout->QueueDraw (); 00831 } 00832 } 00833 00834 _queued_draw = true; 00835 OnQueueDraw.emit (this); 00836 } 00837 00838 bool Layout::IsQueuedForDraw () 00839 { 00840 return _queued_draw; 00841 } 00842 00843 void Layout::SetContentDistribution (LayoutContentDistribution stacking) 00844 { 00845 m_ContentStacking = stacking; 00846 } 00847 00848 LayoutContentDistribution Layout::GetContentDistribution() 00849 { 00850 return m_ContentStacking; 00851 } 00852 00853 void Layout::RequestBottomUpLayoutComputation (Area *bo_initiator) 00854 { 00855 00856 } 00857 00858 void Layout::ChildViewQueuedDraw (View *view) 00859 { 00860 OnChildQueueDraw.emit (view); 00861 } 00862 00863 void Layout::ChildLayoutQueuedDraw (Layout *layout) 00864 { 00865 OnChildQueueDraw.emit (layout); 00866 } 00867 00868 void Layout::ChildLayoutChildQueuedDraw (Area *area) 00869 { 00870 OnChildQueueDraw.emit (area); 00871 } 00872 00873 /* Focusable Code */ 00874 bool Layout::DoGetFocused () 00875 { 00876 bool focused = false; 00877 00878 std::list<Area *>::iterator it; 00879 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00880 { 00881 if ((*it)->GetFocused ()) 00882 focused = true; 00883 } 00884 00885 return focused; 00886 } 00887 00888 void Layout::DoSetFocused (bool focused) 00889 { 00890 _is_focused = focused; 00891 if (focused == GetFocused ()) 00892 return; 00893 00894 if (focused == false) 00895 { 00896 std::list<Area *>::iterator it; 00897 00898 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00899 { 00900 if ((*it)->GetFocused ()) 00901 { 00902 if ( (*it)->IsArea() ) 00903 { 00904 CoreArea *area = NUX_STATIC_CAST (CoreArea *, (*it) ); 00905 area->SetFocused (false); 00906 } 00907 else if ( (*it)->IsView() ) 00908 { 00909 View *ic = NUX_STATIC_CAST (View *, (*it) ); 00910 ic->SetFocused (false); 00911 } 00912 else if ( (*it)->IsLayout() ) 00913 { 00914 Layout *layout = NUX_STATIC_CAST (Layout *, (*it) ); 00915 layout->SetFocused (false); 00916 } 00917 } 00918 00919 } 00920 } 00921 else 00922 { 00923 SetFocusControl (true); 00924 00925 if (GetFocused () == false) 00926 { 00927 FocusFirstChild (); 00928 _ignore_focus = true; 00929 } 00930 00931 // we need to chain up 00932 Area *_parent = GetParentObject(); 00933 if (_parent == NULL) 00934 { 00935 return; 00936 } 00937 00938 if (_parent->IsView ()) 00939 { 00940 View *parent = (View*)_parent; 00941 if (parent->GetFocused () == false && parent->HasPassiveFocus () == false) 00942 { 00943 parent->SetFocused (true); 00944 } 00945 parent->SetFocusControl (false); 00946 } 00947 else if (_parent->IsLayout ()) 00948 { 00949 Layout *parent = (Layout *)_parent; 00950 parent->SetFocusControl (false); 00951 } 00952 00953 } 00954 } 00955 00956 bool Layout::DoCanFocus () 00957 { 00958 std::list<Area *>::iterator it; 00959 if (_layout_element_list.empty ()) 00960 return false; 00961 00962 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) 00963 { 00964 bool can_focus = false; 00965 if ( (*it)->IsArea() ) 00966 { 00967 CoreArea *area = NUX_STATIC_CAST (CoreArea *, (*it) ); 00968 can_focus = area->CanFocus (); 00969 } 00970 else if ( (*it)->IsView() ) 00971 { 00972 View *ic = NUX_STATIC_CAST (View *, (*it) ); 00973 can_focus = ic->CanFocus (); 00974 } 00975 else if ( (*it)->IsLayout() ) 00976 { 00977 Layout *layout = NUX_STATIC_CAST (Layout *, (*it) ); 00978 can_focus = layout->CanFocus (); 00979 } 00980 00981 if (can_focus == true) 00982 return true; 00983 } 00984 00985 return false; 00986 } 00987 00988 bool Layout::AcceptKeyNavFocus() 00989 { 00990 return false; 00991 } 00992 }