Slot = class(Turbine.UI.Control);
function Slot:Constructor(info)
Turbine.UI.Control.Constructor(self);
self:SetMouseVisible(false);
self:SetSize(36, 36);
self:SetInfo(info);
self:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
Turbine.UI.Control.SetAllowDrop(self, false);
end
function Slot:GetInfo()
return self.info;
end
function Slot:GetItem()
if (self.object.GetItem) then
return self.object:GetItem();
end
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: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);
object:SetUseOnRightClick(false);
object.MouseClick = function(sender, args)
DoCallbacks(self, "MouseClick", args);
end
self.object = object;
end
self.object:SetShortcut(Turbine.UI.Lotro.Shortcut(info.type, info.Data));
self.isQuickslot = true;
self.object.DragDrop = function(sender)
sender:SetShortcut(Turbine.UI.Lotro.Shortcut(self.info.type, self.info.Data));
end
elseif (info.class == "Turbine.UI.Control") then
if (not self.object) then
local object = Turbine.UI.Control();
object:SetParent(self);
object:SetSize(32, 32);
object:SetPosition(3, 3);
object:SetZOrder(1);
object.MouseClick = function(sender, args)
DoCallbacks(self, "MouseClick", args);
end
object.MouseEnter = function(sender)
DoCallbacks(self, "MouseEnter");
end
object.MouseLeave = function(sender)
DoCallbacks(self, "MouseLeave");
end
self.object = object;
end
self.isQuickslot = false;
end
-- 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
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;
self.textOverlay:SetBackground(resources.Icon.Delay);
self.textOverlay:SetText(nil);
self:ShowTimeRemaining();
self:SetWantsUpdates(true);
end
function Slot:Update()
self:ShowTimeRemaining();
end
-- Reuse the numLabel layer for cooldown overlay.
function Slot:ShowTimeRemaining()
local currentTime = Turbine.Engine.GetGameTime();
if (currentTime >= self.resetTime) then
self.numLabel:SetParent(nil);
self.numLabel = nil;
self.resetTime = nil;
self:SetWantsUpdates(false);
self.textOverlay:SetBackground(self.background);
self.textOverlay:SetText(self.info.textOverlay);
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;
self:SetWantsUpdates(false);
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);
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: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