Back to Home

ESO Lua File v101041

libraries/zo_templates/tooltip.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
local function OnTooltipHidden(tooltip)
    if tooltip.ClearLines then
        tooltip:ClearLines()
    end
    tooltip:SetHidden(true)
    if tooltip == ItemTooltip then
        tooltip:HideComparativeTooltips()
    end
end
-- Yes, all controls that want to clear tooltips could just call Tooltip:ClearLines.
-- This function is here in case we want to have custom behavior for clearing tooltips.
function ClearTooltip(tooltip)
    if tooltip.SetOwner then
        tooltip:SetOwner(nil)
    end
    if not tooltip:IsControlHidden() then
        if not tooltip.animation then
            tooltip.animation = ANIMATION_MANAGER:CreateTimelineFromVirtual("TooltipFadeOutAnimation", tooltip)
            tooltip.animation:SetHandler("OnStop", function(animation, completedPlaying)
                if completedPlaying then
                    OnTooltipHidden(tooltip)
                end
            end)
        end
        if not tooltip.animation:IsPlaying() then
            tooltip.animation:PlayFromStart()
        end
    end
end
function ClearTooltipImmediately(tooltip)
    if tooltip.animation and tooltip.animation:IsPlaying() then
        tooltip.animation:Stop()
    end
    if tooltip.SetOwner then
        tooltip:SetOwner(nil)
    end
    OnTooltipHidden(tooltip)
end
function SetTooltipText(tooltip, text, color, colorG, colorB)
    if text and #text > 0 then
        local r, g, b
        if(type(color) == "number")
        then
            r = color
            g = colorG
            b = colorB
        else
            color = color or ZO_TOOLTIP_DEFAULT_COLOR
            r, g, b = color:UnpackRGB()
        end
        tooltip:AddLine(text, "", r, g, b)
    else
        ClearTooltip(tooltip)
    end
end
-- Pass nil for relativePoint to have the control choose a good relativePoint
function InitializeTooltip(tooltip, owner, point, offsetX, offsetY, relativePoint)
    if tooltip.ClearLines then
        tooltip:ClearLines()
    end
    tooltip:SetHidden(false)
    if owner then
        if tooltip.SetOwner then
            tooltip:SetOwner(owner, point, offsetX, offsetY, relativePoint)
        else
            tooltip:ClearAnchors()
            tooltip:SetAnchor(point, owner, relativePoint, offsetX, offsetY)
        end
    end
    if tooltip.animation then
        tooltip.animation:Stop()
    end
    tooltip:SetAlpha(1)
end
local QUAD_TOPLEFT      = 1
local QUAD_TOPRIGHT     = 2
local QUAD_BOTTOMRIGHT  = 3
local QUAD_BOTTOMLEFT   = 4
local OFFSET_FROM_OWNER = 4
local BETWEEN_TOOLTIP_OFFSET_X = 20
local BETWEEN_TOOLTIP_OFFSET_Y = 40
local function CalculateQuandrant(ownerMiddleX, ownerMiddleY, middleScreenX, middleScreenY)
    if ownerMiddleX >= middleScreenX and ownerMiddleY < middleScreenY then
        return QUAD_TOPRIGHT
    elseif ownerMiddleX >= middleScreenX and ownerMiddleY >= middleScreenY then
        return QUAD_BOTTOMRIGHT
    elseif ownerMiddleX < middleScreenX and ownerMiddleY >= middleScreenY then
        return QUAD_BOTTOMLEFT
    end
    return QUAD_TOPLEFT
end
local function ValidateComparativeTooltip(comparativeTooltip)
    if comparativeTooltip and not comparativeTooltip:IsHidden() then
        return comparativeTooltip
    end
    return nil
