WoWInterface SVN GymnastTooltips

[/] [trunk/] [Gymnast/] [Gymnast.lua] - Rev 3

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------
-- Gymnast.lua 
--------------------------------------------------------------------------
--[[
Gymnast Tooltips

Bending over backwards to please. Make your Tooltip as flexible as you are.

By author: AnduinLothar    <karlkfi@yahoo.com>

Slash Commands:
"/gtshow" - Makes the Game Tooltip visible for you to drag to your preferred position.
"/gtreset" - Moves the Game Tooltip back to its original position.
"/gttopcenter" - Moves the Game Tooltip to the alternate top center position.
"/gtanchor [position]" - Makes the tooltip extend from this anchored position.
(position can be "SMART", "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", "LEFT", "TOP", "RIGHT", "BOTTOM", "MOUSE", "UBER", "OWNER")
Note: "MOUSE", "UBER", and "OWNER" are toggle commands. Call them again to disable.

'mouse' relocates the tooltip to the mouse.
'uber' relocates "Enhanced Tooltips" to show near their parent frame. (toggle)
'owner' relocates normal tooltips to show near their parent frame. (toggle)

        $Id: Gymnast.lua 17 2010-10-16 00:11:57Z kharthus1 $
        $Rev: 17 $
        $LastChangedBy: kharthus1 $
        $Date: 2010-10-15 17:11:57 -0700 (Fri, 15 Oct 2010) $
        
changelog:
v4.0
-Enhanced GUI
-Checkboxes for anchor selection
-Checkboxes for Uber and Owner togglable options
-Buttons to select Here or Mouse anchoring
-Draggable tooltip no longer hides when you stop dragging it. Click Here or Mouse.
-Removed /gtanchor (use gui)
v3.3
-Converted to use hooksecurefunc instead of manual hooks to fix taint issues
-Removed Cosmos and Khaos code
v3.2
-Changed VARIABLES_LOADED to ADDON_LOADED
-Fixed last instances of 'this'
v3.1
-Updated for WoW 4.0.1
v3.0
-Updated for lua 5.1
-Updated TOC to 20000
-Anchor to MOUSE mode now correctly dissables if you set another mode.
-OO'd the code
-Removed Chronos Dep
v2.7
-Added an option to relocate normal tooltips to be by their parent, like Uber Tooltips were.  Using this option will fix things such as Buff tooltips showing up off screen when you move the buffs to the left of the screen.
-Fixed bug with the position by owner option, needed GetEffectiveScale
-Updated to not use RegisterForSave
-Updated TOC to 11000
v2.6
-Updated TOC to 1700
-Fixed issues not accounting for Screen Scaling
-Fixed compatibility with CosmosLegacy.
v2.5
-Updated TOC to 1600
-Added Khaos Options.
-Fixed the Smart Anchor option to be under advanced options.
-Raised advanced options to Master difficulty.
-Made feedback localizable.
-Clarified Uber tooltip relocation in the mouse-over info.
v2.42
-Extra options now save correctly when not using cosmos.
v2.41
-Updated TOC to 1300
-Fixed a Cosmos dependancy to be truely optional
v2.4
-French localization updated by Sasmira
v2.3
-Added smart anchoring and center anchoring
-Added a button to move to the old cosmos position top center.
v2.2
-Added Mouse and Uber tooltip relocations
v2.1
-Added Anchoring
-Modified instructions in the tooltip.
v2.0
-Completely redesigned... now it plays nicely with TooltipsBase.
v1.0
-Replaced tooltips with mobile ones.
-Included instructions in the tooltip.

]]--

Gymnast = {};

-- Constants
Gymnast.TOOLTIPS_POINT = "Point";
Gymnast.TOOLTIPS_RELATIVETO = "RelativeTo";
Gymnast.TOOLTIPS_RELATIVEPOINT = "RelativePoint";
Gymnast.TOOLTIPS_POSITION = "Position";

local anchorPositions = { "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", "CENTER", "LEFT", "TOP", "RIGHT", "BOTTOM" };
Gymnast.SetTooltipAnchorList = {};

