Thread Tools Display Modes
12-31-14, 08:36 PM   #1
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Hyperlink Tooltip Help

This code has been around for a while and (first found it with NeavUI) but it seems to wrk for most item links except battle pets is there something im missing? Does a battle pet link have it own link style?

In this first image you will notice the mouseover is working. ( I also have fstack enabled to see what the difference in links are)


In this second image I linked a battle pet in the "say" channel and no tooltip. (again fstack is enabled)


Here is the current code I am using:
Code:
		local _G = getfenv(0)
		local orig1, orig2 = {}, {}
		local GameTooltip = GameTooltip

		local linktypes = {
			achievement  = true,
			enchant      = true,
			glyph        = true,
			item         = true,
			instancelock = true,
			quest        = true,
			spell        = true,
			talent       = true,
			unit         = true,
		}

		local function OnHyperlinkEnter(frame, link, ...)
			local linktype = link:match('^([^:]+)')
			if (linktype and linktypes[linktype]) then
				GameTooltip:SetOwner(ChatFrame1, 'ANCHOR_CURSOR', 0, 20)
				GameTooltip:SetHyperlink(link)
				GameTooltip:Show()
			else
				GameTooltip:Hide()
			end

			if (orig1[frame]) then 
				return orig1[frame](frame, link, ...) 
			end
		end

		local function OnHyperlinkLeave(frame, ...)
			GameTooltip:Hide()

			if (orig2[frame]) then 
				return orig2[frame](frame, ...) 
			end
		end

		local function EnableItemLinkTooltip()
			for _, v in pairs(CHAT_FRAMES) do
				local chat = _G[v]
				if (chat and not chat.URLCopy) then
					orig1[chat] = chat:GetScript('OnHyperlinkEnter')
					chat:SetScript('OnHyperlinkEnter', OnHyperlinkEnter)

					orig2[chat] = chat:GetScript('OnHyperlinkLeave')
					chat:SetScript('OnHyperlinkLeave', OnHyperlinkLeave)
					chat.URLCopy = true
				end
			end
		end
		hooksecurefunc('FCF_OpenTemporaryWindow', EnableItemLinkTooltip)
		EnableItemLinkTooltip()
I noticed in the code that linktypes does not have battlepet or any reference to pets so im thinking that might be my issue but what name would I use to get this to work?

Thanks
Coke
  Reply With Quote
01-01-15, 12:34 AM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Battle pets have their own tooltip object; they don't use the GameTooltip at all. Battle pet abilities, garrison followers, follower abilities, and missions also have their own tooltips objects. You can see how the default UI handles those here, though really it would be a lot easier to just call the click function on mouseover instead of recreating it:

Code:
chat:HookScript('OnHyperlinkEnter', ChatFrame_OnHyperlinkShow)
If you wanted to filter out certain types of links, and/or not have it treat "mouseover while shift is down" as a shift-click, then this would still be simpler:

Code:
local linktypes = {
	-- These use GameTooltip:
	achievement    = true,
	enchant        = true,
	glyph          = true,
	item           = true,
	instancelock   = true,
	quest          = true,
	spell          = true,
	talent         = true,
	unit           = true,
	-- This uses FloatingBattlePetTooltip:
	battlepet      = true,
	-- This uses FloatingPetBattleAbilityTooltip:
	battlePetAbil = true,
	-- This uses FloatingGarrisonFollowerTooltip:
	garrfollower  = true,
	-- This uses FloatingGarrisonFollowerAbilityTooltip:
	garrfollowerability = true,
	-- This uses FloatingGarrisonMissionTooltip:
	garrmission   = true,
}

local function OnHyperlinkEnter(frame, link, text)
	local linkType = strsplit(":", link)
	if linktypes[linktype] and not IsModifiedClick() then
		ChatFrame_OnHyperlinkShow(frame, link, text, "LeftButton")
	end
end

chat:HookScript('OnHyperlinkEnter', OnHyperlinkEnter)
Remember to update your OnHyperlinkLeave script to also hide those additional tooltip objects.

