00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_containerwidget.hpp"
00012
00013 #include "xrb_gui_events.hpp"
00014 #include "xrb_input_events.hpp"
00015 #include "xrb_screen.hpp"
00016
00017 namespace Xrb
00018 {
00019
00020
00021
00022
00023
00024 ContainerWidget::ContainerWidget (ContainerWidget *const parent, std::string const &name)
00025 :
00026 Widget(parent, name)
00027 {
00028
00029
00030 m_accepts_focus = false;
00031 m_children_get_input_events_first = false;
00032 m_focus = NULL;
00033 m_focus_has_mouse_grab = false;
00034 m_mouseover_focus = NULL;
00035 m_main_widget = NULL;
00036 m_child_resize_blocker_count = 0;
00037 m_child_resize_was_blocked = false;
00038 }
00039
00040 ContainerWidget::~ContainerWidget ()
00041 {
00042
00043
00044 ASSERT1(m_child_resize_blocker_count == 0 && "you must not delete a ChildResizeBlocker'ed ContainerWidget");
00045
00046
00047 DeleteAllChildren();
00048
00049
00050 m_focus = NULL;
00051 m_mouseover_focus = NULL;
00052 m_main_widget = NULL;
00053 }
00054
00055
00056
00057
00058
00059 ScreenCoordVector2 ContainerWidget::AdjustedSize (ScreenCoordVector2 const &size) const
00060 {
00061 ScreenCoordRect rect(size);
00062 if (m_main_widget != NULL)
00063 {
00064 m_main_widget->AdjustFromMinSize(&rect);
00065 m_main_widget->AdjustFromMaxSize(&rect);
00066 }
00067 else
00068 {
00069 AdjustFromMinSize(&rect);
00070 AdjustFromMaxSize(&rect);
00071 }
00072 return rect.Size();
00073 }
00074
00075
00076
00077
00078
00079 void ContainerWidget::SetSizePropertyEnabled (
00080 SizeProperties::Property const property,
00081 Uint32 const component,
00082 bool const value,
00083 bool const defer_parent_update)
00084 {
00085
00086 ASSERT1(component <= 1);
00087 if (property == SizeProperties::MIN)
00088 m_preferred_size_properties.m_min_size_enabled[component] = value;
00089 else
00090 m_preferred_size_properties.m_max_size_enabled[component] = value;
00091
00092
00093 if (m_main_widget != NULL)
00094 {
00095 if (ChildResizeBlockerCount() == 0)
00096 m_main_widget->SetSizePropertyEnabled(
00097 property,
00098 component,
00099 value,
00100 defer_parent_update);
00101 else
00102 IndicateChildResizeWasBlocked();
00103 }
00104 else
00105 {
00106 if (property == SizeProperties::MIN)
00107 {
00108 if (m_size_properties.m_min_size_enabled[component] != value)
00109 {
00110 m_size_properties.m_min_size_enabled[component] = value;
00111 MinSizeUpdated();
00112 if (AdjustFromMinSize(&m_screen_rect))
00113 Resize(m_screen_rect.Size());
00114 ParentChildSizePropertiesUpdate(defer_parent_update);
00115 }
00116 }
00117 else
00118 {
00119 if (m_size_properties.m_max_size_enabled[component] != value)
00120 {
00121 m_size_properties.m_max_size_enabled[component] = value;
00122 MaxSizeUpdated();
00123 if (AdjustFromMaxSize(&m_screen_rect))
00124 Resize(m_screen_rect.Size());
00125 ParentChildSizePropertiesUpdate(defer_parent_update);
00126 }
00127 }
00128 }
00129 }
00130
00131 void ContainerWidget::SetSizePropertyEnabled (
00132 SizeProperties::Property const property,
00133 Bool2 const &value,
00134 bool const defer_parent_update)
00135 {
00136
00137 if (property == SizeProperties::MIN)
00138 m_preferred_size_properties.m_min_size_enabled = value;
00139 else
00140 m_preferred_size_properties.m_max_size_enabled = value;
00141
00142
00143 if (m_main_widget != NULL)
00144 {
00145 if (ChildResizeBlockerCount() == 0)
00146 m_main_widget->SetSizePropertyEnabled(
00147 property,
00148 value,
00149 defer_parent_update);
00150 else
00151 IndicateChildResizeWasBlocked();
00152 }
00153 else
00154 {
00155 if (property == SizeProperties::MIN)
00156 {
00157 if (m_size_properties.m_min_size_enabled != value)
00158 {
00159 m_size_properties.m_min_size_enabled = value;
00160 MinSizeUpdated();
00161 if (AdjustFromMinSize(&m_screen_rect))
00162 Resize(m_screen_rect.Size());
00163 ParentChildSizePropertiesUpdate(defer_parent_update);
00164 }
00165 }
00166 else
00167 {
00168 if (m_size_properties.m_max_size_enabled != value)
00169 {
00170 m_size_properties.m_max_size_enabled = value;
00171 MaxSizeUpdated();
00172 if (AdjustFromMaxSize(&m_screen_rect))
00173 Resize(m_screen_rect.Size());
00174 ParentChildSizePropertiesUpdate(defer_parent_update);
00175 }
00176 }
00177 }
00178 }
00179
00180 void ContainerWidget::SetSizeProperty (
00181 SizeProperties::Property const property,
00182 Uint32 const component,
00183 ScreenCoord const value,
00184 bool const defer_parent_update)
00185 {
00186
00187 ASSERT1(component <= 1);
00188 ASSERT1(value >= 0);
00189 if (property == SizeProperties::MIN)
00190 m_preferred_size_properties.m_min_size[component] = value;
00191 else
00192 m_preferred_size_properties.m_max_size[component] = value;
00193
00194
00195 if (m_main_widget != NULL)
00196 {
00197 if (ChildResizeBlockerCount() == 0)
00198 m_main_widget->SetSizeProperty(
00199 property,
00200 component,
00201 value,
00202 defer_parent_update);
00203 else
00204 IndicateChildResizeWasBlocked();
00205 }
00206 else
00207 {
00208 ASSERT1(component <= 1);
00209 if (property == SizeProperties::MIN)
00210 {
00211 if (m_size_properties.m_min_size[component] != value)
00212 {
00213 m_size_properties.m_min_size[component] = value;
00214 MinSizeUpdated();
00215 if (AdjustFromMinSize(&m_screen_rect))
00216 Resize(m_screen_rect.Size());
00217 ParentChildSizePropertiesUpdate(defer_parent_update);
00218 }
00219 }
00220 else
00221 {
00222 if (m_size_properties.m_max_size[component] != value)
00223 {
00224 m_size_properties.m_max_size[component] = value;
00225 MaxSizeUpdated();
00226 if (AdjustFromMaxSize(&m_screen_rect))
00227 Resize(m_screen_rect.Size());
00228 ParentChildSizePropertiesUpdate(defer_parent_update);
00229 }
00230 }
00231 }
00232 }
00233
00234 void ContainerWidget::SetSizeProperty (
00235 SizeProperties::Property const property,
00236 ScreenCoordVector2 const &value,
00237 bool const defer_parent_update)
00238 {
00239
00240 ASSERT1(value[Dim::X] >= 0);
00241 ASSERT1(value[Dim::Y] >= 0);
00242 if (property == SizeProperties::MIN)
00243 m_preferred_size_properties.m_min_size = value;
00244 else
00245 m_preferred_size_properties.m_max_size = value;
00246
00247
00248 if (m_main_widget != NULL)
00249 {
00250 if (ChildResizeBlockerCount() == 0)
00251 m_main_widget->SetSizeProperty(
00252 property,
00253 value,
00254 defer_parent_update);
00255 else
00256 IndicateChildResizeWasBlocked();
00257 }
00258 else
00259 {
00260 if (property == SizeProperties::MIN)
00261 {
00262 if (m_size_properties.m_min_size != value)
00263 {
00264 m_size_properties.m_min_size = value;
00265 MinSizeUpdated();
00266 if (AdjustFromMinSize(&m_screen_rect))
00267 Resize(m_screen_rect.Size());
00268 ParentChildSizePropertiesUpdate(defer_parent_update);
00269 }
00270 }
00271 else
00272 {
00273 if (m_size_properties.m_max_size != value)
00274 {
00275 m_size_properties.m_max_size = value;
00276 MaxSizeUpdated();
00277 if (AdjustFromMaxSize(&m_screen_rect))
00278 Resize(m_screen_rect.Size());
00279 ParentChildSizePropertiesUpdate(defer_parent_update);
00280 }
00281 }
00282 }
00283 }
00284
00285 void ContainerWidget::SetMainWidget (Widget *const main_widget)
00286 {
00287 m_main_widget = main_widget;
00288 if (m_main_widget != NULL)
00289 {
00290 ASSERT0(!m_main_widget->IsModal() && "You can't use a modal widget as a main widget");
00291 ASSERT1(m_main_widget->Parent() == this);
00292 m_main_widget->Resize(Size());
00293 m_main_widget->MoveTo(Position());
00294 ParentChildSizePropertiesUpdate(false);
00295 }
00296 }
00297
00298
00299
00300
00301
00302 void ContainerWidget::Draw (RenderContext const &render_context) const
00303 {
00304
00305 Widget::Draw(render_context);
00306
00307 Float const disabled_widget_alpha_mask = 0.5f;
00308
00309 RenderContext child_render_context(render_context);
00310
00311 for (WidgetVector::const_iterator it = m_child_vector.begin(),
00312 it_end = m_child_vector.end();
00313 it != it_end;
00314 ++it)
00315 {
00316 Widget *child = *it;
00317 ASSERT1(child != NULL);
00318
00319
00320
00321 if (!child->IsHidden() && !child->IsModal())
00322 {
00323
00324
00325 child_render_context.SetClipRect(
00326 render_context.ClippedRect(child->ScreenRect()));
00327
00328
00329 if (child_render_context.ClipRect().IsValid())
00330 {
00331
00332 child_render_context.ColorBias() = render_context.ColorBias();
00333 child_render_context.ApplyColorBias(child->ColorBias());
00334 child_render_context.ColorMask() = render_context.ColorMask();
00335 child_render_context.ApplyColorMask(child->ColorMask());
00336
00337
00338 if (!child->IsEnabled() && IsEnabled())
00339 child_render_context.ApplyAlphaMaskToColorMask(disabled_widget_alpha_mask);
00340
00341 child_render_context.SetupGLClipRect();
00342
00343 child->Draw(child_render_context);
00344 }
00345 }
00346 }
00347
00348
00349 if (!m_modal_widget_stack.empty())
00350 {
00351 ASSERT1(IsTopLevelParent());
00352
00353
00354 for (WidgetList::const_iterator it = m_modal_widget_stack.begin(),
00355 it_end = m_modal_widget_stack.end();
00356 it != it_end;
00357 ++it)
00358 {
00359 Widget *modal_widget = *it;
00360 ASSERT1(modal_widget != NULL);
00361
00362
00363 if (modal_widget->IsHidden())
00364 continue;
00365
00366
00367
00368 child_render_context.SetClipRect(
00369 render_context.ClippedRect(modal_widget->ScreenRect()));
00370
00371
00372 if (child_render_context.ClipRect().IsValid())
00373 {
00374
00375 child_render_context.ColorBias() = render_context.ColorBias();
00376 child_render_context.ApplyColorBias(modal_widget->ColorBias());
00377 child_render_context.ColorMask() = render_context.ColorMask();
00378 child_render_context.ApplyColorMask(modal_widget->ColorMask());
00379
00380 ASSERT1(modal_widget->IsEnabled());
00381
00382 child_render_context.SetupGLClipRect();
00383
00384 modal_widget->Draw(child_render_context);
00385 }
00386 }
00387 }
00388
00389
00390
00391
00392 render_context.SetupGLClipRect();
00393 }
00394
00395 void ContainerWidget::MoveBy (ScreenCoordVector2 const &delta)
00396 {
00397
00398 Widget::MoveBy(delta);
00399
00400
00401 for (WidgetVector::iterator it = m_child_vector.begin(),
00402 it_end = m_child_vector.end();
00403 it != it_end;
00404 ++it)
00405 {
00406 Widget *child = *it;
00407 ASSERT1(child != NULL);
00408 child->MoveBy(delta);
00409 }
00410 }
00411
00412 ScreenCoordVector2 ContainerWidget::Resize (ScreenCoordVector2 const &size)
00413 {
00414 ScreenCoordVector2 adjusted_size(m_size_properties.AdjustedSize(size));
00415
00416 if (m_screen_rect.Size() != adjusted_size || (ChildResizeBlockerCount() == 0 && ChildResizeWasBlocked()))
00417 {
00418 m_screen_rect.SetSize(adjusted_size);
00419
00420
00421 if (ChildResizeBlockerCount() == 0)
00422 {
00423 m_child_resize_was_blocked = false;
00424
00425 if (m_main_widget != NULL)
00426 m_main_widget->Resize(m_screen_rect.Size());
00427 }
00428 else
00429 IndicateChildResizeWasBlocked();
00430
00431
00432 SizeRangeAdjustment(&m_screen_rect);
00433
00434 ParentChildSizePropertiesUpdate(false);
00435 }
00436
00437
00438 return m_screen_rect.Size();
00439 }
00440
00441 void ContainerWidget::AttachChild (Widget *const child)
00442 {
00443 ASSERT1(child != NULL);
00444 ASSERT1(child->m_parent == NULL);
00445
00446
00447
00448 WidgetVector::iterator it;
00449 WidgetVector::iterator it_end;
00450 for (it = m_child_vector.begin(),
00451 it_end = m_child_vector.end();
00452 it != it_end;
00453 ++it)
00454 {
00455 Widget *widget = *it;
00456 ASSERT1(widget != NULL);
00457 if (widget->GetStackPriority() > child->GetStackPriority())
00458 break;
00459 }
00460
00461 m_child_vector.insert(it, child);
00462
00463 child->m_parent = this;
00464
00465
00466 child->m_widget_skin = m_widget_skin;
00467
00468 ASSERT1(dynamic_cast<Screen *>(TopLevelParent()) != NULL);
00469 }
00470
00471 void ContainerWidget::DetachChild (Widget *const child)
00472 {
00473 ASSERT1(child != NULL);
00474 ASSERT1(child->Parent() == this);
00475
00476 WidgetVector::iterator it = FindChildWidget(child);
00477 ASSERT1(it != m_child_vector.end() && *it == child && "not a child of this widget");
00478
00479 child->Unfocus();
00480
00481 child->MouseoverOff();
00482
00483 if (m_main_widget == child)
00484 m_main_widget = NULL;
00485
00486 m_child_vector.erase(it);
00487
00488 child->m_parent = NULL;
00489 }
00490
00491 void ContainerWidget::MoveChildDown (Widget *const child)
00492 {
00493
00494 WidgetVector::iterator it = FindChildWidget(child);
00495 WidgetVector::iterator it_end = m_child_vector.end();
00496 ASSERT1((*it)->Parent() == this && it != it_end && "not a child of this widget");
00497 if (it != m_child_vector.begin())
00498 {
00499
00500 WidgetVector::iterator prev = it;
00501 --prev;
00502
00503
00504 if (child->GetStackPriority() == (*prev)->GetStackPriority())
00505 {
00506 Widget *temp = *it;
00507 *it = *prev;
00508 *prev = temp;
00509 }
00510 }
00511 }
00512
00513 void ContainerWidget::MoveChildUp (Widget *const child)
00514 {
00515
00516 WidgetVector::iterator it = FindChildWidget(child);
00517 WidgetVector::iterator it_end = m_child_vector.end();
00518 ASSERT1((*it)->Parent() == this && it != it_end && "not a child of this widget");
00519
00520 WidgetVector::iterator next = it;
00521 ++next;
00522
00523
00524 if (next != it_end &&
00525 child->GetStackPriority() == (*next)->GetStackPriority())
00526 {
00527 Widget *temp = *it;
00528 *it = *next;
00529 *next = temp;
00530 }
00531 }
00532
00533 void ContainerWidget::MoveChildToBottom (Widget *const child)
00534 {
00535
00536 WidgetVector::iterator it_begin = m_child_vector.begin();
00537 WidgetVector::iterator it = FindChildWidget(child);
00538 WidgetVector::iterator it_end = m_child_vector.end();
00539 ASSERT1((*it)->Parent() == this && it != it_end && "not a child of this widget");
00540
00541
00542 WidgetVector::iterator dest_it = it;
00543 while (dest_it != it_begin &&
00544 (*dest_it)->GetStackPriority() == child->GetStackPriority())
00545 {
00546 --dest_it;
00547 }
00548
00549 if ((*dest_it)->GetStackPriority() != child->GetStackPriority())
00550 ++dest_it;
00551
00552
00553 if (it != dest_it)
00554 {
00555
00556 m_child_vector.erase(it);
00557
00558 m_child_vector.insert(dest_it, child);
00559 }
00560 }
00561
00562 void ContainerWidget::MoveChildToTop (Widget *const child)
00563 {
00564
00565 WidgetVector::iterator it = FindChildWidget(child);
00566 WidgetVector::iterator it_end = m_child_vector.end();
00567 ASSERT1((*it)->Parent() == this && it != it_end && "not a child of this widget");
00568
00569
00570 WidgetVector::iterator dest_it = it;
00571 while (dest_it != it_end &&
00572 (*dest_it)->GetStackPriority() == child->GetStackPriority())
00573 {
00574 ++dest_it;
00575 }
00576
00577
00578 if (it != dest_it)
00579 {
00580
00581 m_child_vector.insert(dest_it, child);
00582
00583
00584
00585
00586 it = FindChildWidget(child);
00587
00588 m_child_vector.erase(it);
00589 }
00590 }
00591
00592 void ContainerWidget::DeleteAllChildren ()
00593 {
00594
00595 while (m_child_vector.size() > 0)
00596 {
00597 Widget *child = m_child_vector.back();
00598 ASSERT1(child != NULL);
00599
00600
00601 Delete(child);
00602 }
00603
00604
00605 m_modal_widget_stack.clear();
00606 }
00607
00608
00609
00610
00611
00612 Uint32 ContainerWidget::WidgetSkinHandlerChildCount () const
00613 {
00614 return m_child_vector.size();
00615 }
00616
00617 WidgetSkinHandler *ContainerWidget::WidgetSkinHandlerChild (Uint32 const index)
00618 {
00619 ASSERT1(index < m_child_vector.size());
00620 Widget *child = m_child_vector[index];
00621 ASSERT1(child != NULL);
00622 return static_cast<WidgetSkinHandler *>(child);
00623 }
00624
00625 Bool2 ContainerWidget::ContentsMinSizeEnabled () const
00626 {
00627 ASSERT1(m_main_widget != NULL);
00628 return m_main_widget->MinSizeEnabled();
00629 }
00630
00631 ScreenCoordVector2 ContainerWidget::ContentsMinSize () const
00632 {
00633 ASSERT1(m_main_widget != NULL);
00634 return m_main_widget->MinSize();
00635 }
00636
00637 Bool2 ContainerWidget::ContentsMaxSizeEnabled () const
00638 {
00639 ASSERT1(m_main_widget != NULL);
00640 return m_main_widget->MaxSizeEnabled();
00641 }
00642
00643 ScreenCoordVector2 ContainerWidget::ContentsMaxSize () const
00644 {
00645 ASSERT1(m_main_widget != NULL);
00646 return m_main_widget->MaxSize();
00647 }
00648
00649 void ContainerWidget::HandleFrame ()
00650 {
00651
00652 for (WidgetVector::iterator it = m_child_vector.begin(),
00653 it_end = m_child_vector.end();
00654 it != it_end;
00655 ++it)
00656 {
00657 Widget *child = *it;
00658 ASSERT1(child != NULL);
00659 child->ProcessFrame(FrameTime());
00660 }
00661 }
00662
00663 bool ContainerWidget::ProcessDeleteChildWidgetEvent (EventDeleteChildWidget const *const e)
00664 {
00665 ASSERT1(e->ChildToDelete() != this && "a widget must not delete itself");
00666 e->DeleteChildWidget();
00667 return true;
00668 }
00669
00670 void ContainerWidget::AddModalWidget (Widget *const modal_widget)
00671 {
00672 ASSERT1(modal_widget != NULL);
00673 ASSERT1(modal_widget->IsModal());
00674 ASSERT1(modal_widget->IsEnabled());
00675 ASSERT1(!modal_widget->IsTopLevelParent());
00676
00677
00678
00679 if (IsTopLevelParent())
00680 {
00681
00682
00683 MouseoverOffWidgetLine();
00684
00685 modal_widget->Focus();
00686
00687 m_modal_widget_stack.push_back(modal_widget);
00688 }
00689 else
00690 {
00691
00692 Parent()->AddModalWidget(modal_widget);
00693 }
00694 }
00695
00696 void ContainerWidget::RemoveModalWidget (Widget *const modal_widget)
00697 {
00698 ASSERT1(modal_widget != NULL);
00699 ASSERT1(modal_widget->IsModal());
00700 ASSERT1(modal_widget->IsEnabled());
00701
00702
00703
00704 if (IsTopLevelParent())
00705 {
00706 modal_widget->Unfocus();
00707 WidgetList::iterator it = std::find(m_modal_widget_stack.begin(), m_modal_widget_stack.end(), modal_widget);
00708 ASSERT1(it != m_modal_widget_stack.end());
00709 m_modal_widget_stack.erase(it);
00710 }
00711 else
00712 Parent()->RemoveModalWidget(modal_widget);
00713 }
00714
00715 void ContainerWidget::CalculateMinAndMaxSizePropertiesFromContents ()
00716 {
00717
00718 for (Uint8 d = 0; d < 2; ++d)
00719 {
00720 {
00721 bool contents_min_size_enabled = ContentsMinSizeEnabled()[d];
00722
00723 m_size_properties.m_min_size_enabled[d] =
00724 contents_min_size_enabled ||
00725 m_preferred_size_properties.m_min_size_enabled[d];
00726
00727 if (contents_min_size_enabled)
00728 {
00729 if (m_preferred_size_properties.m_min_size_enabled[d])
00730 m_size_properties.m_min_size[d] =
00731 Max(ContentsMinSize()[d],
00732 m_preferred_size_properties.m_min_size[d]);
00733 else
00734 m_size_properties.m_min_size[d] = ContentsMinSize()[d];
00735 }
00736 else
00737 {
00738 if (m_preferred_size_properties.m_min_size_enabled[d])
00739 m_size_properties.m_min_size[d] =
00740 m_preferred_size_properties.m_min_size[d];
00741 else
00742 m_size_properties.m_min_size[d] =
00743 SizeProperties::DefaultMinSizeComponent();
00744 }
00745 }
00746
00747 {
00748 bool contents_max_size_enabled = ContentsMaxSizeEnabled()[d];
00749
00750 m_size_properties.m_max_size_enabled[d] =
00751 contents_max_size_enabled ||
00752 m_preferred_size_properties.m_max_size_enabled[d];
00753
00754 if (contents_max_size_enabled)
00755 {
00756 if (m_preferred_size_properties.m_max_size_enabled[d])
00757 m_size_properties.m_max_size[d] =
00758 Min(ContentsMaxSize()[d],
00759 m_preferred_size_properties.m_max_size[d]);
00760 else
00761 m_size_properties.m_max_size[d] = ContentsMaxSize()[d];
00762 }
00763 else
00764 {
00765 if (m_preferred_size_properties.m_max_size_enabled[d])
00766 m_size_properties.m_max_size[d] =
00767 m_preferred_size_properties.m_max_size[d];
00768 else
00769 m_size_properties.m_max_size[d] =
00770 SizeProperties::DefaultMaxSizeComponent();
00771 }
00772 }
00773 }
00774
00775 MinSizeUpdated();
00776 ParentChildSizePropertiesUpdate(false);
00777 }
00778
00779 void ContainerWidget::ChildSizePropertiesChanged (Widget *const child)
00780 {
00781 ASSERT1(child != NULL);
00782 ASSERT1(child->Parent() == this);
00783
00784 if (child == m_main_widget)
00785 {
00786 if (ChildResizeBlockerCount() == 0)
00787 {
00788
00789 CalculateMinAndMaxSizePropertiesFromContents();
00790
00791 Resize(m_main_widget->Size());
00792 }
00793 else
00794 IndicateChildResizeWasBlocked();
00795 }
00796 }
00797
00798 void ContainerWidget::ChildStackPriorityChanged (
00799 Widget *const child,
00800 StackPriority const previous_stack_priority)
00801 {
00802 ASSERT1(child != NULL);
00803 ASSERT1(child->Parent() == this);
00804 ASSERT1(child->GetStackPriority() != previous_stack_priority);
00805
00806 WidgetVector::iterator it_begin = m_child_vector.begin();
00807 WidgetVector::iterator it = FindChildWidget(child);
00808 WidgetVector::iterator it_end = m_child_vector.end();
00809 WidgetVector::iterator dest_it = it;
00810
00811
00812 if (it == it_end)
00813 ASSERT1(false && "Given child is somehow not in the child vector");
00814
00815
00816 if (child->GetStackPriority() < previous_stack_priority)
00817 {
00818
00819
00820
00821 while (dest_it != it_begin &&
00822 (*dest_it)->GetStackPriority() > child->GetStackPriority())
00823 {
00824 --dest_it;
00825 }
00826
00827 if ((*dest_it)->GetStackPriority() <= child->GetStackPriority())
00828 ++dest_it;
00829
00830
00831 if (dest_it != it)
00832 {
00833
00834 m_child_vector.erase(it);
00835
00836 m_child_vector.insert(dest_it, child);
00837 }
00838 }
00839 else
00840 {
00841
00842
00843
00844 while (dest_it != it_end &&
00845 (*dest_it)->GetStackPriority() < child->GetStackPriority())
00846 {
00847 ++dest_it;
00848 }
00849
00850
00851 if (dest_it != it)
00852 {
00853
00854 m_child_vector.insert(dest_it, child);
00855
00856
00857
00858
00859 it = FindChildWidget(child);
00860
00861 m_child_vector.erase(it);
00862 }
00863 }
00864 }
00865
00866
00867
00868
00869
00870 ContainerWidget::WidgetVector::iterator ContainerWidget::FindChildWidget (Widget const *const child)
00871 {
00872 WidgetVector::iterator it;
00873 WidgetVector::iterator it_end;
00874 for (it = m_child_vector.begin(),
00875 it_end = m_child_vector.end();
00876 it != it_end;
00877 ++it)
00878 {
00879 if (*it == child)
00880 break;
00881 }
00882 return it;
00883 }
00884
00885 bool ContainerWidget::InternalProcessKeyEvent (EventKey const *const e)
00886 {
00887 ASSERT1(e != NULL);
00888
00889 if (m_children_get_input_events_first)
00890 {
00891 if (m_focus != NULL)
00892 return m_focus->ProcessEvent(e);
00893 else
00894 return ProcessKeyEvent(DStaticCast<EventKey const *>(e));
00895 }
00896 else
00897 {
00898 if (ProcessKeyEvent(DStaticCast<EventKey const *>(e)))
00899 return true;
00900 else if (m_focus != NULL)
00901 return m_focus->ProcessEvent(e);
00902 else
00903 return false;
00904 }
00905 }
00906
00907 bool ContainerWidget::InternalProcessMouseEvent (EventMouse const *const e)
00908 {
00909 ASSERT1(e != NULL);
00910
00911 if (m_children_get_input_events_first)
00912 {
00913 if (m_focus != NULL && m_focus_has_mouse_grab)
00914 return m_focus->ProcessEvent(e);
00915 else if (SendMouseEventToChild(DStaticCast<EventMouse const *>(e)))
00916 return true;
00917 else
00918 return Widget::InternalProcessMouseEvent(e);
00919 }
00920 else
00921 {
00922 if (m_focus != NULL && m_focus_has_mouse_grab)
00923 return m_focus->ProcessEvent(e);
00924 else if (Widget::InternalProcessMouseEvent(e))
00925 return true;
00926 else
00927 return SendMouseEventToChild(DStaticCast<EventMouse const *>(e));
00928 }
00929 }
00930
00931 bool ContainerWidget::InternalProcessJoyEvent (EventJoy const *const e)
00932 {
00933 ASSERT1(e != NULL);
00934
00935 if (m_children_get_input_events_first)
00936 {
00937 if (m_focus != NULL)
00938 return m_focus->ProcessEvent(e);
00939 else if (ProcessJoyEvent(DStaticCast<EventJoy const *>(e)))
00940 return true;
00941 }
00942 else
00943 {
00944 if (ProcessJoyEvent(DStaticCast<EventJoy const *>(e)))
00945 return true;
00946 else if (m_focus != NULL)
00947 return m_focus->ProcessEvent(e);
00948 }
00949
00950 return false;
00951 }
00952
00953 bool ContainerWidget::InternalProcessFocusEvent (EventFocus const *const e)
00954 {
00955
00956 if (IsHidden())
00957 return false;
00958
00959
00960
00961 if (!m_accepts_focus && m_child_vector.size() == 0)
00962 return false;
00963
00964
00965
00966 Widget *modal_widget = NULL;
00967 for (WidgetList::reverse_iterator it = m_modal_widget_stack.rbegin(),
00968 it_end = m_modal_widget_stack.rend();
00969 it != it_end;
00970 ++it)
00971 {
00972 Widget *widget = *it;
00973 ASSERT1(widget != NULL);
00974 if (!widget->IsHidden())
00975 {
00976 modal_widget = widget;
00977 break;
00978 }
00979 }
00980
00981 if (modal_widget != NULL)
00982 {
00983 if (modal_widget->ScreenRect().IsPointInside(e->Position()))
00984 return modal_widget->InternalProcessFocusEvent(e);
00985 else
00986 return false;
00987 }
00988
00989 else
00990 {
00991 WidgetVector::reverse_iterator it;
00992 WidgetVector::reverse_iterator it_end;
00993 for (it = m_child_vector.rbegin(),
00994 it_end = m_child_vector.rend();
00995 it != it_end;
00996 ++it)
00997 {
00998 Widget *child = *it;
00999 ASSERT1(child != NULL);
01000 if (!child->IsHidden() &&
01001 child->ScreenRect().IsPointInside(e->Position()) &&
01002 child->InternalProcessFocusEvent(e))
01003 return true;
01004 }
01005
01006
01007 return Widget::InternalProcessFocusEvent(e);
01008 }
01009 }
01010
01011 bool ContainerWidget::InternalProcessMouseoverEvent (EventMouseover const *const e)
01012 {
01013
01014 if (IsHidden())
01015 return false;
01016
01017
01018 WidgetVector::reverse_iterator it;
01019 WidgetVector::reverse_iterator it_end;
01020 for (it = m_child_vector.rbegin(),
01021 it_end = m_child_vector.rend();
01022 it != it_end;
01023 ++it)
01024 {
01025 Widget *child = *it;
01026 ASSERT1(child != NULL);
01027 if (child->ScreenRect().IsPointInside(e->Position()))
01028 if (child->InternalProcessMouseoverEvent(e))
01029 return true;
01030 }
01031
01032
01033 return Widget::InternalProcessMouseoverEvent(e);
01034 }
01035
01036 bool ContainerWidget::SendMouseEventToChild (EventMouse const *const e)
01037 {
01038
01039
01040
01041 for (WidgetVector::reverse_iterator it = m_child_vector.rbegin(),
01042 it_end = m_child_vector.rend();
01043 it != it_end;
01044 ++it)
01045 {
01046 Widget *child = *it;
01047 ASSERT1(child != NULL);
01048
01049
01050 if (!child->IsHidden() &&
01051 child->ScreenRect().IsPointInside(e->Position()))
01052 if (child->ProcessEvent(e))
01053 return true;
01054 }
01055
01056 return false;
01057 }
01058
01059 void ContainerWidget::IncrementResizeBlockerCount ()
01060 {
01061 ASSERT1(m_child_resize_blocker_count < UINT32_UPPER_BOUND);
01062 ++m_child_resize_blocker_count;
01063 }
01064
01065 void ContainerWidget::DecrementResizeBlockerCount ()
01066 {
01067 ASSERT1(m_child_resize_blocker_count > 0);
01068 --m_child_resize_blocker_count;
01069 if (m_child_resize_blocker_count == 0)
01070 Resize(Size());
01071 m_child_resize_was_blocked = false;
01072 }
01073
01074 }