lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [SequenceBars/] [Slot.lua] - Rev 167

Compare with Previous | Blame | View Log

Slot = class(Turbine.UI.Control);

function Slot:Constructor(info, wantsMouseWheelEvents)
    Turbine.UI.Control.Constructor(self);
    self:SetMouseVisible(false);
    self:SetSize(36, 36);
    self.advanceFunc = {};
    self:SetInfo(info);
    self:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
    Turbine.UI.Control.SetAllowDrop(self, false);
    self.wantsMouseWheelEvents = wantsMouseWheelEvents;
end

function Slot:GetInfo()
    return self.info;
end

-- Get skill name(s) from moebius92's SkillData database
function Slot:GetSkillNames()
    if (not self.skillNames and (self.info.type == Turbine.UI.Lotro.ShortcutType.Skill)) then
        local shortcut = self.object and self.object.GetShortcut and self.object:GetShortcut();
        self.skillNames = shortcut and shortcut:GetSkillName();
        if (type(self.skillNames) == "string") then
            self.skillNames = { self.skillNames };
        end
    end
    return self.skillNames;
end

-- Get canonical skill name (with no fire oil, light oil, alternate stance, etc.)
function Slot:GetSkillName()
    local skillNames = self:GetSkillNames();
    if (skillNames) then
        return skillNames[1];
    end
end

function Slot:GetSkill()
    local names = self:GetSkillNames();
    if (type(names) == "string") then
        return Thurallor.Utils.Watcher.GetSkillByNames(names);
    elseif (type(names) == "table") then
        return Thurallor.Utils.Watcher.GetSkillByNames(names);
    end
end

function Slot:GetItem()
    if (self.object.GetItem) then
        return self.object:GetItem();
    end
end

function Slot:GetItemName()
    local item = self:GetItem();
    return item and item:GetItemInfo():GetName();
end

function Slot:GetNumLabel()
    return self.slotNumber;
end

function Slot:IsQuickslot()
    return self.isQuickslot;
end

function Slot:SetActionEnabled(enabled)
    self.actionEnabled = enabled;
    if (self.object) then
        self.object:SetMouseVisible(enabled);
    end
    if (self.numLabel) then
        self.numLabel:SetMouseVisible(not enabled);
    end
end

function Slot:SetAllowDrop(allowDrop)
    if (self.numLabel) then
        self.numLabel:SetAllowDrop(allowDrop);
    elseif (self.object) then
        self.object:SetAllowDrop(allowDrop);
    end
end

function Slot:SetUseOnRightClick(useOnRightClick)
    self.useOnRightClick = useOnRightClick;
    if (self.object and self.object.SetUseOnRightClick) then
        self.object:SetUseOnRightClick(useOnRightClick);
    end
end

function Slot:SetDraggable(draggable)
    if (draggable) then
        self.numLabel.MouseDown = function(sender, args)
            self:MouseDown(args);
        end
        self.numLabel.MouseUp = function(sender, args)
            self:MouseUp(args);
        end
        self.numLabel.MouseMove = function()
            self:MouseMove();
        end
    elseif (self.numLabel) then
        self.numLabel.MouseDown = nil;
        self.numLabel.MouseUp = nil;
        self.numLabel.MouseMove = nil;
    end
end