Also you can just use HookScript instead of manually storing and replacing and calling the original script. If there is no original script then HookScript behaves exactly like SetScript.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 01-01-15 at 12:50 AM.
  Reply With Quote
01-01-15, 09:56 AM   #3
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Code:
chat:HookScript('OnHyperlinkEnter', ChatFrame_OnHyperlinkShow)
The above code works when I add it to my "local function ModChat(self)" but the whole point of the "mouseover tooltip is to have it show and hide with mouseover, this shows the tooltip but then you need to click the x to close it.

Originally Posted by Phanx View Post
If you wanted to filter out certain types of links, and/or not have it treat "mouseover while shift is down" as a shift-click, then this would still be simpler:

Code:
local linktypes = {
	-- These use GameTooltip:
	achievement    = true,
	enchant        = true,
	glyph          = true,
	item           = true,
	instancelock   = true,
	quest          = true,
	spell          = true,
	talent         = true,
	unit           = true,
	-- This uses FloatingBattlePetTooltip:
	battlepet      = true,
	-- This uses FloatingPetBattleAbilityTooltip:
	battlePetAbil = true,
	-- This uses FloatingGarrisonFollowerTooltip:
	garrfollower  = true,
	-- This uses FloatingGarrisonFollowerAbilityTooltip:
	garrfollowerability = true,
	-- This uses FloatingGarrisonMissionTooltip:
	garrmission   = true,
}

local function OnHyperlinkEnter(frame, link, text)
	local linkType = strsplit(":", link)
	if linktypes[linktype] and not IsModifiedClick() then
		ChatFrame_OnHyperlinkShow(frame, link, text, "LeftButton")
	end
end

chat:HookScript('OnHyperlinkEnter', OnHyperlinkEnter)
Tried this also and nothing happened no tooltip show or anything.

Originally Posted by Phanx View Post
Remember to update your OnHyperlinkLeave script to also hide those additional tooltip objects.
Again tried this and got nothing.

So this is what I tried and didn't get to work:

Code:
                local _G = getfenv(0)
		local orig1, orig2 = {}, {}

		local linktypes = {
			-- These use GameTooltip:
			achievement    = true,
			enchant        = true,
			glyph          = true,
			item           = true,
			instancelock   = true,
			quest          = true,
			spell          = true,
			talent         = true,
			unit           = true,
			-- This uses FloatingBattlePetTooltip:
			battlepet      = true,
			-- This uses FloatingPetBattleAbilityTooltip:
			battlePetAbil = true,
			-- This uses FloatingGarrisonFollowerTooltip:
			garrfollower  = true,
			-- This uses FloatingGarrisonFollowerAbilityTooltip:
			garrfollowerability = true,
			-- This uses FloatingGarrisonMissionTooltip:
			garrmission   = true,
		}

		local function OnHyperlinkEnter(frame, link, ...)
			
			for _, tooltip in pairs({	
				'GameTooltip',
				'FloatingBattlePetTooltip',
				'FloatingPetBattleAbilityTooltip',
				'FloatingGarrisonFollowerTooltip',
				'FloatingGarrisonFollowerAbilityTooltip',
				'FloatingGarrisonMissionTooltip',			
			}) do
			        local linktype = link:match('^([^:]+)')
			        if (linktype and linktypes[linktype]) then				
					tooltip:SetOwner(ChatFrame1, 'ANCHOR_CURSOR', 0, 20)
					tooltip:SetHyperlink(link)
					tooltip:Show()				
				else
					tooltip:Hide()
				end
			end

			if (orig1[frame]) then 
				return orig1[frame](frame, link, ...) 
			end
		end

		local function OnHyperlinkLeave(frame, ...)
			for _, tooltip in pairs({		
				'GameTooltip',
				'FloatingBattlePetTooltip',
				'FloatingPetBattleAbilityTooltip',
				'FloatingGarrisonFollowerTooltip',
				'FloatingGarrisonFollowerAbilityTooltip',
				'FloatingGarrisonMissionTooltip',			
			}) do
				tooltip:Hide()
			end
			
			if (orig2[frame]) then 
				return orig2[frame](frame, ...) 
			end
		end

		local function EnableItemLinkTooltip()
			for _, v in pairs(CHAT_FRAMES) do
				local chat = _G[v]
				if (chat) then
					orig1[chat] = chat:GetScript('OnHyperlinkEnter')
					chat:HookScript('OnHyperlinkEnter', OnHyperlinkEnter)

					orig2[chat] = chat:GetScript('OnHyperlinkLeave')
					chat:HookScript('OnHyperlinkLeave', OnHyperlinkLeave)
				end
			end
		end
		hooksecurefunc('FCF_OpenTemporaryWindow', EnableItemLinkTooltip)
		EnableItemLinkTooltip()
