ToolTip.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../Core/Context.h"
  5. #include "../UI/ToolTip.h"
  6. #include "../UI/UI.h"
  7. namespace Urho3D
  8. {
  9. extern const char* UI_CATEGORY;
  10. ToolTip::ToolTip(Context* context) :
  11. UIElement(context),
  12. delay_(0.0f),
  13. hovered_(false)
  14. {
  15. SetVisible(false);
  16. }
  17. ToolTip::~ToolTip() = default;
  18. void ToolTip::RegisterObject(Context* context)
  19. {
  20. context->RegisterFactory<ToolTip>(UI_CATEGORY);
  21. URHO3D_COPY_BASE_ATTRIBUTES(UIElement);
  22. URHO3D_ACCESSOR_ATTRIBUTE("Delay", GetDelay, SetDelay, 0.0f, AM_FILE);
  23. }
  24. void ToolTip::Update(float timeStep)
  25. {
  26. // Track the element we are parented to for hovering. When we display, we move ourself to the root element
  27. // to ensure displaying on top
  28. UIElement* root = GetRoot();
  29. if (!root)
  30. return;
  31. if (parent_ != root)
  32. target_ = parent_;
  33. // If target is removed while we are displaying, we have no choice but to destroy ourself
  34. if (target_.Expired())
  35. {
  36. Remove();
  37. return;
  38. }
  39. bool hovering = target_->IsHovering() && target_->IsVisibleEffective();
  40. if (!hovering)
  41. {
  42. for (auto it = altTargets_.Begin(); it != altTargets_.End();)
  43. {
  44. SharedPtr<UIElement> target = it->Lock();
  45. if (!target)
  46. it = altTargets_.Erase(it);
  47. else
  48. {
  49. hovering = target->IsHovering() && target->IsVisibleEffective();
  50. if (hovering)
  51. break;
  52. else
  53. ++it;
  54. }
  55. }
  56. }
  57. if (hovering)
  58. {
  59. float effectiveDelay = delay_ > 0.0f ? delay_ : GetSubsystem<UI>()->GetDefaultToolTipDelay();
  60. if (!hovered_)
  61. {
  62. hovered_ = true;
  63. displayAt_.Reset();
  64. }
  65. else if (displayAt_.GetMSec(false) >= (unsigned)(effectiveDelay * 1000.0f) && parent_ == target_)
  66. {
  67. originalPosition_ = GetPosition();
  68. IntVector2 screenPosition = GetScreenPosition();
  69. SetParent(root);
  70. SetPosition(screenPosition);
  71. SetVisible(true);
  72. // BringToFront() is unreliable in this case as it takes into account only input-enabled elements.
  73. // Rather just force priority to max
  74. SetPriority(M_MAX_INT);
  75. }
  76. }
  77. else
  78. {
  79. Reset();
  80. }
  81. }
  82. void ToolTip::Reset()
  83. {
  84. if (IsVisible() && parent_ == GetRoot())
  85. {
  86. SetParent(target_);
  87. SetPosition(originalPosition_);
  88. SetVisible(false);
  89. }
  90. hovered_ = false;
  91. displayAt_.Reset();
  92. }
  93. void ToolTip::AddAltTarget(UIElement* target)
  94. {
  95. altTargets_.Push(WeakPtr<UIElement>(target));
  96. }
  97. void ToolTip::SetDelay(float delay)
  98. {
  99. delay_ = delay;
  100. }
  101. }