function Gymnast.OnLoad(self)
        
        self:RegisterEvent("ADDON_LOADED");
        
        hooksecurefunc("GameTooltip_SetDefaultAnchor", Gymnast.GameTooltip_SetDefaultAnchor);
        hooksecurefunc(GameTooltip,"SetOwner", Gymnast.GameTooltip_SetOwner);
        
        for i, anchor in ipairs(anchorPositions) do
                Gymnast.SetTooltipAnchorList[anchor] = function() Gymnast.SetTooltipAnchor(anchor) end;
        end

        Gymnast.Enabled = true;
        
        SlashCmdList["GYMNASTTOOLTIPSSHOW"] = Gymnast.ShowMobileGameTooltip;
    SLASH_GYMNASTTOOLTIPSSHOW1 = "/gtshow";
        
        SlashCmdList["GYMNASTTOOLTIPSTOPCENTER"] = Gymnast.SetTooltipTopCenter;
    SLASH_GYMNASTTOOLTIPSTOPCENTER1 = "/gttopcenter";
        
        SlashCmdList["GYMNASTTOOLTIPSRESET"] = Gymnast.ResetGameTooltip;
    SLASH_GYMNASTTOOLTIPSRESET1 = "/gtreset";
        
end


function Gymnast.OnEvent(self,event,...)
        local arg1 = ...;
        if (event == "ADDON_LOADED" and arg1 == "Gymnast") then
                if (not Gymnast_TooltipPointSettings) then
                Gymnast_TooltipPointSettings = {
                        [Gymnast.TOOLTIPS_POINT] = "TOPLEFT",
                        [Gymnast.TOOLTIPS_RELATIVETO] = "UIParent",
                        [Gymnast.TOOLTIPS_RELATIVEPOINT] = "BOTTOMLEFT",
                        [Gymnast.TOOLTIPS_POSITION] = nil
                };
                end
        end
end

function Gymnast.UpdateCheckButtons(point)
        for i, anchor in ipairs(anchorPositions) do
                local checkbox = _G["MobileGameTooltip"..anchor];
                if anchor == point then
                        if not checkbox:GetChecked() then
                                checkbox:SetChecked(1);
                        end
                else
                        if checkbox:GetChecked() then
                                checkbox:SetChecked(0);
                        end
                end
        end
end

function Gymnast.SetTooltipAnchor(point)
        Gymnast.UpdateCheckButtons(point);
        Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT] = point;
end

function Gymnast.SetTooltipTopCenter()
        MobileGameTooltip:SetOwner(UIParent, "ANCHOR_NONE");
        MobileGameTooltip:SetPoint("TOP", "UIParent", "TOP", 0, -32);
        local r = 0.3;
        local g = 0.7;
        local b = 0.9;
        MobileGameTooltip:AddLine(GYMNAST_TOOLTIPS_HEADER, r+.3, g, b);
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(GYMNAST_TOOLTIPS_INSTRUCTIONS, r, g, b);
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:Show();
end

