lotrointerface.com
Search Downloads

LoTROInterface SVN Reminders

[/] [trunk/] [Thurallor/] [Common/] [UI/] [Tooltip_3.lua] - Rev 2

Compare with Previous | Blame | View Log

Tooltip = class(Turbine.UI.Control);

-- The 'content' argument can be:
--  * a one-line string, in which case an optimally-sized control will be created for it
--  * a control, something derived from Turbine.UI.Control
--  * a function that returns a string or a control, which will be called each time the Tooltip displays
--    If you want the content to be continuously updated while the tooltip is open, call Tooltip:SetWantsUpdates(true).
--    Otherwise, you can call Update() any time you want it to be updated.
-- A standard border will be added to the resulting control before display.

function Tooltip:Constructor(content)
    Turbine.UI.Control.Constructor(self);
    self.content = content;
    if (content == nil) then
        error("content is nil", 2);
    end

    -- Mouse behaviors to be added to the attached control
    self._ShowTooltip = function()
        self:SetVisible(true);
    end
    self._HideTooltip = function()
        self:SetVisible(false);
    end
    self._MoveTooltip = function()
        if (self.window) then
            self:UpdateWindowPosition();
        end
    end
end

function Tooltip:CreateBorderControl()
    local control = Turbine.UI.Control();
    local parts = {
        topLeft =     { 0x4114061F,  10,  10,   0,   0 };
        top =         { 0x4114061D, -20,   7,  10,   0 };
        topRight =    { 0x41140618,  10,  10, -10,   0 };
        left =        { 0x4114061A,   7, -20,   0,  10 };
        right =       { 0x4114061E,   7, -20,  -7,  10 };
        bottomLeft =  { 0x41140619,  10,  10,   0, -10 };
        bottom =      { 0x4114061C, -20,   7,  10,  -7 };
        bottomRight = { 0x41140620,  10,  10, -10, -10 };
    }
    for name, info in pairs(parts) do
        local assetId, w, h, x, y = unpack(info);
        local ctl = Turbine.UI.Control();
        ctl:SetBackground(assetId);
        ctl:SetParent(control);
        ctl:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
        ctl:SetSize(w, h);
        ctl.w, ctl.h, ctl.x, ctl.y = w, h, x, y;
    end
    control.SetSize = function(_, w, h)
        Turbine.UI.Control.SetSize(control, w, h);
        for c = 1, 8 do
            local ctl = control:GetControls():Get(c);
            ctl:SetSize((w + ctl.w) % w, (h + ctl.h) % h);
            ctl:SetPosition((w + ctl.x) % w, (h + ctl.y) % h);
        end
    end
    return control;
end

function Tooltip:AddBorder(content)
    local border = self:CreateBorderControl();
    
    if (type(content) == "string") then
        -- Make an optimally-sized Label control to contain the text
        local label = Turbine.UI.Label();
        label:SetBackColor(Turbine.UI.Color(0.9, 0, 0, 0));
        label:SetFont(Turbine.UI.Lotro.Font.TrajanPro16);
        label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
        label:SetText(content);
        label:AutoSize();
        content = label;
        self.simple = true;
    else
        self.simple = false;
    end

    content:SetParent(border);
    content:SetPosition(3, 3);
    border:SetSize(content:GetWidth() + 6, content:GetHeight() + 6);
    return border;
end

function Tooltip:GetContent()
    if (type(self.content) == "function") then
        -- Content is a user-supplied function that returns a string or a Turbine.UI.Control
        local result = self.content(self.attachment);
        if (result == nil) then
            error("tooltip function returned nil");
        end
        return self:AddBorder(result);
    else
        -- Content is a user-supplied string or Turbine.UI.Control
        return self:AddBorder(self.content);
    end
end

-- If the tooltip is currently being displayed, and 'content' is a function, it will be called again and the display updated.
function Tooltip:Update()
    if (self.window) then
        self:SetVisible(false);
        self:SetVisible(true);
    end
end

-- Note: This should only be called once; changing the attachment to a different control is not implemented.
function Tooltip:Attach(control)
    if (control == nil) then
        error("control is nil", 2);
    end
    self.attachment = control;
    AddCallback(control, "MouseHover", self._ShowTooltip);
    AddCallback(control, "MouseMove", self._MoveTooltip);
    AddCallback(control, "MouseLeave", self._HideTooltip);
end

function Tooltip:Detach()
    if (self.attachment) then
        RemoveCallback(self.attachment, "MouseHover", self._ShowTooltip);
        RemoveCallback(self.attachment, "MouseMove", self._MoveTooltip);
        RemoveCallback(self.attachment, "MouseLeave", self._HideTooltip);
    end
    self.attachment = nil;
end

function Tooltip:SetVisible(visible)
    if (visible) then
        if (not self.window) then
            self:CreateWindow();
        end
    else
        if (self.window) then
            self:DestroyWindow();
        end
    end
end

function Tooltip:CreateWindow()
    local content = self:GetContent();
    local width, height = content:GetSize();
    local window = Turbine.UI.Window();
    window:SetVisible(true);
    content:SetParent(window);
    window.content = content;
    window:SetSize(width, height);
    window:SetZOrder(2147483647); -- in front of everything, including Turbine tooltip (if any)
    window.MouseEnter = function()
        self:SetVisible(false);
    end
    self.window = window;
    self:UpdateWindowPosition();
end

function Tooltip:DestroyWindow()
    self.window.content:SetParent(nil);
    self.window:SetVisible(false);
    self.window:Close();
    self.window = nil;
end

function Tooltip:UpdateWindowPosition()
    local width, height = self.window:GetSize();

    -- Determine optimal positioning of the tooltip
    local displayWidth, displayHeight = Turbine.UI.Display.GetSize();
    local x, y = Turbine.UI.Display.GetMousePosition();
    local left, top = x + 30, y + 31;
    if (left + width > displayWidth) then
        left = displayWidth - width;
    end
    if (self.simple) then
        -- For a simple one-line tooltip, we try to match Turbine's tooltip
        -- location so we can cover it up (if it's showing).
        if (top + height > displayHeight) then
            top = displayHeight - height;
        end
    else
        -- For multiline tooltips, use a similar strategy, but we try a little
        -- harder to position the tooltip such that it doesn't overlap the
        -- mouse cursor.
        if (top + height > displayHeight) then
            top = y - height - 20;
        end
    end

    self.window:SetPosition(left, top);
end

Thurallor = Thurallor or {};
Thurallor.UI = Thurallor.UI or {};
Thurallor.UI.Tooltip = Tooltip;

Compare with Previous | Blame


All times are GMT -5. The time now is 12:33 PM.


Our Network
EQInterface | EQ2Interface | Minion | WoWInterface | ESOUI | LoTROInterface | MMOUI | Swtorui