You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1543 lines
50 KiB
1543 lines
50 KiB
local _, addon = ...
|
|
local API = addon.API;
|
|
local PixelUtil = addon.PixelUtil;
|
|
local L = addon.L;
|
|
local Round = API.Round;
|
|
local GetItemQualityColor = API.GetItemQualityColor;
|
|
local IsItemValidForComparison = API.IsItemValidForComparison;
|
|
local GetTransmogItemInfo = API.GetTransmogItemInfo;
|
|
local C_TooltipInfo = addon.TooltipAPI;
|
|
local C_TransmogCollection = C_TransmogCollection;
|
|
local IsDressableItemByID = C_Item.IsDressableItemByID;
|
|
local GetItemInfoInstant = C_Item.GetItemInfoInstant;
|
|
|
|
local SharedTooltip = CreateFrame("Frame");
|
|
addon.SharedTooltip = SharedTooltip;
|
|
|
|
SharedTooltip:Hide();
|
|
SharedTooltip:SetSize(16, 16);
|
|
SharedTooltip:SetIgnoreParentScale(true);
|
|
SharedTooltip:SetIgnoreParentAlpha(true);
|
|
SharedTooltip:SetFrameStrata("TOOLTIP");
|
|
SharedTooltip:SetFixedFrameStrata(true);
|
|
SharedTooltip:SetClampedToScreen(true);
|
|
SharedTooltip:SetClampRectInsets(-4, 4, 4, -4);
|
|
|
|
SharedTooltip.ShowFrame = SharedTooltip.Show;
|
|
SharedTooltip.HideFrame = SharedTooltip.Hide;
|
|
|
|
local LINE_TYPE_PRICE = Enum.TooltipDataLineType.SellPrice or 11;
|
|
|
|
local FONT_LARGE = "DUIFont_Tooltip_Large";
|
|
local FONT_MEDIUM = "DUIFont_Tooltip_Medium";
|
|
local FONT_SMALL = "DUIFont_Tooltip_Small";
|
|
local FONT_HEIGHT_MEDIUM = 12;
|
|
local FONTSTRING_MIN_GAP = 24; --Betweeb the left and the right text of the same line
|
|
local SELL_PRICE_TEXT = (SELL_PRICE or "Sell Price").." ";
|
|
local NORMAL_FONT_COLOR = NORMAL_FONT_COLOR;
|
|
|
|
|
|
local SPACING_NEW_LINE = 4; --Between paragraphs
|
|
local SPACING_INTERNAL = 2; --Within the same paragraph
|
|
local TOOLTIP_PADDING = 12;
|
|
local TOOLTIP_MAX_WIDTH = 256;
|
|
local FONTSTRING_MAX_WIDTH = TOOLTIP_MAX_WIDTH - 2*TOOLTIP_PADDING;
|
|
local FONTSTRING_SHRINK_IF_MODEL = 36;
|
|
local MODEL_WIDTH, MODEL_HEIGHT = 78, 104;
|
|
local FORMAT_ICON_TEXT = "|T%s:0:0:0:-"..SPACING_NEW_LINE.."|t %s";
|
|
|
|
local HOTKEY_ALTERNATE_MODE = "Shift";
|
|
|
|
local unpack = unpack;
|
|
local pairs = pairs;
|
|
local max = math.max;
|
|
local PI2 = math.floor(1000*math.pi*2)/1000;
|
|
local format = string.format;
|
|
|
|
|
|
local function PreviewModel_Turntable_OnUpdate(self, elapsed)
|
|
self.yaw = self.yaw + elapsed * PI2 * 0.1;
|
|
if self.yaw > PI2 then
|
|
self.yaw = self.yaw - PI2;
|
|
end
|
|
self:SetFacing(self.yaw);
|
|
end
|
|
|
|
local Model_ApplyUICamera = Model_ApplyUICamera;
|
|
local function PreviewModel_OnModelLoaded(self)
|
|
if self.cameraID then
|
|
Model_ApplyUICamera(self, self.cameraID);
|
|
end
|
|
|
|
self.parent:SyncAnimation();
|
|
end
|
|
|
|
local DualModelMixin = {};
|
|
|
|
function DualModelMixin:Init(parent)
|
|
local model = CreateFrame("DressUpModel", nil, parent);
|
|
self.Model1 = model;
|
|
model.parent = self;
|
|
|
|
API.SetModelLight(model, true, false, -1, 1, -1, 0.8, 1, 1, 1, 0.5, 1, 1, 1);
|
|
model:SetKeepModelOnHide(true);
|
|
model:SetModelDrawLayer("ARTWORK");
|
|
model:SetAutoDress(false);
|
|
model:SetDoBlend(false);
|
|
model:SetScript("OnModelLoaded", PreviewModel_OnModelLoaded);
|
|
|
|
local modelShadow = CreateFrame("DressUpModel", nil, parent);
|
|
self.Model2 = modelShadow;
|
|
modelShadow.parent = self;
|
|
|
|
API.SetModelLight(modelShadow, false);
|
|
modelShadow:SetPoint("CENTER", model, "CENTER", 4, -4);
|
|
modelShadow:SetKeepModelOnHide(true);
|
|
modelShadow:SetModelDrawLayer("BORDER");
|
|
modelShadow:SetAutoDress(false);
|
|
modelShadow:SetDoBlend(false);
|
|
modelShadow:SetScript("OnModelLoaded", PreviewModel_OnModelLoaded);
|
|
|
|
local a = 0;
|
|
modelShadow:SetFogColor(a, a, a);
|
|
modelShadow:SetParticlesEnabled(false);
|
|
|
|
--local inset = 12;
|
|
--model:SetViewInsets(inset, inset, inset, inset); --Push model farther
|
|
--modelShadow:SetViewInsets(inset, inset, inset, inset);
|
|
end
|
|
|
|
function DualModelMixin:SetModelSize(width, height)
|
|
self.width, self.height = width, height;
|
|
self.Model1:SetSize(width, height);
|
|
self.Model2:SetSize(width, height);
|
|
end
|
|
|
|
function DualModelMixin:GetWidth()
|
|
return self.width
|
|
end
|
|
|
|
function DualModelMixin:SetAnimation(animID)
|
|
self.animID = animID;
|
|
self:SyncAnimation();
|
|
end
|
|
|
|
function DualModelMixin:SyncAnimation()
|
|
if self.animID then
|
|
self.Model1:SetAnimation(self.animID, 0);
|
|
self.Model2:SetAnimation(self.animID, 0);
|
|
end
|
|
end
|
|
|
|
function DualModelMixin:UseModelCenterToTransform(state)
|
|
self.Model1:UseModelCenterToTransform(state);
|
|
self.Model2:UseModelCenterToTransform(state);
|
|
end
|
|
|
|
function DualModelMixin:SetPoint(point, relativeTo, relativePoint, x, y)
|
|
self.point = point;
|
|
self.relativeTo = relativeTo;
|
|
self.relativePoint = relativePoint;
|
|
self.x = x;
|
|
self.y = y;
|
|
self.Model1:SetPoint(point, relativeTo, relativePoint, x, y);
|
|
end
|
|
|
|
function DualModelMixin:SetOffsetY(ratio)
|
|
local y = self.height * ratio;
|
|
self.y = y;
|
|
self:SetPoint(self.point, self.relativeTo, self.relativePoint, self.x, y);
|
|
end
|
|
|
|
function DualModelMixin:ClearModel()
|
|
if self.hasModel then
|
|
self.hasModel = false;
|
|
self.Model1:ClearModel();
|
|
self.Model2:ClearModel();
|
|
end
|
|
end
|
|
|
|
function DualModelMixin:SetCameraID(cameraID)
|
|
self.Model1.cameraID = cameraID;
|
|
self.Model2.cameraID = cameraID;
|
|
end
|
|
|
|
function DualModelMixin:ResetPosition()
|
|
self.Model1:SetPosition(0, 0, 0);
|
|
self.Model1:SetPitch(0);
|
|
self.Model1:SetRoll(0);
|
|
self.Model2:SetPosition(0, 0, 0);
|
|
self.Model2:SetPitch(0);
|
|
self.Model2:SetRoll(0);
|
|
end
|
|
|
|
function DualModelMixin:SetYaw(yaw)
|
|
self.Model1:SetFacing(yaw);
|
|
self.Model2:SetFacing(yaw);
|
|
end
|
|
|
|
function DualModelMixin:SetDisplayInfo(creatureDisplayID)
|
|
self.Model1:SetDisplayInfo(creatureDisplayID);
|
|
self.Model2:SetDisplayInfo(creatureDisplayID);
|
|
end
|
|
|
|
function DualModelMixin:SetModelByUnit(unit)
|
|
API.SetModelByUnit(self.Model1, unit);
|
|
API.SetModelByUnit(self.Model2, unit);
|
|
end
|
|
|
|
function DualModelMixin:SetItem(item)
|
|
self.Model1:SetItem(item);
|
|
self.Model2:SetItem(item);
|
|
end
|
|
|
|
function DualModelMixin:FreezeAnimation(animID, variation, frame)
|
|
self.Model1:FreezeAnimation(animID, variation, frame);
|
|
self.Model2:FreezeAnimation(animID, variation, frame);
|
|
end
|
|
|
|
function DualModelMixin:TryOn(item)
|
|
self.Model1:TryOn(item);
|
|
self.Model2:TryOn(item);
|
|
end
|
|
|
|
function DualModelMixin:SetUseTransmogChoices(state)
|
|
self.Model1:SetUseTransmogChoices(state);
|
|
self.Model2:SetUseTransmogChoices(state);
|
|
|
|
self.Model1:SetUseTransmogSkin(state);
|
|
self.Model2:SetUseTransmogSkin(state);
|
|
end
|
|
|
|
function DualModelMixin:SetUseTurntable(useTurntable)
|
|
if useTurntable then
|
|
self.Model1.yaw = -0.78;
|
|
self.Model1:SetScript("OnUpdate", PreviewModel_Turntable_OnUpdate);
|
|
self.Model2.yaw = -0.78;
|
|
self.Model2:SetScript("OnUpdate", PreviewModel_Turntable_OnUpdate);
|
|
else
|
|
self.Model1:SetScript("OnUpdate", nil);
|
|
self.Model2:SetScript("OnUpdate", nil);
|
|
self.Model1.yaw = 0;
|
|
self.Model2.yaw = 0;
|
|
end
|
|
end
|
|
|
|
function DualModelMixin:SetModelAlpha(alpha)
|
|
self.Model1:SetModelAlpha(alpha);
|
|
self.Model2:SetModelAlpha(0.8 * alpha);
|
|
end
|
|
|
|
function DualModelMixin:SetUseParentLevel(parent, containerFrame)
|
|
local level = parent:GetFrameLevel();
|
|
local strata = parent:GetFrameStrata();
|
|
|
|
if containerFrame then
|
|
containerFrame:SetFrameStrata(strata);
|
|
containerFrame:SetFrameLevel(level);
|
|
end
|
|
|
|
self.Model1:SetFrameStrata(strata);
|
|
self.Model1:SetFrameLevel(level);
|
|
self.Model2:SetFrameStrata(strata);
|
|
self.Model2:SetFrameLevel(level);
|
|
end
|
|
|
|
|
|
function SharedTooltip:UpdatePixel(scale)
|
|
if not self.Background then return end;
|
|
|
|
if not scale then
|
|
scale = self:GetEffectiveScale();
|
|
end
|
|
|
|
local pixelOffset = 16.0;
|
|
local offset = API.GetPixelForScale(scale, pixelOffset);
|
|
offset = 0; --Temp Fix Debug
|
|
self.Background:ClearAllPoints();
|
|
self.Background:SetPoint("TOPLEFT", self, "TOPLEFT", -offset, offset);
|
|
self.Background:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", offset, -offset);
|
|
|
|
API.UpdateTextureSliceScale(self.Background);
|
|
end
|
|
|
|
function SharedTooltip:Init()
|
|
if not self.Background then
|
|
local texture = self:CreateTexture(nil, "BACKGROUND", nil, -1);
|
|
local corner = 32;
|
|
self.Background = texture;
|
|
texture:SetTextureSliceMargins(corner, corner, corner, corner);
|
|
texture:SetTextureSliceMode(1);
|
|
texture:SetTexture(addon.ThemeUtil:GetTextureFile("TooltipBackground-Temp.png"));
|
|
|
|
PixelUtil:AddPixelPerfectObject(self);
|
|
end
|
|
|
|
if not self.Content then
|
|
self.Content = CreateFrame("Frame", nil, self);
|
|
self.Content:SetWidth(8); --Temp
|
|
self.Content:SetPoint("TOPLEFT", self, "TOPLEFT", TOOLTIP_PADDING, -TOOLTIP_PADDING);
|
|
self.Content:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT", TOOLTIP_PADDING, TOOLTIP_PADDING);
|
|
--self.Content:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -TOOLTIP_PADDING, TOOLTIP_PADDING);
|
|
end
|
|
|
|
if not self.fontStrings then
|
|
self.fontStrings = {};
|
|
end
|
|
|
|
if not self.PreviewFrame then
|
|
self.PreviewFrame = CreateFrame("Frame", nil, self);
|
|
self.PreviewFrame:SetPoint("TOPRIGHT", self, "TOPRIGHT", -TOOLTIP_PADDING, -TOOLTIP_PADDING);
|
|
self.PreviewFrame:Hide();
|
|
|
|
self.modelWidth, self.modelHeight = MODEL_WIDTH, MODEL_HEIGHT;
|
|
self.PreviewFrame:SetSize(MODEL_WIDTH, MODEL_HEIGHT);
|
|
|
|
self.DualModel = API.CreateFromMixins(DualModelMixin);
|
|
self.DualModel:Init(self.PreviewFrame);
|
|
self.DualModel:SetModelSize(MODEL_WIDTH, MODEL_HEIGHT);
|
|
self.DualModel:SetPoint("TOPRIGHT", self, "TOPRIGHT", -TOOLTIP_PADDING, 0.33*MODEL_HEIGHT);
|
|
|
|
self.DualModel:SetUseParentLevel(self, self.PreviewFrame);
|
|
end
|
|
|
|
|
|
if not self.iconPool then
|
|
local function CreateIcon()
|
|
local icon = self.Content:CreateTexture(nil, "OVERLAY");
|
|
return icon
|
|
end
|
|
|
|
local function RemoveIcon(icon)
|
|
icon:ClearAllPoints();
|
|
icon:Hide();
|
|
icon:SetTexture(nil);
|
|
end
|
|
|
|
self.iconPool = API.CreateObjectPool(CreateIcon, RemoveIcon);
|
|
end
|
|
|
|
self:UpdatePixel();
|
|
self.Init = nil;
|
|
end
|
|
|
|
function SharedTooltip:ClearLines()
|
|
if self.numLines == 0 then return end;
|
|
|
|
self.numLines = 0;
|
|
self.numCols = 1;
|
|
self.numFontStrings = 0;
|
|
self.dataInstanceID = nil;
|
|
self.hyperlink = nil;
|
|
self.fontChanged = false;
|
|
self.grid = {};
|
|
self.useGridLayout = false;
|
|
|
|
if self.triggeredByEvent then
|
|
self.triggeredByEvent = nil;
|
|
else
|
|
self.itemID = nil;
|
|
end
|
|
|
|
if self.fontStrings then
|
|
for _, fontString in pairs(self.fontStrings) do
|
|
fontString:Hide();
|
|
fontString:SetText(nil);
|
|
fontString.icon = nil;
|
|
end
|
|
end
|
|
|
|
if self.usePreviewModel then
|
|
self.usePreviewModel = false;
|
|
self.DualModel:ClearModel();
|
|
end
|
|
|
|
if self.PreviewFrame then
|
|
self.PreviewFrame:Hide();
|
|
end
|
|
|
|
if self.iconPool then
|
|
self.iconPool:Release();
|
|
end
|
|
|
|
self:HideHotkey();
|
|
end
|
|
|
|
function SharedTooltip:GetHyperlink()
|
|
return self.hyperlink
|
|
end
|
|
|
|
function SharedTooltip:GetItemID()
|
|
if self.hyperlink then
|
|
return GetItemInfoInstant(self.hyperlink)
|
|
end
|
|
end
|
|
|
|
do
|
|
function SharedTooltip:DisplayModel()
|
|
local itemID = self:GetItemID();
|
|
local usePreview;
|
|
|
|
if itemID then
|
|
local DualModel = self.DualModel;
|
|
local useTurntable;
|
|
|
|
if IsDressableItemByID(itemID) then
|
|
usePreview = true;
|
|
|
|
local appearanceID, sourceID = GetTransmogItemInfo(itemID);
|
|
|
|
if appearanceID then
|
|
if API.IsHoldableItem(itemID) then --Weapons
|
|
local cameraID = C_TransmogCollection.GetAppearanceCameraIDBySource(sourceID);
|
|
|
|
DualModel:SetCameraID(cameraID);
|
|
DualModel:SetItem(itemID, sourceID);
|
|
else --Armor
|
|
local cameraID = C_TransmogCollection.GetAppearanceCameraIDBySource(sourceID);
|
|
|
|
local useTransmogSkin, setupGear = API.GetTransmogSetup(itemID);
|
|
DualModel:SetUseTransmogChoices(useTransmogSkin);
|
|
DualModel:SetCameraID(cameraID);
|
|
DualModel:SetModelByUnit("player");
|
|
DualModel:FreezeAnimation(0, 0, 0);
|
|
DualModel:TryOn(sourceID);
|
|
|
|
if setupGear then
|
|
for _, v in ipairs(setupGear) do
|
|
DualModel:TryOn(v);
|
|
end
|
|
end
|
|
end
|
|
else --Transmog Set
|
|
useTurntable = true;
|
|
local detailsCameraID, vendorCameraID = C_TransmogSets.GetCameraIDs()
|
|
|
|
DualModel:SetCameraID(vendorCameraID);
|
|
DualModel:SetModelByUnit("player");
|
|
DualModel:FreezeAnimation(0, 0, 0);
|
|
DualModel:TryOn("item:"..itemID);
|
|
end
|
|
DualModel:SetModelSize(MODEL_WIDTH, MODEL_HEIGHT);
|
|
DualModel:SetOffsetY(0.33);
|
|
else
|
|
local mountID = C_MountJournal.GetMountFromItem(itemID);
|
|
local displayID;
|
|
|
|
if mountID then
|
|
usePreview = true;
|
|
local creatureDisplayID, description, _, isSelfMount, _, modelSceneID, animID, spellVisualKitID, disablePlayerMountPreview = C_MountJournal.GetMountInfoExtraByID(mountID);
|
|
displayID = creatureDisplayID;
|
|
if isSelfMount then
|
|
DualModel:SetAnimation(618);
|
|
else
|
|
DualModel:SetAnimation(0);
|
|
end
|
|
else
|
|
local _, _, _, creatureID, _, description, _, _, _, _, _, creatureDisplayID, speciesID = C_PetJournal.GetPetInfoByItemID(itemID);
|
|
if creatureDisplayID then
|
|
displayID = creatureDisplayID;
|
|
usePreview = true;
|
|
DualModel:SetAnimation(0);
|
|
|
|
else
|
|
|
|
end
|
|
end
|
|
|
|
if displayID then
|
|
useTurntable = true;
|
|
DualModel:ClearModel();
|
|
DualModel:SetCameraID(nil);
|
|
DualModel:UseModelCenterToTransform(false);
|
|
DualModel:SetModelSize(MODEL_HEIGHT, MODEL_HEIGHT); --Square
|
|
DualModel:ResetPosition();
|
|
DualModel:SetDisplayInfo(displayID);
|
|
DualModel:SetOffsetY(0.5);
|
|
--DualModel:SetYaw(0.44);
|
|
end
|
|
end
|
|
|
|
DualModel:SetUseTurntable(useTurntable);
|
|
end
|
|
|
|
if usePreview then
|
|
self.usePreviewModel = true;
|
|
self.PreviewFrame:Show();
|
|
else
|
|
self.usePreviewModel = false;
|
|
self.PreviewFrame:Hide();
|
|
end
|
|
end
|
|
|
|
if not (IsDressableItemByID and C_PetJournal and C_PetJournal.GetPetInfoByItemID) then
|
|
function SharedTooltip:DisplayModel()
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function SharedTooltip:ShowHotkey(key, description, callback)
|
|
if not self.HotkeyFrame then
|
|
self.HotkeyFrame = CreateFrame("Frame", nil, self, "DUIDialogHotkeyTemplate");
|
|
end
|
|
|
|
local success = self.HotkeyFrame:SetKey(key);
|
|
if success then
|
|
self:AddBlankLine();
|
|
local gap = 4;
|
|
local width = self.HotkeyFrame:GetWidth();
|
|
local fontString = self:AddLeftLine(description, 0.5, 0.5, 0.5, true, nil, 2, width + gap);
|
|
self.HotkeyFrame:ClearAllPoints();
|
|
self.HotkeyFrame:SetPoint("RIGHT", fontString, "LEFT", -gap, 0);
|
|
self.HotkeyFrame:Show();
|
|
self.hasHotkey = true;
|
|
self:RegisterEvent("MODIFIER_STATE_CHANGED");
|
|
else
|
|
self.hasHotkey = false;
|
|
end
|
|
|
|
self.onHotkeyPressedCallback = callback;
|
|
end
|
|
|
|
function SharedTooltip:HideHotkey()
|
|
if self.hasHotkey then
|
|
self.HotkeyFrame:Hide();
|
|
self.HotkeyFrame:ClearAllPoints();
|
|
self:UnregisterEvent("MODIFIER_STATE_CHANGED");
|
|
self.onHotkeyPressedCallback = nil;
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:ToggleAlternateInfo()
|
|
if self.onHotkeyPressedCallback then
|
|
self.onHotkeyPressedCallback(self);
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:ProcessItemExternal(item)
|
|
--for Pawn
|
|
end
|
|
|
|
local function AlternateModeCallback_ItemComparison(self)
|
|
DialogueUI_DB.TooltipShowItemComparison = not DialogueUI_DB.TooltipShowItemComparison;
|
|
|
|
SharedTooltip:ReprocessInfo();
|
|
end
|
|
|
|
do
|
|
if C_TooltipComparison and C_TooltipComparison.GetItemComparisonInfo and TooltipComparisonManager then
|
|
function SharedTooltip:AddComparisonItems(shouldShowComparison, comparisonItem, rewardItem, equippedItem)
|
|
--Item = { guid = "" }
|
|
if equippedItem and equippedItem.guid then
|
|
local delta = C_TooltipComparison.GetItemComparisonDelta(comparisonItem, equippedItem);
|
|
local itemGUID = equippedItem.guid;
|
|
if delta and itemGUID then
|
|
if not shouldShowComparison then
|
|
return true
|
|
end
|
|
self:AddBlankLine();
|
|
|
|
local equippedItemLink = C_Item.GetItemLinkByGUID(itemGUID); --API.GetEquippedItemLink(rewardItem);
|
|
if equippedItemLink then
|
|
self:AddLeftLine(L["Format Replace Item"]:format(equippedItemLink), 1, 0.82, 0, true);
|
|
else
|
|
self:AddLeftLine(ITEM_DELTA_DESCRIPTION, 1, 0.82, 0, true);
|
|
end
|
|
|
|
local itemLevelDelta = API.GetItemLevelDelta(rewardItem, equippedItemLink, true);
|
|
if itemLevelDelta then
|
|
self:AddLeftLine(itemLevelDelta, 1, 1, 1, false, nil, 2, TOOLTIP_PADDING);
|
|
end
|
|
|
|
if #delta > 0 then
|
|
for i, deltaLine in ipairs(delta) do
|
|
self:AddLeftLine(deltaLine, 1, 1, 1, false, nil, 2, TOOLTIP_PADDING);
|
|
end
|
|
else
|
|
self:AddLeftLine(L["Identical Stats"], 1, 0.82, 0, false, nil, 2, TOOLTIP_PADDING);
|
|
end
|
|
|
|
local effectText, cached = API.GetItemEffect(equippedItemLink);
|
|
if not cached then
|
|
C_Timer.After(0.25, function()
|
|
self:ReTriggerOnEnter();
|
|
end);
|
|
end
|
|
if effectText then
|
|
local offset = nil; --TOOLTIP_PADDING
|
|
self:AddLeftLine(effectText, 0, 1, 0, false, nil, 2, offset);
|
|
end
|
|
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function SharedTooltip:ShowItemComparison()
|
|
local rewardItem = self:GetHyperlink();
|
|
if not IsItemValidForComparison(rewardItem) then return end;
|
|
|
|
local shouldShowComparison = DialogueUI_DB.TooltipShowItemComparison == true;
|
|
local canCompare = false;
|
|
|
|
local comparisonItem = TooltipComparisonManager:CreateComparisonItem(self.tooltipData); --Mouse-over item: Quest Reward
|
|
local compairsonInfo = comparisonItem and C_TooltipComparison.GetItemComparisonInfo(comparisonItem);
|
|
|
|
if compairsonInfo then
|
|
local method = compairsonInfo.method;
|
|
local isPairedItem = method == 2 or method == 3; --.WithBagMainHandItem or comparisonMethod == Enum.TooltipComparisonMethod.WithBagOffHandItem;
|
|
canCompare = self:AddComparisonItems(shouldShowComparison, comparisonItem, rewardItem, compairsonInfo.item);
|
|
if (not isPairedItem) and compairsonInfo.additionalItems and #compairsonInfo.additionalItems >= 1 then
|
|
self:AddComparisonItems(shouldShowComparison, comparisonItem, rewardItem, compairsonInfo.additionalItems[1]);
|
|
end
|
|
end
|
|
|
|
self:ProcessItemExternal(rewardItem);
|
|
|
|
if canCompare then
|
|
local description = shouldShowComparison and L["Hide Comparison"] or L["Show Comparison"];
|
|
self:ShowHotkey(HOTKEY_ALTERNATE_MODE, description, AlternateModeCallback_ItemComparison);
|
|
self:Show();
|
|
end
|
|
end
|
|
else --Classic
|
|
function SharedTooltip:ShowItemComparison()
|
|
local rewardItem = self:GetHyperlink();
|
|
if not IsItemValidForComparison(rewardItem) then return end;
|
|
|
|
local shouldShowComparison = DialogueUI_DB.TooltipShowItemComparison == true;
|
|
local canCompare = false;
|
|
|
|
local compairsonInfo, areItemsSameType = API.GetItemComparisonInfo(rewardItem);
|
|
|
|
if compairsonInfo then
|
|
canCompare = true;
|
|
if shouldShowComparison then
|
|
local requery = false;
|
|
for _, info in ipairs(compairsonInfo) do
|
|
self:AddBlankLine();
|
|
self:AddLeftLine(L["Format Replace Item"]:format(info.equippedItemLink), 1, 0.82, 0, true);
|
|
|
|
if not areItemsSameType then
|
|
self:AddLeftLine(L["Different Item Types Alert"], 1.000, 0.125, 0.125, true); --TODO: this red on the Dark theme doesn't look comforting.
|
|
end
|
|
|
|
if #info.deltaStats > 0 then
|
|
for i, deltaLine in ipairs(info.deltaStats) do
|
|
self:AddLeftLine(deltaLine, 1, 1, 1, false, nil, 2, TOOLTIP_PADDING);
|
|
end
|
|
else
|
|
self:AddLeftLine(L["Identical Stats"], 1, 0.82, 0, false, nil, 2, TOOLTIP_PADDING);
|
|
end
|
|
|
|
local effectText, cached = API.GetItemEffect(info.equippedItemLink);
|
|
if not cached then
|
|
if not requery then
|
|
requery = true;
|
|
C_Timer.After(0.25, function()
|
|
self:ReTriggerOnEnter();
|
|
end);
|
|
end
|
|
end
|
|
if effectText then
|
|
local offset = nil; --TOOLTIP_PADDING
|
|
self:AddLeftLine(effectText, 0, 1, 0, false, nil, 2, offset);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
self:ProcessItemExternal(rewardItem);
|
|
|
|
if canCompare then
|
|
local description = shouldShowComparison and L["Hide Comparison"] or L["Show Comparison"];
|
|
self:ShowHotkey(HOTKEY_ALTERNATE_MODE, description, AlternateModeCallback_ItemComparison);
|
|
self:Show();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function SharedTooltip:SetOwner(owner, anchor, offsetX, offsetY)
|
|
if self.Init then
|
|
self:Init();
|
|
end
|
|
|
|
self.owner = owner;
|
|
anchor = anchor or "ANCHOR_BOTTOM";
|
|
offsetX = offsetX or 0;
|
|
offsetY = offsetY or 0;
|
|
|
|
self:ClearAllPoints();
|
|
|
|
if anchor == "ANCHOR_NONE" then
|
|
return
|
|
else
|
|
self:SetPoint("BOTTOMLEFT", owner, "TOPRIGHT", offsetX, offsetY);
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:ReTriggerOnEnter()
|
|
if self:IsVisible() and self.owner and self.owner.OnEnter and self.owner:IsShown() and self.owner:IsMouseOver() then
|
|
self.owner:OnEnter();
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:SetLineFont(fontString, sizeIndex)
|
|
if fontString.sizeIndex ~= sizeIndex then
|
|
fontString.sizeIndex = sizeIndex;
|
|
if sizeIndex == 1 then
|
|
fontString:SetFontObject(FONT_LARGE);
|
|
elseif sizeIndex == 2 then
|
|
fontString:SetFontObject(FONT_MEDIUM);
|
|
elseif sizeIndex == 3 then
|
|
fontString:SetFontObject(FONT_SMALL);
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:SetLineAlignment(fontString, alignIndex)
|
|
fontString.alignIndex = alignIndex;
|
|
if alignIndex == 1 then
|
|
fontString:SetJustifyH("LEFT");
|
|
elseif alignIndex == 2 then
|
|
fontString:SetJustifyH("CENTER");
|
|
elseif alignIndex == 3 then
|
|
fontString:SetJustifyH("RIGHT");
|
|
end
|
|
return true
|
|
end
|
|
|
|
function SharedTooltip:AcquireFontString()
|
|
local n = self.numFontStrings + 1;
|
|
self.numFontStrings = n;
|
|
|
|
if not self.fontStrings[n] then
|
|
self.fontStrings[n] = self.Content:CreateFontString(nil, "OVERLAY", FONT_MEDIUM);
|
|
self.fontStrings[n]:SetSpacing(SPACING_INTERNAL);
|
|
self.fontStrings[n].sizeIndex = 2;
|
|
self.fontStrings[n].alignIndex = 1;
|
|
self.fontStrings[n]:SetJustifyV("MIDDLE");
|
|
end
|
|
|
|
self.fontStrings[n].horizontalOffset = 0;
|
|
|
|
return self.fontStrings[n]
|
|
end
|
|
|
|
function SharedTooltip:AddText(text, r, g, b, wrapText, offsetY, sizeIndex, alignIndex, horizontalOffset)
|
|
r = r or 1;
|
|
g = g or 1;
|
|
b = b or 1;
|
|
wrapText = (wrapText == true) or false;
|
|
offsetY = offsetY or -SPACING_NEW_LINE;
|
|
sizeIndex = sizeIndex or 2;
|
|
alignIndex = alignIndex or 1;
|
|
horizontalOffset = horizontalOffset or 0;
|
|
|
|
local fs = self:AcquireFontString();
|
|
|
|
local fontChanged = self:SetLineFont(fs, sizeIndex);
|
|
if fontChanged then
|
|
self.fontChanged = true;
|
|
end
|
|
self:SetLineAlignment(fs, alignIndex);
|
|
|
|
fs:ClearAllPoints();
|
|
fs:SetPoint("TOPLEFT", self.Content, "TOPLEFT", 0, 0);
|
|
|
|
fs:SetWidth(FONTSTRING_MAX_WIDTH);
|
|
fs:SetText(text);
|
|
fs:SetTextColor(r, g, b, 1);
|
|
fs:Show();
|
|
fs.inGrid = nil;
|
|
fs.horizontalOffset = horizontalOffset;
|
|
|
|
return fs
|
|
end
|
|
|
|
function SharedTooltip:SetGridLine(row, col, text, r, g, b, sizeIndex, alignIndex)
|
|
if not text then return end
|
|
|
|
if self.grid[row] and self.grid[row][col] then
|
|
self.grid[row][col]:SetText("(Occupied)")
|
|
return
|
|
end
|
|
|
|
local fs = self:AddText(text, r, g, b, nil, nil, sizeIndex, alignIndex);
|
|
fs.inGrid = true;
|
|
|
|
if not self.grid[row] then
|
|
self.grid[row] = {};
|
|
end
|
|
self.grid[row][col] = fs;
|
|
|
|
if row > self.numLines then
|
|
self.numLines = row;
|
|
end
|
|
|
|
if col > self.numCols then
|
|
self.numCols = col;
|
|
end
|
|
|
|
self.useGridLayout = true;
|
|
end
|
|
|
|
function SharedTooltip:AddIcon(file, width, height, layer, sublevel)
|
|
local f = self.iconPool:Acquire();
|
|
f:ClearAllPoints();
|
|
f:SetPoint("TOPLEFT", self.Content, "TOPLEFT", 0, 0);
|
|
f:SetSize(width, height or width);
|
|
f:SetDrawLayer(layer or "OVERLAY", sublevel or 0);
|
|
f:SetTexture(file);
|
|
return f
|
|
end
|
|
|
|
function SharedTooltip:AddLeftLine(text, r, g, b, wrapText, offsetY, sizeIndex, horizontalOffset)
|
|
--This will start a new line
|
|
|
|
if (not text) or (text == "") then return end
|
|
local n = self.numLines + 1;
|
|
self.numLines = n;
|
|
|
|
local alignIndex = 1;
|
|
local fs = self:AddText(text, r, g, b, wrapText, offsetY, sizeIndex, alignIndex, horizontalOffset);
|
|
|
|
if not self.grid[n] then
|
|
self.grid[n] = {};
|
|
end
|
|
self.grid[n][1] = fs;
|
|
|
|
return fs
|
|
end
|
|
|
|
function SharedTooltip:AddCenterLine(text, r, g, b, wrapText, offsetY, sizeIndex)
|
|
--This will also start a new line
|
|
--Align to the center
|
|
|
|
if not text then return end
|
|
local n = self.numLines + 1;
|
|
self.numLines = n;
|
|
|
|
local alignIndex = 2;
|
|
local fs = self:AddText(text, r, g, b, wrapText, offsetY, sizeIndex, alignIndex);
|
|
|
|
if not self.grid[n] then
|
|
self.grid[n] = {};
|
|
end
|
|
self.grid[n][1] = fs;
|
|
|
|
return fs
|
|
end
|
|
|
|
function SharedTooltip:SetTitle(text, r, g, b)
|
|
self:AddLeftLine(text, r, g, b, true, nil, 1);
|
|
end
|
|
|
|
function SharedTooltip:AddRightLine(text, r, g, b, wrapText, offsetY, sizeIndex)
|
|
--Right line must come in pairs with a LeftLine
|
|
--This will NOT start a new line
|
|
|
|
if not text then return end
|
|
local alignIndex = 3;
|
|
local fs = self:AddText(text, r, g, b, wrapText, offsetY, sizeIndex, alignIndex);
|
|
local n = self.numLines;
|
|
|
|
if not self.grid[n] then
|
|
self.grid[n] = {};
|
|
end
|
|
self.grid[n][2] = fs;
|
|
|
|
self.numCols = 2;
|
|
|
|
return fs
|
|
end
|
|
|
|
function SharedTooltip:AddDoubleLine(leftText, rightText, leftR, leftG, leftB, rightR, rightG, rightB)
|
|
self:AddLeftLine(leftText, leftR, leftG, leftB);
|
|
self:AddRightLine(rightText, rightR, rightG, rightB);
|
|
end
|
|
|
|
function SharedTooltip:AddBlankLine()
|
|
local n = self.numLines + 1;
|
|
self.numLines = n;
|
|
self.grid[n] = {
|
|
gap = SPACING_NEW_LINE,
|
|
};
|
|
end
|
|
|
|
function SharedTooltip:AddColoredLine(text, colorGlobal)
|
|
local r, g, b;
|
|
if colorGlobal and colorGlobal.GetRGB then
|
|
r, g, b = colorGlobal:GetRGB();
|
|
else
|
|
r, g, b = 1, 1, 1;
|
|
end
|
|
self:AddLeftLine(text, r, g, b, true);
|
|
end
|
|
|
|
function SharedTooltip:ProcessInfo(info)
|
|
self.tooltipInfo = info;
|
|
|
|
if not info then
|
|
return false
|
|
end
|
|
|
|
local tooltipData;
|
|
if info.getterArgs then
|
|
tooltipData = C_TooltipInfo[info.getterName](unpack(info.getterArgs));
|
|
else
|
|
tooltipData = C_TooltipInfo[info.getterName]();
|
|
end
|
|
|
|
self:ClearLines();
|
|
self:SetScript("OnUpdate", nil);
|
|
|
|
if tooltipData then
|
|
tooltipData.isItem = info.isItem;
|
|
end
|
|
|
|
local success = self:ProcessTooltipData(tooltipData);
|
|
|
|
if success then
|
|
self:Show();
|
|
else
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:ReprocessInfo()
|
|
if self.tooltipData then
|
|
self:ClearLines();
|
|
self:ProcessTooltipData(self.tooltipData);
|
|
self:Show();
|
|
end
|
|
end
|
|
|
|
local OVERRIDE_COLORS = {
|
|
["ffa335ee"] = 4,
|
|
["ff0070dd"] = 3,
|
|
};
|
|
|
|
function SharedTooltip:ProcessTooltipData(tooltipData)
|
|
if not (tooltipData and tooltipData.lines) then
|
|
self.tooltipData = nil;
|
|
return false
|
|
end
|
|
|
|
self.tooltipData = tooltipData;
|
|
self.dataInstanceID = tooltipData.dataInstanceID;
|
|
self.hyperlink = tooltipData.hyperlink;
|
|
|
|
self:RegisterEvent("TOOLTIP_DATA_UPDATE");
|
|
|
|
local leftText, leftColor, wrapText, rightText, rightColor, leftOffset;
|
|
local r, g, b;
|
|
|
|
for i, lineData in ipairs(tooltipData.lines) do
|
|
leftText = lineData.leftText;
|
|
leftColor = lineData.leftColor or NORMAL_FONT_COLOR;
|
|
rightText = lineData.rightText;
|
|
wrapText = lineData.wrapText or false;
|
|
leftOffset = lineData.leftOffset;
|
|
|
|
if leftText then
|
|
if leftText == " "then
|
|
--A whole blank line is too tall, so we change its height
|
|
self:AddBlankLine();
|
|
else
|
|
if i == 1 then
|
|
local hex = leftColor:GenerateHexColor();
|
|
if OVERRIDE_COLORS[hex] then
|
|
leftColor = GetItemQualityColor( OVERRIDE_COLORS[hex] );
|
|
end
|
|
end
|
|
|
|
if lineData.price and lineData.price > 0 then
|
|
local colorized = true;
|
|
local cointText = API.GenerateMoneyText(lineData.price, colorized);
|
|
if cointText then
|
|
leftText = SELL_PRICE_TEXT .. cointText;
|
|
--self:AddBlankLine();
|
|
self:AddLeftLine(leftText, 1, 1, 1, false, nil, 2);
|
|
end
|
|
else --lineData.type ~= LINE_TYPE_PRICE
|
|
r, g, b = leftColor:GetRGB();
|
|
self:AddLeftLine(leftText, r, g, b, wrapText, nil, (i == 1 and 1) or 2);
|
|
end
|
|
|
|
if rightText then
|
|
rightColor = lineData.rightColor or NORMAL_FONT_COLOR;
|
|
r, g, b = rightColor:GetRGB();
|
|
self:AddRightLine(rightText, r, g, b, wrapText, nil, 2);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if tooltipData.isItem then
|
|
self:ShowItemComparison();
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local TOPLINE_MAX_ROW = 2;
|
|
|
|
function SharedTooltip:Layout()
|
|
local textWidth, textHeight, lineWidth;
|
|
local topLinesWidth;
|
|
local totalHeight = 0;
|
|
local maxLineWidth = 0;
|
|
local maxLineHeight = 0;
|
|
local grid = self.grid;
|
|
local fs;
|
|
local ref = self.Content;
|
|
local usePreviewModel = self.usePreviewModel;
|
|
|
|
local colMaxWidths, rowOffsetYs;
|
|
local numCols = self.numCols;
|
|
local useGridLayout = self.useGridLayout;
|
|
if useGridLayout then
|
|
colMaxWidths = {};
|
|
rowOffsetYs = {};
|
|
for i = 1, numCols do
|
|
colMaxWidths[i] = 0;
|
|
end
|
|
end
|
|
|
|
for row = 1, self.numLines do
|
|
if grid[row] then
|
|
lineWidth = 0;
|
|
maxLineHeight = 0;
|
|
if grid[row].gap then
|
|
--Positive value increase the distance between lines
|
|
totalHeight = totalHeight + grid[row].gap;
|
|
end
|
|
for col = 1, numCols do
|
|
fs = grid[row][col];
|
|
if fs then
|
|
if usePreviewModel and col == 1 and row <= 3 then
|
|
fs:SetWidth(FONTSTRING_MAX_WIDTH - FONTSTRING_SHRINK_IF_MODEL);
|
|
end
|
|
|
|
textWidth = fs:GetWrappedWidth() + fs.horizontalOffset;
|
|
textHeight = fs:GetHeight();
|
|
|
|
if fs.icon then
|
|
textWidth = textWidth + fs.icon:GetWidth() + (fs.icon.iconGap or 0);
|
|
textHeight = max(textHeight, fs.icon:GetHeight());
|
|
end
|
|
|
|
if col == 1 then
|
|
lineWidth = textWidth;
|
|
else
|
|
lineWidth = lineWidth + FONTSTRING_MIN_GAP + textWidth;
|
|
end
|
|
|
|
fs.lineWidth = lineWidth;
|
|
|
|
if lineWidth > maxLineWidth then
|
|
maxLineWidth = lineWidth;
|
|
end
|
|
|
|
if textHeight > maxLineHeight then
|
|
maxLineHeight = textHeight;
|
|
end
|
|
|
|
if useGridLayout and textWidth > colMaxWidths[col] and fs.inGrid then
|
|
colMaxWidths[col] = textWidth;
|
|
end
|
|
end
|
|
end
|
|
|
|
if row ~= 1 then
|
|
totalHeight = totalHeight + SPACING_NEW_LINE;
|
|
end
|
|
totalHeight = Round(totalHeight);
|
|
|
|
if useGridLayout then
|
|
rowOffsetYs[row] = -totalHeight;
|
|
else
|
|
local obj;
|
|
local iconGap;
|
|
|
|
for col = 1, numCols do
|
|
fs = grid[row][col];
|
|
if fs then
|
|
fs:ClearAllPoints();
|
|
|
|
if fs.icon then
|
|
obj = fs.icon;
|
|
obj:ClearAllPoints();
|
|
iconGap = fs.icon.iconGap or 0;
|
|
if fs.alignIndex == 2 then
|
|
fs:SetPoint("TOPLEFT", obj, "TOPRIGHT", iconGap, 0);
|
|
elseif fs.alignIndex == 3 then
|
|
fs:SetPoint("TOPRIGHT", obj, "TOPLEFT", -iconGap, 0);
|
|
else
|
|
fs:SetPoint("TOPLEFT", obj, "TOPRIGHT", iconGap, 0);
|
|
end
|
|
else
|
|
obj = fs;
|
|
end
|
|
|
|
if fs.alignIndex == 2 then
|
|
if fs.icon then
|
|
obj:SetPoint("TOPLEFT", ref, "TOP", -0.5*fs.lineWidth + fs.horizontalOffset, -totalHeight);
|
|
else
|
|
obj:SetPoint("TOP", ref, "TOP", 0 + fs.horizontalOffset, -totalHeight);
|
|
end
|
|
elseif fs.alignIndex == 3 then
|
|
obj:SetPoint("TOPRIGHT", ref, "TOPRIGHT", 0 + fs.horizontalOffset, -totalHeight);
|
|
else
|
|
obj:SetPoint("TOPLEFT", ref, "TOPLEFT", 0 + fs.horizontalOffset, -totalHeight);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
totalHeight = totalHeight + maxLineHeight;
|
|
totalHeight = Round(totalHeight);
|
|
end
|
|
|
|
if not topLinesWidth then
|
|
topLinesWidth = maxLineWidth;
|
|
elseif row <= TOPLINE_MAX_ROW then
|
|
if maxLineWidth > topLinesWidth then
|
|
topLinesWidth = maxLineWidth;
|
|
end
|
|
end
|
|
end
|
|
|
|
if useGridLayout then
|
|
local offsetX, offsetY;
|
|
for row = 1, self.numLines do
|
|
offsetX = 0;
|
|
offsetY = rowOffsetYs[row];
|
|
for col = 1, numCols do
|
|
fs = grid[row][col];
|
|
textWidth = colMaxWidths[col] + 1;
|
|
if fs then
|
|
fs:ClearAllPoints();
|
|
if fs.alignIndex == 2 then
|
|
if fs.inGrid then
|
|
fs:SetPoint("TOPLEFT", ref, "TOPLEFT", offsetX, offsetY);
|
|
fs:SetWidth(textWidth);
|
|
else
|
|
fs:SetPoint("TOP", ref, "TOP", offsetX, offsetY);
|
|
end
|
|
elseif fs.alignIndex == 3 then
|
|
if col == numCols then
|
|
fs:SetPoint("TOPRIGHT", ref, "TOPRIGHT", 0, offsetY);
|
|
else
|
|
fs:SetPoint("TOPLEFT", ref, "TOPLEFT", offsetX, offsetY);
|
|
fs:SetWidth(textWidth);
|
|
end
|
|
else
|
|
fs:SetPoint("TOPLEFT", ref, "TOPLEFT", offsetX, offsetY);
|
|
end
|
|
end
|
|
|
|
offsetX = offsetX + colMaxWidths[col] + FONTSTRING_MIN_GAP;
|
|
end
|
|
end
|
|
|
|
maxLineWidth = 0;
|
|
for col = 1, numCols do
|
|
maxLineWidth = maxLineWidth + colMaxWidths[col];
|
|
if col > 1 then
|
|
maxLineWidth = maxLineWidth + FONTSTRING_MIN_GAP;
|
|
end
|
|
end
|
|
end
|
|
|
|
local contentWidth = Round(maxLineWidth);
|
|
self.Content:SetWidth(contentWidth);
|
|
|
|
if usePreviewModel then
|
|
local modelWidth = self.DualModel:GetWidth();
|
|
topLinesWidth = topLinesWidth or 0;
|
|
topLinesWidth = topLinesWidth + modelWidth + TOOLTIP_PADDING;
|
|
contentWidth = max(topLinesWidth, maxLineWidth);
|
|
self:SetClampRectInsets(-4, 4, 56, -4);
|
|
else
|
|
self:SetClampRectInsets(-4, 4, 4, -4);
|
|
end
|
|
|
|
local fullWidth = Round(contentWidth) + 2*TOOLTIP_PADDING;
|
|
local fullHeight = Round(totalHeight) + 2*TOOLTIP_PADDING;
|
|
|
|
self:SetSize(fullWidth, fullHeight);
|
|
end
|
|
|
|
function SharedTooltip:SetFrameAlpha(alpha)
|
|
self:SetAlpha(alpha);
|
|
if self.DualModel then
|
|
self.DualModel:SetModelAlpha(alpha);
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:LoadTheme()
|
|
if self.Background then
|
|
self.Background:SetTexture(addon.ThemeUtil:GetTextureFile("TooltipBackground-Temp.png"));
|
|
end
|
|
|
|
if self.HotkeyFrame then
|
|
self.HotkeyFrame:LoadTheme();
|
|
end
|
|
end
|
|
|
|
local function SharedTooltip_OnUpdate_FadeIn(self, elapsed)
|
|
self.t = self.t + elapsed;
|
|
if self.t > 0 then
|
|
local alpha = 10*self.t;
|
|
if alpha >= 1 then
|
|
alpha = 1;
|
|
self.t = nil;
|
|
self:SetScript("OnUpdate", nil);
|
|
end
|
|
self:SetFrameAlpha(alpha);
|
|
else
|
|
self:SetFrameAlpha(0);
|
|
end
|
|
end
|
|
|
|
local function SharedTooltip_OnUpdate_Layout(self, elapsed)
|
|
self:SetScript("OnUpdate", nil);
|
|
self:Layout();
|
|
|
|
if self.showDelay then
|
|
self:SetScript("OnUpdate", SharedTooltip_OnUpdate_FadeIn);
|
|
end
|
|
end
|
|
|
|
|
|
function SharedTooltip:LayoutNextUpdate()
|
|
self:SetScript("OnUpdate", SharedTooltip_OnUpdate_Layout);
|
|
end
|
|
|
|
function SharedTooltip:Show()
|
|
local layoutComplete;
|
|
|
|
self:DisplayModel();
|
|
|
|
if self.fontChanged or self.useGridLayout then
|
|
--fontString width will take one frame to change
|
|
layoutComplete = false;
|
|
self:LayoutNextUpdate();
|
|
else
|
|
layoutComplete = true;
|
|
self:Layout();
|
|
end
|
|
|
|
if self.showDelay then
|
|
self.t = self.showDelay;
|
|
self:SetFrameAlpha(0);
|
|
if layoutComplete then
|
|
self:SetScript("OnUpdate", SharedTooltip_OnUpdate_FadeIn);
|
|
end
|
|
else
|
|
self.t = nil;
|
|
self:SetFrameAlpha(1);
|
|
end
|
|
|
|
self:ShowFrame();
|
|
end
|
|
|
|
function SharedTooltip:SetShowDelay(delay)
|
|
if delay and delay > 0 then
|
|
self.showDelay = -delay;
|
|
else
|
|
self.showDelay = nil;
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:Hide()
|
|
self:HideFrame();
|
|
self:ClearAllPoints();
|
|
self:SetScript("OnUpdate", nil);
|
|
self:ClearLines();
|
|
end
|
|
|
|
function SharedTooltip:OnEvent(event, ...)
|
|
if event == "TOOLTIP_DATA_UPDATE" then
|
|
local dataInstanceID = ...
|
|
if dataInstanceID and dataInstanceID == self.dataInstanceID then
|
|
self.triggeredByEvent = true;
|
|
self:ProcessInfo(self.tooltipInfo);
|
|
end
|
|
elseif event == "MODIFIER_STATE_CHANGED" then
|
|
local key, down = ...
|
|
if key == "LSHIFT" and down == 1 then
|
|
self:ToggleAlternateInfo();
|
|
end
|
|
end
|
|
end
|
|
|
|
SharedTooltip:SetScript("OnEvent", SharedTooltip.OnEvent);
|
|
|
|
SharedTooltip:SetScript("OnHide", function(self)
|
|
self:UnregisterEvent("TOOLTIP_DATA_UPDATE");
|
|
self:UnregisterEvent("MODIFIER_STATE_CHANGED");
|
|
self.tooltipInfo = nil;
|
|
self.tooltipData = nil;
|
|
end);
|
|
|
|
|
|
do
|
|
--Emulate the default GameTooltip
|
|
--Code from Interface/SharedXML/Tooltip/TooltipDataHandler.lua
|
|
|
|
local function AddTooltipDataAccessor(handler, accessor, getterName)
|
|
local isItem = string.find(getterName, "Item");
|
|
|
|
handler[accessor] = function(self, ...)
|
|
local tooltipInfo = {
|
|
getterName = getterName,
|
|
getterArgs = { ... };
|
|
isItem = (isItem ~= nil) or nil,
|
|
};
|
|
return self:ProcessInfo(tooltipInfo);
|
|
end
|
|
end
|
|
|
|
|
|
local accessors = {
|
|
SetItemByID = "GetItemByID",
|
|
SetCurrencyByID = "GetCurrencyByID",
|
|
SetQuestItem = "GetQuestItem",
|
|
SetQuestCurrency = "GetQuestCurrency",
|
|
SetSpellByID = "GetSpellByID",
|
|
SetItemByGUID = "GetItemByGUID",
|
|
SetHyperlink = "GetHyperlink",
|
|
};
|
|
|
|
local handler = SharedTooltip;
|
|
for accessor, getterName in pairs(accessors) do
|
|
AddTooltipDataAccessor(handler, accessor, getterName);
|
|
end
|
|
end
|
|
|
|
SharedTooltip:ClearLines();
|
|
|
|
function SharedTooltip:FormatIconText(icon, text)
|
|
return format(FORMAT_ICON_TEXT, icon, text);
|
|
end
|
|
|
|
function SharedTooltip:AddSimpleIconText(file, size, text, r, g, b)
|
|
size = size or FONT_HEIGHT_MEDIUM;
|
|
|
|
local icon = self:AddIcon(file, size, size, "OVERLAY", 0);
|
|
local fs = self:AddLeftLine(text, r, g, b, true);
|
|
|
|
fs.icon = icon;
|
|
icon.iconGap = SPACING_INTERNAL;
|
|
|
|
return fs
|
|
end
|
|
|
|
do
|
|
local C_Garrison = C_Garrison;
|
|
local NUM_ABILITIES = 4;
|
|
|
|
local function AddFollowerAbility(self, getterName, followerID, title)
|
|
local getterFunc = C_Garrison[getterName];
|
|
if not getterFunc then return end;
|
|
|
|
local titleAdded;
|
|
|
|
for index = 1, NUM_ABILITIES do
|
|
local abilityID = getterFunc(followerID, index);
|
|
if (not abilityID) or (abilityID == 0) then
|
|
break
|
|
end
|
|
if not titleAdded then
|
|
titleAdded = true;
|
|
self:AddLeftLine(title, 1, 0.82, 0);
|
|
end
|
|
|
|
local ability = C_Garrison.GetFollowerAbilityInfo(abilityID);
|
|
local abilityName = ability.name;
|
|
if ability.icon then
|
|
abilityName = self:FormatIconText(ability.icon, abilityName);
|
|
end
|
|
|
|
local sizeIndex = 1;
|
|
self:AddLeftLine(abilityName, 1, 0.82, 0, false, nil, sizeIndex);
|
|
|
|
if ability.description then
|
|
local descriptionOffset = 16;
|
|
self:AddLeftLine(ability.description, 1, 1, 1, true, nil, 2, descriptionOffset);
|
|
end
|
|
end
|
|
end
|
|
|
|
function SharedTooltip:SetFollowerByID(followerID)
|
|
local info = C_Garrison.GetFollowerInfo(followerID);
|
|
|
|
if not info then
|
|
return false
|
|
end
|
|
|
|
self:ClearLines();
|
|
self:SetScript("OnUpdate", nil);
|
|
|
|
local name = info.name;
|
|
self:SetTitle(name, 1, 0.82, 0);
|
|
|
|
if info.level and info.className then
|
|
local title = format(L["Format Follower Level Class"], info.level, info.className);
|
|
self:AddLeftLine(title, 1, 1, 1);
|
|
end
|
|
|
|
local abilities = C_Garrison.GetFollowerAbilities(followerID)
|
|
|
|
if abilities and #abilities > 0 then
|
|
AddFollowerAbility(self, "GetFollowerAbilityAtIndexByID", followerID, L["Abilities"])
|
|
AddFollowerAbility(self, "GetFollowerTraitAtIndexByID", followerID, L["Traits"])
|
|
end
|
|
|
|
--print(followerID);
|
|
|
|
self:Show();
|
|
return true
|
|
end
|
|
end
|
|
|
|
do
|
|
--Emulate for Classic
|
|
local function TOOLTIP_DATA_UPDATE(dataInstanceID)
|
|
if SharedTooltip:IsVisible() then
|
|
if dataInstanceID and dataInstanceID == SharedTooltip.dataInstanceID and SharedTooltip.tooltipInfo and SharedTooltip.tooltipData then
|
|
SharedTooltip.triggeredByEvent = true;
|
|
local oldData = SharedTooltip.tooltipData;
|
|
local newData;
|
|
local info = SharedTooltip.tooltipInfo;
|
|
if info.getterArgs then
|
|
newData = C_TooltipInfo[info.getterName](unpack(info.getterArgs));
|
|
else
|
|
newData = C_TooltipInfo[info.getterName]();
|
|
end
|
|
if newData and oldData.lines and newData.lines and (#oldData.lines ~= #newData.lines) then
|
|
SharedTooltip:ClearLines();
|
|
SharedTooltip:SetScript("OnUpdate", nil);
|
|
|
|
newData.isItem = oldData.isItem;
|
|
|
|
local success = SharedTooltip:ProcessTooltipData(newData);
|
|
|
|
if success then
|
|
SharedTooltip:Show();
|
|
else
|
|
SharedTooltip:Hide();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
addon.CallbackRegistry:Register("SharedTooltip.TOOLTIP_DATA_UPDATE", TOOLTIP_DATA_UPDATE);
|
|
end
|
|
|
|
|
|
do
|
|
local function PostFontSizeChanged()
|
|
if SharedTooltip.HotkeyFrame then
|
|
SharedTooltip.HotkeyFrame:UpdateBaseHeight();
|
|
end
|
|
|
|
local _;
|
|
_, FONT_HEIGHT_MEDIUM = _G[FONT_MEDIUM]:GetFont();
|
|
FONT_HEIGHT_MEDIUM = Round(FONT_HEIGHT_MEDIUM);
|
|
end
|
|
addon.CallbackRegistry:Register("PostFontSizeChanged", PostFontSizeChanged);
|
|
|
|
local function PostInputDeviceChanged(dbValue)
|
|
if SharedTooltip.HotkeyFrame then
|
|
SharedTooltip.HotkeyFrame:UpdateBaseHeight();
|
|
end
|
|
end
|
|
addon.CallbackRegistry:Register("PostInputDeviceChanged", PostInputDeviceChanged);
|
|
end
|
|
|
|
|
|
do --DEBUG
|
|
--[[
|
|
local f = CreateFrame("Frame", "NTT", nil);
|
|
f:SetSize(100, 100);
|
|
f:SetPoint("CENTER", UIParent, "CENTER", 0, 0);
|
|
|
|
local function Setup()
|
|
local pieces = {};
|
|
local cornerSize = 32;
|
|
local offset = cornerSize * 0.5;
|
|
local file = "Interface/AddOns/DialogueUI/Art/Tooltip_Debug";
|
|
|
|
local function CreatePiece()
|
|
local tex = f:CreateTexture(nil, "BACKGROUND");
|
|
table.insert(pieces, tex);
|
|
tex:SetSize(cornerSize, cornerSize);
|
|
|
|
tex:SetTexture(file)
|
|
return tex
|
|
end
|
|
|
|
f.P1 = CreatePiece();
|
|
f.P1:SetPoint("TOPLEFT", f, "TOPLEFT", -offset, offset);
|
|
f.P1:SetTexCoord(0, 0.25, 0, 0.25);
|
|
|
|
f.P3 = CreatePiece();
|
|
f.P3:SetPoint("TOPRIGHT", f, "TOPRIGHT", offset, offset);
|
|
f.P3:SetTexCoord(0.75, 1, 0, 0.25);
|
|
|
|
f.P7 = CreatePiece();
|
|
f.P7:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", -offset, -offset);
|
|
f.P7:SetTexCoord(0, 0.25, 0.75, 1);
|
|
|
|
f.P9 = CreatePiece();
|
|
f.P9:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", offset, -offset);
|
|
f.P9:SetTexCoord(0.75, 1, 0.75, 1);
|
|
|
|
f.P2 = CreatePiece();
|
|
f.P2:SetPoint("TOPLEFT", f.P1, "TOPRIGHT", 0, 0);
|
|
f.P2:SetPoint("BOTTOMRIGHT", f.P3, "BOTTOMLEFT", 0, 0);
|
|
f.P2:SetHorizTile(true);
|
|
f.P2:SetVertTile(false);
|
|
f.P2:SetTexture(file)
|
|
f.P2:SetTexCoord(0.25, 0.75, 0, 0.25);
|
|
|
|
f.P4 = CreatePiece();
|
|
f.P4:SetPoint("TOPLEFT", f.P1, "BOTTOMLEFT", 0, 0);
|
|
f.P4:SetPoint("BOTTOMRIGHT", f.P7, "TOPRIGHT", 0, 0);
|
|
f.P4:SetTexCoord(0, 0.25, 0.25, 0.75);
|
|
f.P4:SetVertTile(true);
|
|
|
|
f.P6 = CreatePiece();
|
|
f.P6:SetPoint("TOPLEFT", f.P3, "BOTTOMLEFT", 0, 0);
|
|
f.P6:SetPoint("BOTTOMRIGHT", f.P9, "TOPRIGHT", 0, 0);
|
|
f.P6:SetTexCoord(0.75, 1, 0.25, 0.75);
|
|
f.P6:SetVertTile(true);
|
|
|
|
f.P8 = CreatePiece();
|
|
f.P8:SetPoint("TOPLEFT", f.P7, "TOPRIGHT", 0, 0);
|
|
f.P8:SetPoint("BOTTOMRIGHT", f.P9, "BOTTOMLEFT", 0, 0);
|
|
f.P8:SetTexCoord(0.25, 0.75, 0.75, 1);
|
|
f.P8:SetHorizTile(true);
|
|
|
|
f.P5 = CreatePiece();
|
|
f.P5:SetPoint("TOPLEFT", f.P1, "BOTTOMRIGHT", 0, 0);
|
|
f.P5:SetPoint("BOTTOMRIGHT", f.P9, "TOPLEFT", 0, 0);
|
|
f.P5:SetHorizTile(true);
|
|
f.P5:SetVertTile(true);
|
|
f.P5:SetTexCoord(0.25, 0.75, 0.25, 0.75);
|
|
end
|
|
--]]
|
|
|
|
--C_Timer.After(1, Setup);
|
|
end
|