function Slot:SetInfo(info)

    -- Discard old object, if it's a different type
    if (self.object and (self.info.class ~= info.class)) then
        self.object:SetParent(nil);
        self.object = nil;
    end

    self.info = {};
    DeepTableCopy(info, self.info);
    
    if (not self.parent) then
        return;
    end

    -- Create the quickslot object or command icon
    if ((not info.class) or (info.class == "Turbine.UI.Lotro.Quickslot")) then
        if (not self.object) then
            local object = Turbine.UI.Lotro.Quickslot();
            object:SetParent(self);
            object:SetZOrder(1);
            self.object = object;

            -- Forward events to parent object
            object.MouseClick = function(sender, args)
                DoCallbacks(self, "MouseClick", args);
            end
            object.MouseWheel = function(sender, args)
                DoCallbacks(self, "MouseWheel", args);
            end
        end
        local shortcut = Turbine.UI.Lotro.Shortcut(info.type, ((type(info.Data) == "string") and info.Data:toWindows()) or info.Data);
        self.object:SetShortcut(shortcut);
        self.isQuickslot = true;
        self.skillNames = nil;
        self.object.DragDrop = function(sender)
            sender:SetShortcut(Turbine.UI.Lotro.Shortcut(self.info.type, self.info.Data));
        end
    elseif ((info.class == "Turbine.UI.Control") or (info.class == "Turbine.UI.Lotro.EntityControl")) then
        if (not self.object) then
        
            local object;
            if (info.type == "SelectTarget") then
                object = Turbine.UI.Lotro.EntityControl();
                object:SetSelectionEnabled(true);
                object:SetContextMenuEnabled(false);
                object:SetBackground(resources.Icon.SelectTarget);
                self.watcher = Thurallor.Utils.Watcher;
                self.player = Turbine.Gameplay.LocalPlayer:GetInstance();
                self.getTargetFunc = loadstring(info.getTargetFunc);
            else
                -- MouseWheel events aren't implemented for Controls, only ListBoxes.
                -- But I think they probably use more resources than Controls, so I'll
                -- only use ListBoxes if the mouse wheel option is enabled.
                if (self.wantsMouseWheelEvents) then
                    object = Turbine.UI.ListBox();
                else
                    object = Turbine.UI.Control();
                end
            end
            
            object:SetParent(self);
            object:SetSize(32, 32);
            object:SetPosition(3, 3);
            object:SetZOrder(1);
            self.object = object;
            object.slot = self;

            -- Forward events to parent object
            object.MouseClick = function(obj, args)
                if (obj.slot.info.type == "SelectTarget") then
                    -- Update the round-robin "cursor" to the next member, regardless
                    -- of whether the member was successfully selected; clicking on the
                    -- slot is enough to know the user's intent.
                    Thurallor.Utils.Watcher.GetNextPartyMember(obj.slot.entity);
                end
                DoCallbacks(obj.slot, "MouseClick", args);
            end
            object.MouseEnter = function(obj)
                if (obj.slot.info.type == "SelectTarget") then
                    obj.slot:UpdateEntity();
                    obj.slot:SetWantsUpdates(true);
                end
                DoCallbacks(obj.slot, "MouseEnter");
            end
            object.MouseLeave = function(obj)
                if (obj.slot.info.type == "SelectTarget") then
                    obj:SetBackground(resources.Icon.SelectTarget);
                    obj:SetEntity(nil);
                    obj.slot.entity = nil;
                    obj.slot:SetWantsUpdates(false);
                end
                DoCallbacks(obj.slot, "MouseLeave");
            end
            object.MouseWheel = function(obj, args)
                DoCallbacks(obj.slot, "MouseWheel", args);
            end

            -- Add tooltip
            if (info.type == "SelectTarget") then
                self:SetTooltip(function()
                    local entity = self.object:GetEntity();
                    return entity and entity:GetName() or L:GetText("/SequenceEditor/NoTarget");
                end);
            end
        end
        self.isQuickslot = false;
    end
    self:SetUseOnRightClick(self.useOnRightClick);

    -- Draw text overlay and icon overlay (if any)
    if (not self.textOverlay) then
        local textOverlay = Turbine.UI.Label();
        textOverlay:SetParent(self);
        textOverlay:SetZOrder(2);
        textOverlay:SetSize(32, 32);
        textOverlay:SetPosition(3, 3);
        textOverlay:SetMouseVisible(false);
        textOverlay:SetFont(Turbine.UI.Lotro.Font.Verdana10);
        textOverlay:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
        textOverlay:SetFontStyle(Turbine.UI.FontStyle.Outline);
        textOverlay:SetOutlineColor(Turbine.UI.Color(1, 0, 0, 0));
        textOverlay:SetMultiline(true);
        textOverlay:SetMarkupEnabled(true);
        textOverlay:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
        self.textOverlay = textOverlay;
    end
    self.background = info.background;
    if (info.altIcon) then
        self.background = info.altIcon;
    end
    self.textOverlay:SetBackground(self.background);
    self.textOverlay:SetText(info.textOverlay);
end

