1 |
157 |
Thurallor-7095 |
Tooltip = class(); |
2 |
|
Thurallor-7095 |
|
3 |
|
Thurallor-7095 |
-- The 'content' argument can be: |
4 |
|
Thurallor-7095 |
-- * a one-line string, in which case an optimally-sized control will be created for it |
5 |
|
Thurallor-7095 |
-- * a control, something derived from Turbine.UI.Control |
6 |
|
Thurallor-7095 |
-- * a function that returns a string or a control, which will be called each time the Tooltip displays |
7 |
|
Thurallor-7095 |
-- A standard border will be added to the resulting control before display. |
8 |
|
Thurallor-7095 |
|
9 |
|
Thurallor-7095 |
function Tooltip:Constructor(content) |
10 |
|
Thurallor-7095 |
self.content = content; |
11 |
|
Thurallor-7095 |
if (content == nil) then |
12 |
|
Thurallor-7095 |
error("content is nil", 2); |
13 |
|
Thurallor-7095 |
end |
14 |
|
Thurallor-7095 |
end |
15 |
|
Thurallor-7095 |
|
16 |
|
Thurallor-7095 |
function Tooltip:CreateBorderControl() |
17 |
|
Thurallor-7095 |
local control = Turbine.UI.Control(); |
18 |
|
Thurallor-7095 |
local parts = { |
19 |
|
Thurallor-7095 |
topLeft = { 0x4114061F, 10, 10, 0, 0 }; |
20 |
|
Thurallor-7095 |
top = { 0x4114061D, -20, 7, 10, 0 }; |
21 |
|
Thurallor-7095 |
topRight = { 0x41140618, 10, 10, -10, 0 }; |
22 |
|
Thurallor-7095 |
left = { 0x4114061A, 7, -20, 0, 10 }; |
23 |
|
Thurallor-7095 |
right = { 0x4114061E, 7, -20, -7, 10 }; |
24 |
|
Thurallor-7095 |
bottomLeft = { 0x41140619, 10, 10, 0, -10 }; |
25 |
|
Thurallor-7095 |
bottom = { 0x4114061C, -20, 7, 10, -7 }; |
26 |
|
Thurallor-7095 |
bottomRight = { 0x41140620, 10, 10, -10, -10 }; |
27 |
|
Thurallor-7095 |
} |
28 |
|
Thurallor-7095 |
for name, info in pairs(parts) do |
29 |
|
Thurallor-7095 |
local assetId, w, h, x, y = unpack(info); |
30 |
|
Thurallor-7095 |
local ctl = Turbine.UI.Control(); |
31 |
|
Thurallor-7095 |
ctl:SetBackground(assetId); |
32 |
|
Thurallor-7095 |
ctl:SetParent(control); |
33 |
|
Thurallor-7095 |
ctl:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend); |
34 |
|
Thurallor-7095 |
ctl:SetSize(w, h); |
35 |
|
Thurallor-7095 |
ctl.w, ctl.h, ctl.x, ctl.y = w, h, x, y; |
36 |
|
Thurallor-7095 |
end |
37 |
|
Thurallor-7095 |
control.SetSize = function(_, w, h) |
38 |
|
Thurallor-7095 |
Turbine.UI.Control.SetSize(control, w, h); |
39 |
|
Thurallor-7095 |
for c = 1, 8 do |
40 |
|
Thurallor-7095 |
local ctl = control:GetControls():Get(c); |
41 |
|
Thurallor-7095 |
ctl:SetSize((w + ctl.w) % w, (h + ctl.h) % h); |
42 |
|
Thurallor-7095 |
ctl:SetPosition((w + ctl.x) % w, (h + ctl.y) % h); |
43 |
|
Thurallor-7095 |
end |
44 |
|
Thurallor-7095 |
end |
45 |
|
Thurallor-7095 |
return control; |
46 |
|
Thurallor-7095 |
end |
47 |
|
Thurallor-7095 |
|
48 |
|
Thurallor-7095 |
function Tooltip:AddBorder(content) |
49 |
|
Thurallor-7095 |
local border = self:CreateBorderControl(); |
50 |
|
Thurallor-7095 |
|
51 |
|
Thurallor-7095 |
if (type(content) == "string") then |
52 |
|
Thurallor-7095 |
-- Make an optimally-sized Label control to contain the text |
53 |
|
Thurallor-7095 |
local label = Turbine.UI.Label(); |
54 |
|
Thurallor-7095 |
label:SetBackColor(Turbine.UI.Color(0.9, 0, 0, 0)); |
55 |
|
Thurallor-7095 |
label:SetFont(Turbine.UI.Lotro.Font.TrajanPro16); |
56 |
|
Thurallor-7095 |
label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter); |
57 |
|
Thurallor-7095 |
label:SetText(content); |
58 |
|
Thurallor-7095 |
label:AutoSize(); |
59 |
|
Thurallor-7095 |
content = label; |
60 |
|
Thurallor-7095 |
self.simple = true; |
61 |
|
Thurallor-7095 |
else |
62 |
|
Thurallor-7095 |
self.simple = false; |
63 |
|
Thurallor-7095 |
end |
64 |
|
Thurallor-7095 |
|
65 |
|
Thurallor-7095 |
content:SetParent(border); |
66 |
|
Thurallor-7095 |
content:SetPosition(3, 3); |
67 |
|
Thurallor-7095 |
border:SetSize(content:GetWidth() + 6, content:GetHeight() + 6); |
68 |
|
Thurallor-7095 |
return border; |
69 |
|
Thurallor-7095 |
end |
70 |
|
Thurallor-7095 |
|
71 |
|
Thurallor-7095 |
function Tooltip:GetContent() |
72 |
|
Thurallor-7095 |
if (type(self.content) == "function") then |
73 |
|
Thurallor-7095 |
-- Content is a user-supplied function that returns a string or a Turbine.UI.Control |
74 |
|
Thurallor-7095 |
local result = self.content(self.attachment); |
75 |
|
Thurallor-7095 |
if (result == nil) then |
76 |
|
Thurallor-7095 |
error("tooltip function returned nil"); |
77 |
|
Thurallor-7095 |
end |
78 |
|
Thurallor-7095 |
return self:AddBorder(result); |
79 |
|
Thurallor-7095 |
else |
80 |
|
Thurallor-7095 |
-- Content is a user-supplied string or Turbine.UI.Control |
81 |
|
Thurallor-7095 |
return self:AddBorder(self.content); |
82 |
|
Thurallor-7095 |
end |
83 |
|
Thurallor-7095 |
end |
84 |
|
Thurallor-7095 |
|
85 |
|
Thurallor-7095 |
-- If the tooltip is currently being displayed, and 'content' is a function, it will be called again and the display updated. |
86 |
|
Thurallor-7095 |
function Tooltip:Update() |
87 |
|
Thurallor-7095 |
if (self.window) then |
88 |
|
Thurallor-7095 |
self:SetVisible(false); |
89 |
|
Thurallor-7095 |
self:SetVisible(true); |
90 |
|
Thurallor-7095 |
end |
91 |
|
Thurallor-7095 |
end |
92 |
|
Thurallor-7095 |
|
93 |
|
Thurallor-7095 |
-- Note: This should only be called once; changing the attachment to a different control is not implemented. |
94 |
|
Thurallor-7095 |
function Tooltip:Attach(control) |
95 |
|
Thurallor-7095 |
if (control == nil) then |
96 |
|
Thurallor-7095 |
error("control is nil", 2); |
97 |
|
Thurallor-7095 |
end |
98 |
|
Thurallor-7095 |
self.attachment = control; |
99 |
|
Thurallor-7095 |
control._ShowTooltip = function() |
100 |
|
Thurallor-7095 |
self:SetVisible(true); |
101 |
|
Thurallor-7095 |
end |
102 |
|
Thurallor-7095 |
control._HideTooltip = function() |
103 |
|
Thurallor-7095 |
self:SetVisible(false); |
104 |
|
Thurallor-7095 |
end |
105 |
|
Thurallor-7095 |
AddCallback(control, "MouseHover", control._ShowTooltip); |
106 |
|
Thurallor-7095 |
AddCallback(control, "MouseLeave", control._HideTooltip); |
107 |
|
Thurallor-7095 |
end |
108 |
|
Thurallor-7095 |
|
109 |
|
Thurallor-7095 |
function Tooltip:Detach() |
110 |
|
Thurallor-7095 |
if (self.attachment) then |
111 |
169 |
Thurallor-7095 |
RemoveCallback(self.attachment, "MouseHover", self.attachment._ShowTooltip); |
112 |
|
Thurallor-7095 |
RemoveCallback(self.attachment, "MouseLeave", self.attachment._HideTooltip); |
113 |
157 |
Thurallor-7095 |
end |
114 |
|
Thurallor-7095 |
self.attachment = nil; |
115 |
|
Thurallor-7095 |
end |
116 |
|
Thurallor-7095 |
|
117 |
|
Thurallor-7095 |
function Tooltip:SetVisible(visible) |
118 |
|
Thurallor-7095 |
if (visible) then |
119 |
|
Thurallor-7095 |
if (not self.window) then |
120 |
|
Thurallor-7095 |
self.window = self:CreateWindow(); |
121 |
|
Thurallor-7095 |
end |
122 |
|
Thurallor-7095 |
else |
123 |
|
Thurallor-7095 |
if (self.window) then |
124 |
|
Thurallor-7095 |
self.window.content:SetParent(nil); |
125 |
|
Thurallor-7095 |
self.window:SetVisible(false); |
126 |
|
Thurallor-7095 |
self.window:Close(); |
127 |
|
Thurallor-7095 |
self.window = nil; |
128 |
|
Thurallor-7095 |
end |
129 |
|
Thurallor-7095 |
end |
130 |
|
Thurallor-7095 |
end |
131 |
|
Thurallor-7095 |
|
132 |
|
Thurallor-7095 |
function Tooltip:CreateWindow() |
133 |
|
Thurallor-7095 |
local content = self:GetContent(); |
134 |
|
Thurallor-7095 |
local width, height = content:GetSize(); |
135 |
|
Thurallor-7095 |
local window = Turbine.UI.Window(); |
136 |
|
Thurallor-7095 |
window:SetVisible(true); |
137 |
|
Thurallor-7095 |
content:SetParent(window); |
138 |
|
Thurallor-7095 |
window.content = content; |
139 |
|
Thurallor-7095 |
window:SetSize(width, height); |
140 |
|
Thurallor-7095 |
window:SetZOrder(2147483647); -- in front of everything, including Turbine tooltip (if any) |
141 |
|
Thurallor-7095 |
window.MouseEnter = function() |
142 |
|
Thurallor-7095 |
self:SetVisible(false); |
143 |
|
Thurallor-7095 |
end |
144 |
|
Thurallor-7095 |
|
145 |
|
Thurallor-7095 |
-- Determine optimal positioning of the tooltip |
146 |
|
Thurallor-7095 |
local displayWidth, displayHeight = Turbine.UI.Display.GetSize(); |
147 |
|
Thurallor-7095 |
local x, y = Turbine.UI.Display.GetMousePosition(); |
148 |
|
Thurallor-7095 |
local left, top = x + 30, y + 31; |
149 |
|
Thurallor-7095 |
if (left + width > displayWidth) then |
150 |
|
Thurallor-7095 |
left = displayWidth - width; |
151 |
|
Thurallor-7095 |
end |
152 |
|
Thurallor-7095 |
if (self.simple) then |
153 |
|
Thurallor-7095 |
-- For a simple one-line tooltip, we try to match Turbine's tooltip |
154 |
|
Thurallor-7095 |
-- location so we can cover it up (if it's showing). |
155 |
|
Thurallor-7095 |
if (top + height > displayHeight) then |
156 |
|
Thurallor-7095 |
top = displayHeight - height; |
157 |
|
Thurallor-7095 |
end |
158 |
|
Thurallor-7095 |
else |
159 |
|
Thurallor-7095 |
-- For multiline tooltips, use a similar strategy, but we try a little |
160 |
|
Thurallor-7095 |
-- harder to position the tooltip such that it doesn't overlap the |
161 |
|
Thurallor-7095 |
-- mouse cursor. |
162 |
|
Thurallor-7095 |
if (top + height > displayHeight) then |
163 |
|
Thurallor-7095 |
top = y - height - 20; |
164 |
|
Thurallor-7095 |
end |
165 |
|
Thurallor-7095 |
end |
166 |
|
Thurallor-7095 |
window:SetPosition(left, top); |
167 |
|
Thurallor-7095 |
|
168 |
|
Thurallor-7095 |
return window; |
169 |
|
Thurallor-7095 |
end |
170 |
|
Thurallor-7095 |
|
171 |
|
Thurallor-7095 |
Thurallor = Thurallor or {}; |
172 |
|
Thurallor-7095 |
Thurallor.UI = Thurallor.UI or {}; |
173 |
|
Thurallor-7095 |
Thurallor.UI.Tooltip = Tooltip; |