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