Thread Tools Display Modes
09-29-16, 09:51 AM   #1
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Anchoring tooltip to mouse

Hello, I'm looking to anchor tooltips to mouse.

I want them to anchor to the mouse cursor at their bottom-right corner.
Exactly like this, pretty much:


The addon TipTac can do what I want, but it has lots and lots of other features that I really don't want (along with some stuff that just causes issues in general), so I'm trying to extract the code responsible for re-anchoring the tooltips, so I can have an addon that -only- re-anchors the tooltips, and nothing else.

Looking at TipTac's code, I've found that those are the functions for it:

Code:
-- Function to loop through tips to modify and hook
function tt:HookTips()
	-- Need to be called as late as possible during load, as we want to try and be the last addon to hook "OnTooltipSetUnit" so we always have a "completed" tip to work on
	gtt:HookScript("OnShow",GTTHook_OnShow);
	gtt:HookScript("OnUpdate",GTTHook_OnUpdate);
	gtt:HookScript("OnTooltipSetUnit",GTTHook_OnTooltipSetUnit);
	gtt:HookScript("OnTooltipCleared",GTTHook_OnTooltipCleared);
	-- HOOK: OnHide & OnTooltipSetItem Scripts
	for index, tipName in ipairs(TT_TipsToModify) do
		local tip = (_G[tipName] or false);	-- don't want to nil out an entry
		-- Here we make sure not to add duplicate items. This can happen for thing like AtlasLoot, which sets AtlasLootTooltip = GameTooltip
		if (tip) then
			for i = 1, index - 1 do
				if (tip == TT_TipsToModify[i]) then
					tip = false;
					break;
				end
			end
		end
		-- Set string index to table or false
		TT_TipsToModify[index] = tip;
		if (type(tip) == "table") and (type(tip.GetObjectType) == "function") then
			tip:HookScript("OnHide",TipHook_OnHide);
		end
	end
	-- Replace GameTooltip_SetDefaultAnchor (For Re-Anchoring) -- Patch 3.2 made this function secure for some reason
	hooksecurefunc("GameTooltip_SetDefaultAnchor",function(tooltip,parent)
		-- Return if no tooltip or parent
		if (not tooltip or not parent) then
			return;
		end
		-- Position Tip to Normal, Mouse or Parent anchor
		gtt_anchorType, gtt_anchorPoint = GetAnchorPosition();
		tooltip:SetOwner(parent,"ANCHOR_NONE");
		tooltip:ClearAllPoints();
		if (gtt_anchorType == "mouse") then
			tt:AnchorFrameToMouse(tooltip);
		elseif (gtt_anchorType == "parent") then
			tooltip:SetPoint(TT_MirrorAnchorsSmart[gtt_anchorPoint] or TT_MirrorAnchors[gtt_anchorPoint],parent,gtt_anchorPoint);
		else
			tooltip:SetPoint(gtt_anchorPoint,tt);
		end
		tooltip.default = 1;
	end);
	-- Clear this function as it's not needed anymore
	self.HookTips = nil;
end
Code:
-- Anchor any given frame to mouse position
function tt:AnchorFrameToMouse(frame)
	local x, y = GetCursorPosition();
	local effScale = frame:GetEffectiveScale();
	frame:ClearAllPoints();
	frame:SetPoint(gtt_anchorPoint,UIParent,"BOTTOMLEFT",(x / effScale + cfg.mouseOffsetX),(y / effScale + cfg.mouseOffsetY));
end
I've pruned out the stuff I didn't need, and came up with this:

Code:
local function AnchorFrameToMouse(frame)
	local x, y = GetCursorPosition()
	local effScale = frame:GetEffectiveScale()
	frame:ClearAllPoints()
	frame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMLEFT", (x / effScale), (y / effScale))
end

hooksecurefunc("GameTooltip_SetDefaultAnchor", function(tooltip, parent)
	tooltip:SetOwner(parent, "ANCHOR_CURSOR")
	tooltip:ClearAllPoints()
	AnchorFrameToMouse(tooltip)
	tooltip.default = 1
end)
Actually works surprisingly well, I'm somehow not getting that bug where tooltips appear for a split second at their previous location before jumping over to my mouse (was always struggling with that every time I tried to anchor tooltip to mouse).
The tooltips show up at my cursor's location when I mouse over something and they instantly hide when I move it away, which is good because I don't want any fadeout timer stuff, I want it to disappear right away when I mouse away.

There's one problem, though. When I move my cursor around, the tooltip follows my cursor on the X-axis, but its Y positioning doesn't update, and I really have no idea why it does that.

https://gfycat.com/SoggyDenseFlamingo

I feel like I must be missing something really obvious, but what?
Any help would be appreciated. :s

Edit: I just figured out that if I set the anchor to just "BOTTOM" instead of "BOTTOMRIGHT", things work as expected, except of course my cursor is at the bottom-center of my tooltip instead of bottom-right like I want it.

Last edited by Ammako : 09-29-16 at 09:57 AM.
  Reply With Quote
09-29-16, 10:43 AM   #2
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
This works for me:
Code:
local function setPoint(self)
	local scale = self:GetEffectiveScale()
	local x, y = GetCursorPosition()
	self:ClearAllPoints()
	self:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMLEFT", x / scale, y / scale)
end

hooksecurefunc("GameTooltip_SetDefaultAnchor", function(tooltip, parent)
	tooltip:SetOwner(parent, "ANCHOR_CURSOR")
	setPoint(tooltip)
	tooltip.default = 1
end)
Not sure why yours wouldn't.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
09-29-16, 10:56 AM   #3
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Yeah I'm not sure why, if it works for you, cause that exact code you just gave me has the same problem, even if I have absolutely no other add-ons running.
  Reply With Quote
09-29-16, 11:09 AM   #4
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Well I did try it on PTR, but I doubt anything's changed there.

This is the code I've used on live for years:
Code:
local function setPoint(self)
	local scale = self:GetEffectiveScale()
	local x, y = GetCursorPosition()
	self:ClearAllPoints()
	self:SetPoint("BOTTOMLEFT", UIParent, x / scale + 16, (y / scale - self:GetHeight() - 16))
end

hooksecurefunc("GameTooltip_SetDefaultAnchor", function(tooltip, parent)
	if GetMouseFocus() ~= WorldFrame then return end
	tooltip:SetOwner(parent, "ANCHOR_CURSOR")
	setPoint(tooltip)
	-- tooltip.default = 1
end)
I don't think I have anything anywhere else, at least...
__________________
Grab your sword and fight the Horde!
  Reply With Quote
09-29-16, 11:31 AM   #5
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
mm I figured maybe my client had some weird bug that was causing this, because I do have some other weird tooltip bug that nobody else seems to have, so I tried on PTR, and... yeah, same problem there :s

If I try to set the anchor point to BOTTOMLEFT, the tooltip anchors there when i mouse over something but doesn't actually move along with the cursor anymore.
If I set anchor point to LEFT, RIGHT or CENTER, the tooltip intially appears with the cursor there but automatically snaps back up to put the cursor at the bottom of the tooltip, not sure if that's intended behavior.

If I set the anchor point to TOP, something really funky happens and the tooltip gets completely broken

This second one you just gave me has the tooltips appear where intended but then they remain static and don't follow the cursor. Not sure if that's how it's meant to work.

I'm having a really hard time understanding why different anchor points give such wildly different results...

I like your if GetMouseFocus() ~= WorldFrame then return end though, gonna re-use that one.

Last edited by Ammako : 09-29-16 at 11:36 AM.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Anchoring tooltip to mouse


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