lotrointerface.com
Search Downloads

LoTROInterface SVN Reminders

[/] [trunk/] [Thurallor/] [Common/] [UI/] [DropDown_3.lua] - Rev 7

Compare with Previous | Blame | View Log

DropDown = class(Turbine.UI.Control);

-- Adapted from Galuhad's DropDown class
-- http://www.lotrointerface.com/list.php?skinnerid=3762

-- Added member functions:
--   SetFont()
--   SetBorderColor()
--   SetInteriorColor()
--   SetExpanded()
--   SetSelectedItem()
--   GetSelectedItem()

-- Changes:
--   Replaced SetMaxItems() with
--     SetExpandedWidth(), SetExpandedHeight(), SetExpandedSize(), Get...()

-- Added events:
--   SelectionChanged

-- Added features:
--   The itemList can be text strings or controls.  If strings, controls
--   to contain them will be created automatically.
--   The user can resize the expanded window by dragging the corner.

function DropDown:Constructor(itemList, selectedItem)
    Turbine.UI.Control.Constructor(self);
    if (type(itemList) ~= "table") then
        error("itemList must be a table", 3);
    end
    if (selectedItem == nil) then
        error("selectedItem is nil", 3);
    end

    self.itemList = itemList;
    self.selectedItem = selectedItem;
    self.callbacks = {};

    -- Defaults for configurable options
    self.borderColor = Turbine.UI.Color(1, 0.63, 0.63, 0.63);
    self.borderSize = 2;
    self.backColor = Turbine.UI.Color.Black;
    self.expandedBackColor = Turbine.UI.Color(0.9, 0, 0, 0);
    self.foreColor = Turbine.UI.Color(1, 0.90, 0.82, 0.53);
    self.outlineColor = Turbine.UI.Color.Black;
    self.selectedColor = Turbine.UI.Color.Yellow;
    self.mouseOverColor = Turbine.UI.Color.White;
    self.mouseOverOutlineColor = Turbine.UI.Color(1, 0.85, 0.65, 0);
    self.alignment = Turbine.UI.ContentAlignment.MiddleCenter;
    self.font = Turbine.UI.Lotro.Font.TrajanPro14;
    
    self:SetBackColor(self.borderColor);
    
    local interior = Turbine.UI.Control();
    interior:SetParent(self);
    interior:SetPosition(self.borderSize, self.borderSize);
    interior:SetBackColor(self.backColor);
    interior:SetMouseVisible(false);
    self.interior = interior;

    local arrow = Turbine.UI.Control();
    arrow:SetParent(interior);
    arrow:SetSize(14, 14);
    arrow:SetBackground(0x41007E18);
    arrow:SetBlendMode(Turbine.UI.BlendMode.Overlay);
    arrow:SetMouseVisible(false);
    self.arrow = arrow;

    self:SetSelectedItem(selectedItem);
    
    self:SetSize(100, 19);
end

function DropDown:SetBorderColor(color)
    self.borderColor = color;
    self:SetBackColor(color);
    if (self.listWindow) then
        self.listWindow:SetBackColor(color);
    end
end

function DropDown:SetInteriorColor(color)
    self.backColor = color;
    self.interior:SetBackColor(color);
    self.expandedBackColor = color;
    if (self.listWindow) then
        self.listWindow.interior:SetBackColor(color);
    end
end

function DropDown:SetWidth(width)
    self:SetSize(width, self:GetHeight());
end

function DropDown:SetHeight(height)
    self:SetSize(self:GetWidth(), height);
end

function DropDown:SetSize(width, height)
    Turbine.UI.Control.SetSize(self, width, height);
    
    local interiorWidth = width - (2 * self.borderSize);
    self.textHeight = height - (2 * self.borderSize);
    self.interior:SetSize(interiorWidth, self.textHeight);
    
    local arrowWidth, arrowHeight = self.arrow:GetSize();
    local labelWidth = interiorWidth - 4;
    self.label:SetSize(labelWidth, self.textHeight);
    self.arrow:SetLeft(interiorWidth - arrowWidth);
    self.arrow:SetTop(math.floor((self.textHeight - arrowHeight) / 2) - 1);
