lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [Common/] [Utils/] [AutoSizing_3.lua] - Rev 171

Go to most recent revision | Compare with Previous | Blame | View Log

import "Turbine.UI";

-- Adds AutoSize() function to Turbine.UI.Label.
-- It works for single or multiline strings.
-- Not yet tested with inline markup.

-- Get font heights from enumeration strings
local FontHeight = {};
for key, value in pairs(Turbine.UI.Lotro.Font) do
    local points = string.match(key, "[0-9]+$", -3) or 12;
    FontHeight[value] = tonumber(points);
end

-- Override SetMultiLine() because the built-in IsMultline() function doesn't work and we need to fix it
Turbine.UI.Label._SetMultiline = Turbine.UI.Label.SetMultiline;
function Turbine.UI.Label:SetMultiline(enable)
    Turbine.UI.Label._SetMultiline(self, enable);
    self.multiline = enable;
    if (self.autoSizingEnabled) then
        self:AutoSize();
    end
end

function Turbine.UI.Label:IsMultiline()
    return ((self.multiline == true) or (self.multiline == nil));
end

function Turbine.UI.Label:AutoSize()

    -- Save this to restore afterwards
    local text = self:GetText();
    local userScrollBar = self:GetHorizontalScrollBar();
    self:SetHorizontalScrollBar(nil);
    self:_SetMultiline(false);

    -- We can set the height based on the selected font and the number of '\n' characters present
    local lineHeight = FontHeight[self:GetFont()];
    self:SetHeight(lineHeight);

    -- Make a temporary scrollbar that whose visibility will indicate text width
    local tempScrollBar = Turbine.UI.Lotro.ScrollBar();
    tempScrollBar:SetParent(self);
    self:SetHorizontalScrollBar(tempScrollBar);
    
    -- Magic function call that is necessary to make the ScrollBar:IsVisible() function work
    self:SetText(text);

    local function autoSizeLine()
        self:SetWidth(64);

        -- Rapidly find lower and upper bounds for the possible widths.
        local lower_bound, upper_bound = 0, 64;
        local visible = tempScrollBar:IsVisible();
        while (visible) do
            --Puts("\"" .. tostring(self:GetText()) .. "\" is wider than " .. upper_bound);
            lower_bound = upper_bound;
            upper_bound = 2 * upper_bound;
            self:SetWidth(upper_bound);
            visible = tempScrollBar:IsVisible();
        end

        -- Binary search for the precise width.  Fractions are OK; they are handled by the API.
        local width, distance = self:GetWidth();
        repeat
            if (tempScrollBar:IsVisible()) then
                --Puts("\"" .. tostring(self:GetText()) .. "\" is wider than " .. width);
                lower_bound = width;
            else
                --Puts("\"" .. tostring(self:GetText()) .. "\" is narrower than " .. width);
                upper_bound = width;
            end
            distance = upper_bound - lower_bound;
            width = lower_bound + math.floor(0.5 + distance / 2);
            self:SetWidth(width);
        until (distance <= 1);
        return width;
    end

    if (not self:IsMultiline()) then
        autoSizeLine();
    else
        -- If multiline, run once for each line and use the widest line to set the overall width.
        local numLines, maxWidth, _ = 0, 0;
        for line in string.gmatch(self:GetText(), "[^\n]+") do
            numLines = numLines + 1;
            self:SetText(line);
            maxWidth = math.max(maxWidth, autoSizeLine());
        end
        maxWidth = maxWidth + lineHeight; -- fudge that seems necessary to account for phantom width of "\n" character
        self:_SetMultiline(true);
        self:SetSize(maxWidth, numLines * lineHeight);
        self:SetText(text);
    end
    
    tempScrollBar:SetParent(nil);
    -- Restore user's scrollbar (if any)
    self:SetHorizontalScrollBar(userScrollBar);
end

Go to most recent revision | Compare with Previous | Blame


All times are GMT -5. The time now is 08:12 AM.


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