1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #include "../Precompiled.h"
24 
25 #include "../Core/Context.h"
26 #include "../UI/ToolTip.h"
27 #include "../UI/UI.h"
28 
29 namespace Urho3D
30 {
31 
32 extern const char* UI_CATEGORY;
33 
ToolTip(Context * context)34 ToolTip::ToolTip(Context* context) :
35     UIElement(context),
36     delay_(0.0f),
37     parentHovered_(false)
38 {
39     SetVisible(false);
40 }
41 
~ToolTip()42 ToolTip::~ToolTip()
43 {
44 }
45 
RegisterObject(Context * context)46 void ToolTip::RegisterObject(Context* context)
47 {
48     context->RegisterFactory<ToolTip>(UI_CATEGORY);
49 
50     URHO3D_COPY_BASE_ATTRIBUTES(UIElement);
51     URHO3D_ACCESSOR_ATTRIBUTE("Delay", GetDelay, SetDelay, float, 0.0f, AM_FILE);
52 }
53 
Update(float timeStep)54 void ToolTip::Update(float timeStep)
55 {
56     // Track the element we are parented to for hovering. When we display, we move ourself to the root element
57     // to ensure displaying on top
58     UIElement* root = GetRoot();
59     if (!root)
60         return;
61     if (parent_ != root)
62         target_ = parent_;
63 
64     // If target is removed while we are displaying, we have no choice but to destroy ourself
65     if (target_.Expired())
66     {
67         Remove();
68         return;
69     }
70 
71     if (target_->IsHovering() && target_->IsVisibleEffective())
72     {
73         float effectiveDelay = delay_ > 0.0f ? delay_ : GetSubsystem<UI>()->GetDefaultToolTipDelay();
74 
75         if (!parentHovered_)
76         {
77             parentHovered_ = true;
78             displayAt_.Reset();
79         }
80         else if (displayAt_.GetMSec(false) >= (unsigned)(effectiveDelay * 1000.0f) && parent_ == target_)
81         {
82             originalPosition_ = GetPosition();
83             IntVector2 screenPosition = GetScreenPosition();
84             SetParent(root);
85             SetPosition(screenPosition);
86             SetVisible(true);
87             // BringToFront() is unreliable in this case as it takes into account only input-enabled elements.
88             // Rather just force priority to max
89             SetPriority(M_MAX_INT);
90         }
91     }
92     else
93     {
94         if (IsVisible() && parent_ == root)
95         {
96             SetParent(target_);
97             SetPosition(originalPosition_);
98             SetVisible(false);
99         }
100         parentHovered_ = false;
101         displayAt_.Reset();
102     }
103 }
104 
SetDelay(float delay)105 void ToolTip::SetDelay(float delay)
106 {
107     delay_ = delay;
108 }
109 
110 }
111