-- For "Select Target" slots only:
function Slot:UpdateEntity()
    local entity = self.getTargetFunc(Thurallor.Utils.Watcher, self.player, self.info.raidMemberName, self.info.number); 
    if (entity ~= self.entity) then
        self.object:SetEntity(entity);
        self.entity = entity;
        self.tooltip:Update();
    end
    if (entity) then
        self.object:SetBackground(resources.Icon.SelectTargetKnown);
    else
        self.object:SetBackground(resources.Icon.SelectTargetUnknown);
    end
end

function Slot:SetTooltip(content)
    if (self.tooltip) then
        self.tooltip:SetVisible(false);
        self.tooltip:Detach();
    end
    self.tooltip = Thurallor.UI.Tooltip(content);
    self.tooltip:Attach(self.object);
end

function Slot:SetNumLabel(slotNumber)
    if (not self.numLabel) then
        local numLabel = Turbine.UI.Label();
        numLabel:SetParent(self);
        numLabel:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
        numLabel:SetFontStyle(Turbine.UI.FontStyle.Outline);
        numLabel:SetOutlineColor(Turbine.UI.Color(1, 0, 0, 0));
        numLabel:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
        numLabel:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
        numLabel:SetSize(38, 38);
        numLabel:SetZOrder(3);
        numLabel.DragDrop = function(sender, args)
            DoCallbacks(self, "DragDrop", args);
        end
        numLabel.MouseClick = function(sender, args)
            DoCallbacks(self, "MouseClick", args);
        end
        self.numLabel = numLabel;
    end
    self.numLabel:SetText(slotNumber);
    self.slotNumber = slotNumber;
end

function Slot:StartCooldown(period)
    if (period <= 0) then
        period = 0.001;
    end
    self.coolDown = period;
    self.resetTime = Turbine.Engine.GetGameTime() + period;
    if (self.textOverlay) then
        self.textOverlay:SetBackground(resources.Icon.Delay);
        self.textOverlay:SetText(nil);
    end
    self:ShowTimeRemaining(true);
    self:SetWantsUpdates(true);
end

function Slot:Update()
    if (self.info.type == "SelectTarget") then
        self:UpdateEntity();
    else
        self:ShowTimeRemaining();
    end
end

-- Reuse the numLabel layer for cooldown overlay.
function Slot:ShowTimeRemaining(starting)
    local currentTime = Turbine.Engine.GetGameTime();
    -- Check for abort ("Reset" event handler removed)
    if (not starting and not self.Reset) then
        self.resetTime = currentTime;
    end

    if (currentTime >= self.resetTime) then
        self.numLabel:SetParent(nil);
        self.numLabel = nil;
        self.resetTime = nil;
        self:SetWantsUpdates(false);
        if (self.textOverlay) then
            self.textOverlay:SetBackground(self.background);
            self.textOverlay:SetText(self.info.textOverlay);
        end
        self.hidden = self.hiddenAfterReset;
        DoCallbacks(self, "Reset");
    else
        self:SetNumLabel("");
        self.numLabel.MouseClick = nil;
        self.numLabel:SetPosition(3, 3);
        self.numLabel:SetSize(32, 32);
        local steps = resources.Icon.CoolDownEnd - resources.Icon.CoolDownStart + 1;
        local progress = 1 - (self.resetTime - currentTime) / self.coolDown;
        self.numLabel:SetBackground(resources.Icon.CoolDownStart + math.floor(progress * steps));
    end
end

function Slot:SetSelected(selected, color)
    if (not selected) then
        if (self.marquee) then
            self.marquee:SetParent(nil);
            self.marquee = nil;
        end
        return;
    end

    if (not color) then
        color = Turbine.UI.Color.White;
    end

    if (not self.marquee) then
        local marquee = Thurallor.UI.Marquee();
        marquee:SetParent(self);
        marquee:SetPosition(2, 2);
        marquee:SetSize(34, 34);
        marquee:SetMouseVisible(false);
        self.marquee = marquee;
    end
    
    self.marquee:SetColor(color);
end

function Slot:SetParent(parent)
    self.parent = parent;
    if (parent) then
        self:SetInfo(self.info);
    elseif (self.object) then
        self:MouseLeave();
        self.object:SetParent(nil);
        self.object = nil;
    end
    Turbine.UI.Control.SetParent(self, parent);
end