end

function DropDown:MouseEnter()
    self.arrow:SetBackground(0x41007E1B);
end

function DropDown:MouseLeave()
    self.arrow:SetBackground(0x41007E18);
end

function DropDown:MouseClick(args)
    if (args.Button == Turbine.UI.MouseButton.Left) then
        self:SetExpanded(not self.expanded);
    end
end

function DropDown:SetParent(parent)
    Turbine.UI.Control.SetParent(self, parent);
    self:SetExpanded(false);
    
    -- Find out which window this control is contained by
    self.window = nil;
    while (parent ~= nil) do
        self.window = parent;
        parent = parent:GetParent();
    end
end

function DropDown:SetExpanded(expand)
    if (self.listWindow) then
        -- Remove previous event handlers on user controls
        for _, cbInfo in ipairs(self.callbacks) do
            local control, event, func = unpack(cbInfo);
            RemoveCallback(control, event, func);
        end
        self.callbacks = {};
        self.listWindow:Close();
    end
    if (expand) then
        local window = Turbine.UI.Window();
        local width = self:GetExpandedWidth();
        window:SetZOrder(self.window:GetZOrder() + 1);
        window:SetWidth(width);
        window:SetBackColor(self.borderColor);
        window:SetVisible(true);
        window:SetPosition(self:PointToScreen(0, self.borderSize + self.textHeight));
        window.Deactivated = function()
            self:SetExpanded(false);
        end
        self.listWindow = window;

        local interior = Turbine.UI.Control();
        width = width - 2 * self.borderSize;
        interior:SetWidth(width);
        interior:SetParent(window);
        interior:SetBackColor(self.expandedBackColor);
        interior:SetPosition(self.borderSize, self.borderSize);
        window.interior = interior;
        
        local listBox = Turbine.UI.ListBox();
        width = width - 14;
        listBox:SetParent(interior);
        listBox:SetWidth(width);
        listBox:SetLeft(2);
        
        local scrollBar = Turbine.UI.Lotro.ScrollBar();
        scrollBar:SetPosition(width + 3, 0);
        scrollBar:SetWidth(10);
        scrollBar:SetParent(interior);
        scrollBar:SetOrientation(Turbine.UI.Orientation.Vertical);
        listBox:SetVerticalScrollBar(scrollBar);
        
        local height = 0;
        for n, item in ipairs(self.itemList) do
            local control = self:_CreateItem(listBox, n, item);
            control:SetWidth(width);
            listBox:AddItem(control);
            height = height + control:GetHeight();
        end

        height = math.max(height, 3 * self.textHeight);
        height = math.min(height, self:GetExpandedHeight() - (self.borderSize * 2));
        interior:SetHeight(height);
        listBox:SetHeight(height);
        scrollBar:SetHeight(height - 16);
        height = height + 2 * self.borderSize;
        window:SetHeight(height);

        -- If the expanded list goes off the screen, move it above
        if (window:GetTop() + height > Turbine.UI.Display:GetHeight()) then
            window:SetPosition(self:PointToScreen(0, - height + self.borderSize));
        else
            -- If expanded downward, then allow it to be resized by dragging the corner
            local resizer = Thurallor.UI.Resizer(interior);
            resizer:SetMinimumSize(self:GetWidth() - (self.borderSize * 2), 3 * self.textHeight);
            interior.Resizing = function()
                local width, height = interior:GetSize();
                listBox:SetSize(width - 14, height);
                scrollBar:SetLeft(width - 11);
                scrollBar:SetHeight(height - 16);
                width = width + 2 * self.borderSize;
                height = height + 2 * self.borderSize;
                window:SetSize(width, height);
                self.expandedWidth = width;
                self.expandedHeight = height;
            end
        end
        
        window:Activate();
    end
    self.expanded = expand;