Am I looking at this totally wrong?

Coke
  Reply With Quote
01-01-15, 10:31 AM   #4
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
so I figured it out (kinda on my own :P)

in Phanx's original code the linkType the T was no capitalized in the function code so it was not finding the table.
Code:
		local linktypes = {
			-- These use GameTooltip:
			achievement    = true,
			enchant        = true,
			glyph          = true,
			item           = true,
			instancelock   = true,
			quest          = true,
			spell          = true,
			talent         = true,
			unit           = true,
			-- This uses FloatingBattlePetTooltip:
			battlepet      = true,
			-- This uses FloatingPetBattleAbilityTooltip:
			battlePetAbil = true,
			-- This uses FloatingGarrisonFollowerTooltip:
			garrfollower  = true,
			-- This uses FloatingGarrisonFollowerAbilityTooltip:
			garrfollowerability = true,
			-- This uses FloatingGarrisonMissionTooltip:
			garrmission   = true,
		}

		local function OnHyperlinkEnter(frame, link, text)
			local linkType = strsplit(":", link)
			if linktypes[linkType] and not IsModifiedClick() then
				ChatFrame_OnHyperlinkShow(frame, link, text, "LeftButton")
			end
		end	
		
		local function OnHyperlinkLeave(frame, link, text)
			local linkType = strsplit(":", link)
			if linktypes[linkType] and not IsModifiedClick() then
				ChatFrame_OnHyperlinkShow(frame, link, text, "LeftButton")
			end
		end		
		
		local function ModChat(self)
			local chat = _G[self]


			chat:HookScript('OnHyperlinkEnter', OnHyperlinkEnter)
			chat:HookScript('OnHyperlinkLeave', OnHyperlinkLeave)
               end
Now mouse over shows and hides.

Coke

Last edited by cokedrivers : 01-01-15 at 10:43 AM.
  Reply With Quote
01-01-15, 10:47 AM   #5
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
That works too, but your last attempt didn't work because you were using some awful table-creating Frankenstein instead of the code I posted.

(1) When you use HookScript you should not manually capture and call the original script -- if you do that, it will be called twice, once before your script, and once from inside your script. If the original method toggles something, then calling it twice is like not calling it at all.

(2) You were looping over a list of string values and trying to call frame methods on them. This would generate a Lua error telling you exactly what and where the problem was. I know I've told you before -- go get an error display addon and use it!

(3) Even if you fixed #2, you'd still be attempting to show every tooltip object at the same time, which doesn't even make sense, because...

(4) You'd also be calling methods like SetOwner and SetHyperlink on objects that do not have those methods. Battle pet and garrison related tooltips are not GameTooltip-type objects, and cannot display arbitrary hyperlinks.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
01-01-15, 11:06 AM   #6
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
is there a SetPoint I can use to have the tooltip for the hyperlink show above my chatframe instead of above my mainmenubar?

I guess what im asking is were would I put this code:

Code:
	local i
	for i = 1, NUM_CHAT_WINDOWS do
               tooltip:SetPoint("TOP", _G["ChatFrame"..i], 0, 20)
        end
or ami totally off base here?