function Gymnast.MarkTooltipCoords(smart)
        local centerX,centerY = MobileGameTooltip:GetCenter();
        local left = MobileGameTooltip:GetLeft(); 
        local top = MobileGameTooltip:GetTop(); 
        local right = MobileGameTooltip:GetRight(); 
        local bottom = MobileGameTooltip:GetBottom();
        local coords;
        local place = Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT];
        
        if (smart) then
                local parentW = UIParent:GetRight() - UIParent:GetLeft();
                local parentH = UIParent:GetTop() - UIParent:GetLeft();
                local onRightThird = (centerX > 2*(parentW/3));
                local onLeftThird = (centerX < (parentW/3));
                local onTopThird = (centerY > 2*(parentH/3));
                local onBottomThird = (centerY < (parentH/3));
                if onRightThird then
                        if onTopThird then
                                place = "TOPRIGHT";
                        elseif onBottomThird then
                                place = "BOTTOMRIGHT";
                        else
                                place = "RIGHT";
                        end
                elseif onLeftThird then
                        if onTopThird then
                                place = "TOPLEFT";
                        elseif onBottomThird then
                                place = "BOTTOMLEFT";
                        else
                                place = "LEFT"; 
                        end
                else
                        if onTopThird then
                                place = "TOP"; 
                        elseif onBottomThird then
                                place = "BOTTOM";
                        else
                                place = "CENTER";
                        end
                end
                Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT] = place;
        end

        if (place == "TOPLEFT") then
                coords = { left, top }; 
        elseif (place == "TOPRIGHT") then
                coords = { right, top }; 
        elseif (place == "BOTTOMLEFT") then
                coords = { left, bottom }; 
        elseif (place == "BOTTOMRIGHT") then
                coords = { right, bottom };
        elseif (place == "CENTER") then
                coords = { centerX, centerY }; 
        elseif (place == "LEFT") then
                coords = { left, centerY }; 
        elseif (place == "TOP") then
                coords = { centerX, top }; 
        elseif (place == "RIGHT") then
                coords = { right, centerY };
        elseif (place == "BOTTOM") then
                coords = { centerX, bottom };
        end
        Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POSITION] = coords;
        
        --print(place.." "..coords[1]..","..coords[2]);
end

function Gymnast.RelocateGameTooltipToMouse(toggle)
        if ( toggle == nil ) then
                Gymnast_RelocateTooltip_ToMouse = (not Gymnast_RelocateTooltip_ToMouse);
        elseif ( toggle == 0 ) then
                Gymnast_RelocateTooltip_ToMouse = false;
        else
                Gymnast_RelocateTooltip_ToMouse = true;
        end
end

function Gymnast.GameTooltipUber(toggle)
        if ( toggle == nil ) then
                Gymnast_RelocateUberTooltips = (not Gymnast_RelocateUberTooltips);
        elseif ( toggle == 0 ) then
                Gymnast_RelocateUberTooltips = false;
        else
                Gymnast_RelocateUberTooltips = true;
        end
end

function Gymnast.GameTooltipOwner(toggle)
        if ( toggle == nil ) then
                Gymnast_RelocateTooltipsToOwner = (not Gymnast_RelocateTooltipsToOwner);
        elseif ( toggle == 0 ) then
                Gymnast_RelocateTooltipsToOwner = false;
        else
                Gymnast_RelocateTooltipsToOwner = true;
        end
end

function Gymnast.ToggleEnable(toggle)
        if ( toggle == 0 ) then
                Gymnast.Enabled = false;
        else
                Gymnast.Enabled = true;
        end
end

local function AnchorToCursor(tooltip)
        if (tooltip == MobileGameTooltip) then
                tooltip:ClearAllPoints();
                Gymnast.SafeSetOwner(tooltip, UIParent, "ANCHOR_NONE");
                tooltip:SetPoint("CENTER", "UIParent", "CENTER", 0, 0);
        else
                tooltip:ClearAllPoints();
                Gymnast.SafeSetOwner(tooltip, UIParent, "ANCHOR_CURSOR");
        end
end

local setOwnerIgnoreHook = false;

function Gymnast.SafeSetOwner(tooltip, owner, anchorPoint, setX, setY)
        if tooltip == GameTooltip then
                setOwnerIgnoreHook = true;
        end
        tooltip:SetOwner(owner, anchorPoint, setX, setY);
end

function Gymnast.GameTooltip_SetOwner(tooltip, owner, anchorPoint, setX, setY)
        if setOwnerIgnoreHook then
                setOwnerIgnoreHook = false;
                return;
        end
        if (Gymnast.Enabled and Gymnast_RelocateTooltipsToOwner) then
                if (not owner) then
                        owner = UIParent;
                end
                if (not tooltip) then
                        tooltip = GameTooltip;
                end
                if (owner == UIParent) then
                        AnchorToCursor(tooltip);
                else
                        NewSmartSetOwner(owner, "ANCHOR_NONE", setX, setY, tooltip);
                end
        end
end