end

function DropDown:_CreateItem(listBox, n, item)
    local control = item;
    if (type(item) == "string") then
        control = Turbine.UI.Label();
        control.item = item;
        control:SetHeight(self.textHeight);
        control:SetFont(self.font);
        if (item == self.selectedItem) then
            control:SetForeColor(self.selectedColor);
        else
            control:SetForeColor(self.foreColor);
        end
        control:SetTextAlignment(self.alignment);
        control:SetText(item);
        control:SetMultiline(false);
        control.MouseEnter = function()
            control.foreColor = control:GetForeColor();
            control:SetForeColor(self.mouseOverColor);
            control:SetOutlineColor(self.mouseOverOutlineColor);
            control:SetFontStyle(Turbine.UI.FontStyle.Outline);
        end
        control.MouseLeave = function()
            control:SetForeColor(control.foreColor);
            control:SetFontStyle(Turbine.UI.FontStyle.None);
        end
    end
    if (listBox) then
        local function MouseClick(ctl, args)
            if (args.Button == Turbine.UI.MouseButton.Left) then
                self:SetSelectedItem(item);
                -- For backward compatibility with Galuhad's class:
                DoCallbacks(self, "ItemChanged", { Index = n; Text = item });
            end
        end
        -- Keep track of this so we can remove it when the pulldown closes
        table.insert(self.callbacks, { control, "MouseClick", MouseClick });
        AddCallback(control, "MouseClick", MouseClick);
    end
    return control;
end

function DropDown:GetSelectedItem()
    return self.selectedItem;
end

function DropDown:GetText()
    return self:GetSelectedItem()
end

function DropDown:SetSelectedItem(item)
    self:SetExpanded(false);
    self.selectedItem = item;

    -- Delete old label (if any)
    if (self.label) then
        RemoveCallback(self.label, "MouseClick", self.labelMouseClick);
        self.label:SetParent(nil);
    end
    
    -- Create or place new label
    local label = self:_CreateItem(nil, 0, item);
    label:SetParent(self.interior);
    label:SetLeft(2);
    self.labelMouseClick = function(_, args)
        DoCallbacks(self, "MouseClick", args);
    end
    AddCallback(label, "MouseClick", self.labelMouseClick);
    self.label = label;
    self:SetSize(self:GetSize());
    
    -- Make sure arrow control is in front
--    self.arrow:SetParent(nil);
--    self.arrow:SetParent(self.interior);
--    self.arrow:SetZOrder(3);
    
    DoCallbacks(self, "SelectionChanged", { Item = item });
end

function DropDown:SetText(text)
    self:SetSelectedItem(text);
end

function DropDown:SetAlignment(alignment)
    self.alignment = alignment;
    self:SetSelectedItem(self:GetSelectedItem());
end

function DropDown:SetFont(font)
    self:SetExpanded(false);
    self.font = font;
    self.label:SetFont(font);
    self.label:SetText(self.label:GetText());
end

function DropDown:GetExpandedWidth()
    return self.expandedWidth or self:GetWidth();
end

function DropDown:GetExpandedHeight()
    local defaultHeight = (self.textHeight * 8) + (self.borderSize * 2);
    return self.expandedHeight or defaultHeight;
end

function DropDown:GetExpandedSize()
    return self:GetExpandedWidth(), self:GetExpandedHeight();
end

function DropDown:SetExpandedWidth(width)
    self:SetExpandedSize(width, self:GetExpandedHeight());
end

function DropDown:SetExpandedHeight(height)
    self:SetExpandedSize(self:GetExpandedWidth(), height);
end

function DropDown:SetExpandedSize(width, height)
    self:SetExpanded(false);
    self.expandedWidth = width;
    self.expandedHeight = height;
end

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

Compare with Previous | Blame


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


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