Coke
  Reply With Quote
01-01-15, 11:12 AM   #7
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
(2) You were looping over a list of string values and trying to call frame methods on them. This would generate a Lua error telling you exactly what and where the problem was. I know I've told you before -- go get an error display addon and use it!
I do have Bugger and Bugsack installed an have them on at all times. I just didn't post the errors because like you posted in [4] it was throwing errors for SetOwner and Hide.

And believe it or not Phanx I listen to everything you have to say on coding, It might not sink in for the first few attempts or tries but in the end all my code seems to have the Phanx Seal of Approval because it is how you have written it.

Coke
  Reply With Quote
10-27-16, 11:38 PM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Try changing this:
Code:
        local function OnHyperlinkEnter(frame, linkData, link)
            local normal = showLinkType[linkData:match("^(.-):")]
to this:
Code:
        local function OnHyperlinkEnter(frame, link, text)
            local normal = showLinkType[link:match("(%a+):%d+")]
and this:
Code:
        local function OnHyperlinkLeave(frame, linkData, link)
            local normal = showLinkType[linkData:match("^(.-):")]
to this:
Code:
        local function OnHyperlinkLeave(frame, link, text)
            local normal = showLinkType[link:match("(%a+):%d+")]
and both instances of this:
Code:
                SetItemRef(linkData, link, "LeftButton", frame)
to this:
Code:
                SetItemRef(link, text, "LeftButton", frame)
The variable name changes are probably not strictly necessary (just the string.match argument change) but I'm just using the same names and techniques Blizzard is now using so I don't have to load the game client and test anything to figure out what actually changed.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-28-16, 01:20 PM   #9
Tonyleila
A Molten Giant
 
Tonyleila's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 758
Thanks for the reply Phanx! I think I made exactly the changes you posted but I still get exactly the same error, so I guess its something different going on here. I also disable all other addons.
Code:
13x LinkHover\LinkHover-1.6.lua:34: attempt to index local 'link' (a nil value)
LinkHover\LinkHover-1.6.lua:34: in function <LinkHover\LinkHover.lua:33>

.........
New code:

Lua Code:
  1. local showLinkType = {
  2.             -- Normal tooltip things:
  3.             achievement  = true,
  4.             enchant      = true,
  5.             glyph        = true,
  6.             item         = true,
  7.             instancelock = true,
  8.             quest        = true,
  9.             spell        = true,
  10.             talent       = true,
  11.             unit         = true,
  12.             currency       = true,
  13.             -- Special tooltip things:
  14.             battlepet           = false,
  15.             battlePetAbil       = false,
  16.             garrfollowerability = false,
  17.             garrfollower        = false,
  18.             garrmission         = false,
  19.         }
  20.          
  21.         local function OnHyperlinkEnter(frame, link, text)
  22.             local normal = showLinkType[link:match("(%a+):%d+")]
  23.             if normal == true then
  24.                 GameTooltip:SetOwner(ChatFrame1Tab, "ANCHOR_TOPLEFT", 20, 20)
  25.                 GameTooltip:SetHyperlink(link)
  26.                 GameTooltip:Show()
  27.             elseif normal == false then
  28.                 -- Uses a special tooltip, just let the default function handle it.
  29.                 SetItemRef(link, text, "LeftButton", frame)
  30.             end
  31.         end
  32.      
  33.         local function OnHyperlinkLeave(frame, link, text)
  34.             local normal = showLinkType[link:match("(%a+):%d+")]
  35.             if normal == true then
  36.                 GameTooltip:Hide()
  37.             elseif normal == false then
  38.                 -- Uses a special tooltip, just let the default function handle it.
  39.                 SetItemRef(link, text, "LeftButton", frame)
  40.             end
  41.         end
  42.          
  43.         local function RegisterFrame(frame)
  44.             frame:SetScript("OnHyperlinkEnter", OnHyperlinkEnter)
  45.             frame:SetScript("OnHyperlinkLeave", OnHyperlinkLeave)
  46.         end
  47.          
  48.         local f = CreateFrame("Frame")
  49.         f:RegisterEvent("PLAYER_LOGIN")
  50.         f:SetScript("OnEvent", function(self, event, name)
  51.             if event == "PLAYER_LOGIN" then
  52.                 for i = 1, NUM_CHAT_WINDOWS do
  53.                     RegisterFrame(_G["ChatFrame"..i])
  54.                 end
  55.             end
  56.             if GuildBankMessageFrame then
  57.                 RegisterFrame(GuildBankMessageFrame)
  58.                 self:UnregisterAllEvents()
  59.                 self:SetScript("OnEvent", nil)
  60.                 RegisterFrame = nil
  61.             else
  62.                 self:RegisterEvent("ADDON_LOADED")
  63.             end
  64.         end)