function Gymnast.GameTooltip_SetDefaultAnchor(tooltip, owner) 
        if (Gymnast.Enabled) then
                if (Gymnast_RelocateUberTooltips) and (owner ~= UIParent) then
                        NewSmartSetOwner(owner, "ANCHOR_NONE", 0, 0, tooltip);
                        return;
                elseif (tooltip == GameTooltip) or (tooltip == MobileGameTooltip) then 
                        if (Gymnast_RelocateTooltip_ToMouse) then
                                AnchorToCursor(tooltip);
                                return;
                        elseif ( Gymnast_TooltipPointSettings ) then
                                local position = Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POSITION];
                                if ( ( position ) and ( position[1] ) and ( position[2] ) ) then
                                        tooltip:Hide()
                                        Gymnast.SafeSetOwner(tooltip, owner, "ANCHOR_NONE");
                                        tooltip:ClearAllPoints();
                                        tooltip:SetPoint(Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT], Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_RELATIVETO], Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_RELATIVEPOINT], position[1], position[2] );
                                        return;
                                end
                        end
                end
        end
        Gymnast.SafeSetOwner(tooltip, owner, "ANCHOR_NONE");
        tooltip:SetPoint("BOTTOMRIGHT", "UIParent", "BOTTOMRIGHT", -CONTAINER_OFFSET_X - 13, CONTAINER_OFFSET_Y);
        tooltip.default = 1;
end

function NewSmartSetOwner(owner, position, setX, setY, tooltip)
        if (not owner) then
                owner = UIParent;
        end
        if (not tooltip) then
                tooltip = GameTooltip;
        end
        if (not setX) then
                setX = 0;
        end
        if (not setY) then
                setY = 0;
        end

        local x,y = owner:GetCenter();
        local left = owner:GetLeft();
        local right = owner:GetRight();
        local top = owner:GetTop();
        local bottom = owner:GetBottom();
        local screenWidth = UIParent:GetRight() - UIParent:GetLeft();
        local screenHeight = UIParent:GetTop() - UIParent:GetBottom();
        local scale = owner:GetEffectiveScale();
        if (x~=nil and y~=nil and left~=nil and right~=nil and top~=nil and bottom~=nil and screenWidth>0 and screenHeight>0) then
                setX = setX * scale;
                setY = setY * scale;
                x = x * scale;
                y = y * scale;
                left = left * scale;
                right = right * scale;
                width = right - left;
                top = top * scale;
                bottom = bottom * scale;
                local anchorPoint = "";
                if (y <= (screenHeight * (1/2))) then
                        top = top + setY;
                        anchorPoint = "TOP";
                        if (top < 0) then
                                setY = setY - top;
                        end
                else
                        setY = -setY;
                        bottom = bottom + setY;
                        anchorPoint = "BOTTOM";
                        if (bottom > screenHeight) then
                                setY = setY + (screenHeight - bottom);
                        end
                end
                
                if (x <= (screenWidth * (1/2))) then
                        left = left + setX;
                        if (anchorPoint == "BOTTOM") then
                                anchorPoint = anchorPoint.."RIGHT";
                                setX = setX - width;
                                if (left < 0) then
                                        setX = setX - left;
                                end
                        else
                                anchorPoint = anchorPoint.."LEFT";
                                if (left < 0) then
                                        setX = setX - left;
                                end
                        end
                else
                        setX = -setX;
                        right = right + setX;
                        if (anchorPoint == "BOTTOM") then
                                anchorPoint = anchorPoint.."LEFT";
                                setX = setX + width;
                                if (right > screenWidth) then
                                        setX = setX - (right - screenWidth);
                                end
                        else
                                anchorPoint = anchorPoint.."RIGHT";
                                if (right > screenWidth) then
                                        setX = setX + (screenWidth - right);
                                end
                        end
                end
                
                if (anchorPoint == "") then
                        anchorPoint = "TOPLEFT";
                end
                scale = tooltip:GetScale();
                if (scale) then
                        setX = setX / scale;
                        setY = setY / scale;
                end
                Gymnast.SafeSetOwner(tooltip, owner, "ANCHOR_"..anchorPoint, setX, setY);
        end