function Slot:DragDrop(args)
    local info = {};
    info.class = "Turbine.UI.Lotro.Quickslot";
    local newShortcut = args.DragDropInfo:GetShortcut();
    if (newShortcut) then
        info.type = newShortcut:GetType();
        info.Data = newShortcut:GetData();
        self:SetInfo(info);
        DoCallbacks(self, "ShortcutChanged", info.type, info.Data);
    end

    -- Don't remove the item/skill from the location where it was dragged from.
    args.DragDropInfo:SetSuccessful(false);
end

function Slot:MouseEnter()
    if ((self.actionEnabled) and (not self.highlight)) then
        local highlight = Turbine.UI.Control();
        highlight:SetParent(self);
        highlight:SetSize(32, 32);
        highlight:SetPosition(3, 3);
        highlight:SetZOrder(4);
        highlight:SetBlendMode(Turbine.UI.BlendMode.Overlay);
        highlight:SetBackground(resources.Icon.Highlight);
        highlight:SetMouseVisible(false);
        self.highlight = highlight;
    end
end

function Slot:MouseLeave()
    if (self.highlight) then
        self.highlight:SetParent(nil);
        self.highlight = nil;
    end
end

function Slot:MouseDown(args)
    if (args.Button == Turbine.UI.MouseButton.Left) then
        -- Drag begin.  Save the current position of the slot and mouse.
        self.mouseDown = true;
        self.mouseMoved = false;
        self.originalLeft, self.originalTop = self:PointToScreen(0, 0);
        self.originalMouseX, self.originalMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
    end
end

function Slot:MouseMove()
    if (not self.mouseDown) then
        return;
    end
    
    -- Detach from parent if we haven't already done so.
    if (not self.mouseMoved) then
        self.numLabel:SetText(nil);
        self.parent = self:GetParent();
        self.tempContainer = Turbine.UI.Window();
        self.tempContainer:SetVisible(true);
        self.tempContainer:SetSize(self:GetSize());
        self.tempContainer:SetZOrder(2147483647);
        self.tempContainer:SetOpacity(0.75);
        self:SetParent(self.tempContainer);
        self:SetPosition(0, 0);
        self.mouseMoved = true;
    end
    
    -- Drag continuing.  Find out how much the mouse has moved.
    local newMouseX, newMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
    local deltaX, deltaY = newMouseX - self.originalMouseX, newMouseY - self.originalMouseY;

    -- Move the icon and overlay.
    local left, top = self.originalLeft + deltaX, self.originalTop + deltaY;
    self.tempContainer:SetPosition(left, top);
    
    -- Show a red "X" if invalid drag location is selected.
    local centerX, centerY = left + 16, top + 16;
    if (self:DropPositionValid(centerX, centerY)) then
        self.numLabel:SetBackground(nil);
    else
        self.numLabel:SetBackground(resources.Icon.DragFail);
    end
end

function Slot:MouseUp(args)
    if (args.Button ~= Turbine.UI.MouseButton.Left) then
        return;
    end
    self.mouseDown = false;
    if (not self.mouseMoved) then
        return;
    end
    
    -- Reattach to parent.
    local left, top = self.tempContainer:GetPosition();
    self:SetParent(self.parent);
    self.tempContainer:Close();
    self.tempContainer = nil;
    self.numLabel:SetBackground(nil);
    self.numLabel:SetText(self.slotNumber);

    local centerX, centerY = left + 16, top + 16;
    self:DragDropComplete(centerX, centerY);
end

-- Event handlers that should be overridden
-- 
-- function Slot:ShortcutChanged(shortcutType, shortcutData)
--     Puts("ShortcutChanged(" .. Serialize(shortcutType) .. ", " .. Serialize(shortcutData) .. ")");
-- end
-- 
-- function Slot:MouseClick(args)
--     Puts("MouseClick(" .. Serialize(args) .. ")");
-- end
-- 
-- function Slot:MouseWheel(args)
--     Puts("MouseWheel(" .. Serialize(args) .. ")");
-- end
-- 
-- function Slot:DropPositionValid(left, top)
--     Puts("DropPositionValid(" .. tostring(left) .. ", " .. tostring(top) .. ")");
--     return true;
-- end
-- 
-- function Slot:DragDropComplete(left, top)
--     Puts("DragDropComplete(" .. tostring(left) .. ", " .. tostring(top) .. ")");
--     return true;
-- end

Compare with Previous | Blame


All times are GMT -5. The time now is 04:41 PM.


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