end
do
    local g_comparisonDynamicAnchors = {}
    local function DynamicAnchorLayout(tooltip, owner, quadrant, comparativeTooltip1, comparativeTooltip2, relativeAnchorsUsed)
        local isValid, point, relativeTo, relativePoint, offsetX, offsetY = tooltip:GetAnchor()
        local positionToLeftByAnchors = relativeAnchorsUsed and isValid and point == TOPRIGHT or false
        local positionToLeftByQuadrant = not relativeAnchorsUsed and quadrant and (quadrant == QUAD_TOPLEFT or quadrant == QUAD_BOTTOMLEFT)
        if comparativeTooltip1 and comparativeTooltip2 then
            if positionToLeftByAnchors or positionToLeftByQuadrant then
                comparativeTooltip1:SetOwner(tooltip, TOPLEFT, BETWEEN_TOOLTIP_OFFSET_X, 0)
                comparativeTooltip2:SetOwner(comparativeTooltip1, TOPLEFT, BETWEEN_TOOLTIP_OFFSET_X, 0, TOPRIGHT)
            else
                comparativeTooltip1:SetOwner(tooltip, TOPRIGHT, -BETWEEN_TOOLTIP_OFFSET_X, 0)
                comparativeTooltip2:SetOwner(comparativeTooltip1, TOPRIGHT, -BETWEEN_TOOLTIP_OFFSET_X, 0, TOPLEFT)
            end
            comparativeTooltip1:SetClampedToScreenInsets(0, comparativeTooltip1.topClampedToScreenInset, 0, 0)
            comparativeTooltip2:SetClampedToScreenInsets(0, comparativeTooltip2.topClampedToScreenInset, 0, 0)
        elseif comparativeTooltip1 then
            if positionToLeftByAnchors or positionToLeftByQuadrant then
                comparativeTooltip1:SetOwner(tooltip, TOPLEFT, BETWEEN_TOOLTIP_OFFSET_X, 0)
                comparativeTooltip1:SetClampedToScreenInsets(0, comparativeTooltip1.topClampedToScreenInset, 0, 0)
            else
                comparativeTooltip1:SetOwner(tooltip, TOPRIGHT, -BETWEEN_TOOLTIP_OFFSET_X, 0)
                comparativeTooltip1:SetClampedToScreenInsets(0, comparativeTooltip1.topClampedToScreenInset, 0, 0)
            end
        end
    end
    local function UpdateComparisonDynamicAnchors()
        for tooltip, anchorInfo in pairs(g_comparisonDynamicAnchors) do
            if tooltip:IsControlHidden() then
                g_comparisonDynamicAnchors[tooltip] = nil
            else
                DynamicAnchorLayout(tooltip, unpack(anchorInfo))
            end
        end
    end
    EVENT_MANAGER:RegisterForUpdate("UpdateComparisonDynamicAnchors", 0, UpdateComparisonDynamicAnchors)
    function StartWatchingComparisonDynamicAnchor(tooltip, owner, quadrant, comparativeTooltip1, comparativeTooltip2, relativeAnchorsUsed)
        if comparativeTooltip1 then
            g_comparisonDynamicAnchors[tooltip] = { owner, quadrant, comparativeTooltip1, comparativeTooltip2, relativeAnchorsUsed }
        else
            g_comparisonDynamicAnchors[tooltip] = nil
        end
    end