end

function Gymnast.ShowMobileGameTooltip()
        GameTooltip_SetDefaultAnchor(MobileGameTooltip, UIParent);
        local r = 0.3;
        local g = 0.7;
        local b = 0.9;
        MobileGameTooltip:AddLine(GYMNAST_TOOLTIPS_HEADER, r+.3, g, b);
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(GYMNAST_TOOLTIPS_INSTRUCTIONS, r, g, b);
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:AddLine(" ");
        MobileGameTooltip:Show();
end

function Gymnast.ResetGameTooltip()
        Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POSITION] = nil;
        Gymnast.GameTooltipUber(0);
        Gymnast.GameTooltipOwner(0);
        Gymnast.ShowMobileGameTooltip();
        MobileGameTooltip.fadeCount = 0.0;
end

-- Frame Scripts
function Gymnast.OnMouseUp(self)
        if ( self.isMoving ) then
                self:StopMovingOrSizing();
                self.isMoving = false;
        end
        -- default to smart anchoring
        Gymnast.MarkTooltipCoords(true);
        Gymnast.SetTooltipAnchor(Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT]);
        --Gymnast.MarkTooltipCoords();
        --self.fadeCount = 1;
end

function Gymnast.OnMouseDown(self,button)
        if ( ( not self.isLocked ) or ( self.isLocked == 0 ) ) and ( button == "LeftButton" ) then
                self:StartMoving();
                self.isMoving = true;
        end
end

function Gymnast.OnHide(self)
        if ( self.isMoving ) then
                self:StopMovingOrSizing();
                self.isMoving = false;
        end
end

function Gymnast.OnUpdate(self,elapsed)
        if ( self.fadeCount ) then
                self.fadeCount = self.fadeCount - elapsed;
                if ( self.fadeCount <= 0 ) then
                        self.fadeCount = nil;
                        self:FadeOut();
                end
        end
end

function Gymnast.CheckButtonOnClick(self)
        PlaySound("igMainMenuOptionCheckBoxOn");
        if self.anchor == "UBER" then
                Gymnast.GameTooltipUber(self:GetChecked() and 1 or 0);
        elseif self.anchor == "OWNER" then
                Gymnast.GameTooltipOwner(self:GetChecked() and 1 or 0);
        else
                Gymnast.SetTooltipAnchor(self.anchor);
        end
end

function Gymnast.HereButtonOnClick(self)
        Gymnast.RelocateGameTooltipToMouse(0);
        Gymnast.MarkTooltipCoords();
        self:GetParent():Hide();
end

function Gymnast.MouseButtonOnClick(self)
        Gymnast.RelocateGameTooltipToMouse(1);
        self:GetParent():Hide();
end

function Gymnast.ShowAnchorCheckButtons()
        for i, anchor in ipairs(anchorPositions) do
                local checkbox = _G["MobileGameTooltip"..anchor];
                checkbox:Show();
        end
end

function Gymnast.HideAnchorCheckButtons()
        for i, anchor in ipairs(anchorPositions) do
                local checkbox = _G["MobileGameTooltip"..anchor];
                checkbox:Hide();
        end
end

function Gymnast.OnShow(self)
        if not self:IsMouseOver() then
                Gymnast.HideAnchorCheckButtons();
        end
        --check the right checkboxes
        MobileGameTooltipUBER:SetChecked(Gymnast_RelocateUberTooltips);
        MobileGameTooltipOWNER:SetChecked(Gymnast_RelocateTooltipsToOwner);
        Gymnast.SetTooltipAnchor(Gymnast_TooltipPointSettings[Gymnast.TOOLTIPS_POINT]);
end

function Gymnast.OnEnter(self)
        Gymnast.ShowAnchorCheckButtons();
end

function Gymnast.OnLeave(self)
        if not self:IsMouseOver() then
                Gymnast.HideAnchorCheckButtons();
        end
end

Compare with Previous | Blame