__________________
Author of: LeilaUI and Aurora: Missing Textures
__________________

Last edited by Tonyleila : 10-28-16 at 01:23 PM.
  Reply With Quote
10-29-16, 02:30 PM   #10
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Replace:

Code:
local function OnHyperlinkLeave(frame, link, text)
with:

Code:
local function OnHyperlinkLeave(...)
    return print("OnHyperlinkLeave", ...)
Mouse over a link, then off, then post the printout you get in the chat frame.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-30-16, 07:46 AM   #11
Tonyleila
A Molten Giant
 
Tonyleila's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 758
Originally Posted by Phanx View Post
Replace:

Code:
local function OnHyperlinkLeave(frame, link, text)
with:

Code:
local function OnHyperlinkLeave(...)
    return print("OnHyperlinkLeave", ...)
Mouse over a link, then off, then post the printout you get in the chat frame.
That code did not work but I replaced it with this:

Lua Code:
  1. local function OnHyperlinkLeave(...)
  2.             if true then --debug
  3.                 return print("OnHyperlinkLeave", ...)
  4.             end
  5.             if normal == true then
  6.                 GameTooltip:Hide()
  7.             elseif normal == false then
  8.                 -- Uses a special tooltip, just let the default function handle it.
  9.                 SetItemRef(link, text, "LeftButton", frame)
  10.             end
  11.         end

and got this chat printout:
Code:
OnHyperlinkLeave table: 00000165D37D7F7
reloaded UI and disabled all addons new chat print:
Code:
OnHyperlinkLeave table: 00000165D35AEEA0
Tested it and it changes ever time.
__________________
Author of: LeilaUI and Aurora: Missing Textures
__________________

Last edited by Tonyleila : 10-30-16 at 07:51 AM.
  Reply With Quote
10-31-16, 04:13 AM   #12
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
That means it's only receiving the "self" argument, without any information about the link. You'll have to keep track of that yourself:

Code:
        local lastLink, lastText, useGameTooltip

        local function OnHyperlinkEnter(frame, link, text)
            lastLink, lastText, useGameTooltip = link, text, showLinkType[link:match("(%a+):%d+")]
            if useGameTooltip then
                GameTooltip:SetOwner(ChatFrame1Tab, "ANCHOR_TOPLEFT", 20, 20)
                GameTooltip:SetHyperlink(link)
                GameTooltip:Show()
            elseif useGameTooltip == false then
                -- Uses a special tooltip, just let the default function handle it.
                SetItemRef(link, text, "LeftButton", frame)
            end
        end
     
        local function OnHyperlinkLeave(frame)
            if useGameTooltip then
                GameTooltip:Hide()
            elseif useGameTooltip == false then
                -- Uses a special tooltip, just let the default function handle it.
                SetItemRef(lastLink, lastText, "LeftButton", frame)
            end
            lastLink, lastText, lastLinkIsNormal = nil, nil, nil
        end
Green lines are new. Yellow lines are changed. A few lines were removed, too. (On a side note, you can just do "if X then" instead of "if X == true then" if your only need to to make sure X isn't false or nil.)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 10-31-16 at 04:17 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Hyperlink Tooltip Help


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off