end
function ZO_Tooltips_SetupDynamicTooltipAnchors(tooltip, owner, comparativeTooltip1, comparativeTooltip2, useRelativeAnchors)
    if tooltip and owner then
        local quadrant = nil
        local relativeAnchorsUsed = false
        if useRelativeAnchors then
            local isValid, point, relativeTo, relativePoint, offsetX, offsetY = tooltip:GetAnchor()
            if isValid then
                tooltip:ClearAnchors()
                tooltip:SetOwner(owner, point, offsetX, offsetY, relativePoint)
                relativeAnchorsUsed = true
            end
        end
        if not relativeAnchorsUsed then
            local left, top, right, bottom = owner:GetScreenRect()
            local ownerScale = owner:GetScale()
            local ownerMiddleX = (left + right) / (2 * ownerScale)
            local ownerMiddleY = (top + bottom) / (2 * ownerScale)
            local screenWidth, screenHeight = GuiRoot:GetDimensions()
            local middleScreenX = screenWidth / 2
            local middleScreenY = screenHeight / 2
            quadrant = CalculateQuandrant(ownerMiddleX, ownerMiddleY, middleScreenX, middleScreenY)
            tooltip:ClearAnchors()
            if quadrant == QUAD_TOPLEFT or quadrant == QUAD_BOTTOMLEFT then
                tooltip:SetOwner(owner, LEFT, OFFSET_FROM_OWNER, 0)
            else
                tooltip:SetOwner(owner, RIGHT, -OFFSET_FROM_OWNER, 0)
            end
        end
        comparativeTooltip1 = ValidateComparativeTooltip(comparativeTooltip1)
        comparativeTooltip2 = ValidateComparativeTooltip(comparativeTooltip2)
        if comparativeTooltip2 and not comparativeTooltip1 then
            comparativeTooltip1 = comparativeTooltip2
            comparativeTooltip2 = nil
        end
        StartWatchingComparisonDynamicAnchor(tooltip, owner, quadrant, comparativeTooltip1, comparativeTooltip2, relativeAnchorsUsed)
    end
end
function ZO_Tooltips_ShowTruncatedTextTooltip(labelControl)
    if labelControl:WasTruncated() then
        local buttonText = labelControl:GetText()
        InitializeTooltip(InformationTooltip, labelControl, BOTTOM, 0, -3)
        InformationTooltip:AddLine(buttonText)
    end
end
    ClearTooltip(InformationTooltip)
end
local OFFSET_DISTANCE = 5
local OFFSETS_X =
{
    [TOP] = 0,
    [BOTTOM] = 0,
    [LEFT] = -OFFSET_DISTANCE,
    [RIGHT] = OFFSET_DISTANCE,
}
local OFFSETS_Y =
{
    [TOP] = -OFFSET_DISTANCE,
    [BOTTOM] = OFFSET_DISTANCE,
    [LEFT] = 0,
    [RIGHT] = 0,
}
local SIDE_TO_TOOLTIP_SIDE =
{
    [TOP] = BOTTOM,
    [BOTTOM] = TOP,
    [LEFT] = RIGHT,
    [RIGHT] = LEFT,
}
function ZO_Tooltips_ShowTextTooltip(control, side, ...)
    if side == nil then
        InitializeTooltip(InformationTooltip)
        ZO_Tooltips_SetupDynamicTooltipAnchors(InformationTooltip, control)
    else
        InitializeTooltip(InformationTooltip, control, SIDE_TO_TOOLTIP_SIDE[side], OFFSETS_X[side], OFFSETS_Y[side])
    end
    for i = 1, select("#", ...) do
        local line = select(i, ...)
        InformationTooltip:AddLine(line, "", ZO_TOOLTIP_DEFAULT_COLOR:UnpackRGB())
    end
end
    ClearTooltip(InformationTooltip)
end
function ZO_Tooltip_AddDivider(tooltipControl)
    if not tooltipControl.dividerPool then
        tooltipControl.dividerPool = ZO_ControlPool:New("ZO_BaseTooltipDivider", tooltipControl, "Divider")
        tooltipControl.dividerPool:SetCustomResetBehavior(function(divider)
            --ZO_ItemTooltip_SetStolen swaps out the divider texture so we have to reset it back
            divider:SetTexture("EsoUI/Art/Miscellaneous/horizontalDivider.dds")
        end)
    end
    local divider = tooltipControl.dividerPool:AcquireObject()
    if divider then
        tooltipControl:AddControl(divider)
        divider:SetAnchor(CENTER)
    end
end
function ZO_Tooltip_OnAddGameData(tooltipControl, gameDataType, ...)
    if gameDataType == TOOLTIP_GAME_DATA_DIVIDER then
        ZO_Tooltip_AddDivider(tooltipControl, ...)
    end
end
function ZO_Tooltip_OnCleared(tooltipControl)
    if tooltipControl.dividerPool then
        tooltipControl.dividerPool:ReleaseAllObjects()
    end
end