Manager = class(Group);
function Manager:Constructor()
Turbine.UI.Window.Constructor(self);
self.constructing = true;
self.manager = self;
self.groupID = "0";
self.objects = {};
self.eventGenerators = {};
self.eventCallbacks = {};
self.lastSaveTime = 0;
self.username = Turbine.Gameplay.LocalPlayer:GetInstance():GetName();
self.preferredBagSlot = 1;
-- Default settings
self.settings = {};
self.settings.type = "group";
self.settings.caption = {};
self.settings.snapToGrid = false;
self.settings.gridSize = 35;
self.settings.language = Turbine.Engine:GetLanguage();
local name = L:GetText("/Default/GlobalName");
self.settings.caption.text = string.gsub(name, "<name>", self.username);
self.settings.caption.width = 80;
self.settings.caption.height = 20;
self.settings.caption.font = Turbine.UI.Lotro.Font.TrajanPro15;
self.settings.color = "FFFFFF";
self.settings.barIDs = {};
self.settings.groupIDs = { "new" };
self.settings.deletedBarIDs = {};
self.settings.deletedGroupIDs = {};
self.settings.eventHandlers = {};
self.settings.eventsEnabled = false;
self.settings.groups = {};
self.settings.bars = {};
self.settings.nextObjectID = 1;
self.globals = self.settings;
self:LoadSettings();
end
function Manager:LoadSettings()
Turbine.PluginData.Load(Turbine.DataScope.Character, "SequenceBars", function(loadStr)
if (loadStr) then
-- Workaround for Turbine localization bug -- Thanks, Lynx3d!
local settings = ImportTable(loadStr);
if (not settings) then
Turbine.Shell.WriteLine("Failed to parse SequenceBars.plugindata file!");
return;
end
-- Previously-saved settings override the defaults
DeepTableCopy(settings, self.settings);
end
-- Make color object from hex string
self.color = Thurallor.Utils.Color(1, 0, 0, 0);
self.color:SetHex(self.settings.color);
-- Select language
L:SetLanguage(self.settings.language);
self:LoadBars();
self:LoadGroups();
self:UpdateOptionsPanel();
self.constructing = nil;
end);
end
function Manager:Unload()
self.lastSaveTime = 0;
self.constructing = false;
self.editingCaption = true;
self.lastSaveTime = 0; -- force save
self:SaveSettings(false);
for objectID, object in pairs(self.objects) do
--Puts("Destroying object " .. tostring(objectID));
if (object) then
object:Destroy();
end
end
end
function Manager:SaveSettings(updateOptionsPanel)
if (updateOptionsPanel) then
self.updateOptionsPanel = true;
end
if (not self.constructing) then
-- Start the idle timer.
self.lastIdleTime = Turbine.Engine.GetGameTime();
self:SetWantsUpdates(true);
end
end
function Manager:Update()
-- Save will only occur when idle time reaches 0.25 s.
local currentTime = Turbine.Engine.GetGameTime();
if (currentTime - self.lastIdleTime < 0.25) then
return;
end
--Puts("Saving...");
-- Workaround for Turbine localization bug -- Thanks, Lynx3d!
local saveData = ExportTable(self.settings);
Turbine.PluginData.Save(Turbine.DataScope.Character, "SequenceBars", saveData, function()
--Puts("Save complete.");
end);
if (self.updateOptionsPanel and (not self.editingCaption)) then
self:UpdateOptionsPanel();
self.updateOptionsPanel = false;
end
self:SetWantsUpdates(false);
end
function Manager:UpdateOptionsPanel()
if (not self.optionsPanel) then
self.optionsPanel = OptionsPanel(self);
end
self.optionsPanel:Update();
end
function Manager:FindNewObjectID()
local id = self.settings.nextObjectID;
self.settings.nextObjectID = id + 1;
id = self.username .. "." .. tostring(id);
self.objects[id] = { "reserved" };
return id;
end
function Manager:HaveTrash()
local haveTrash = (#self.settings.deletedGroupIDs > 0);
for g = 1, #self.settings.groupIDs, 1 do
local groupID = self.settings.groupIDs[g];
local object = self.objects[groupID];
if ((object) and (object:HaveTrash())) then
haveTrash = true;
end
end
return haveTrash;
end
function Manager:TransferBar(barID, oldGroup, newGroup)
local foundPos = nil;
for pos = 1, #oldGroup.settings.barIDs, 1 do
if (oldGroup.settings.barIDs[pos] == barID) then
foundPos = pos;
break;
end
end
if (foundPos) then
table.remove(oldGroup.settings.barIDs, foundPos);
table.insert(newGroup.settings.barIDs, barID);
local bar = self.objects[barID];
bar.parent = newGroup;
self:SaveSettings(true);
end
end
function Manager:TransferGroup(groupID, oldGroup, newGroup)
local foundPos = nil;
for pos = 1, #oldGroup.settings.groupIDs, 1 do
if (oldGroup.settings.groupIDs[pos] == groupID) then
foundPos = pos;
break;
end
end
if (foundPos) then
table.remove(oldGroup.settings.groupIDs, foundPos);
table.insert(newGroup.settings.groupIDs, groupID);
local group = self.objects[groupID];
group.parent = newGroup;
self:SaveSettings(true);
end
end
function Manager:EmptyTrash()
self.settings.deletedGroupIDs = {};
for groupID, settings in pairs(self.settings.groups) do
settings.deletedGroupIDs = {};
settings.deletedBarIDs = {};
if (not self.objects[groupID]) then
self.settings.groups[groupID] = nil;
end
end
for barID, bar in pairs(self.settings.bars) do
if (not self.objects[barID]) then
self.settings.bars[barID] = nil;
end
end
self:SaveSettings(false);
end
function Manager:ShowSettingsMenu(fromOptionsPanel)
-- Build the settings menu.
if (not self.settingsMenu) then
self.settingsMenu = Turbine.UI.ContextMenu();
end
Group.AddSettingsMenuItem(self, self.settingsMenu, "Root", fromOptionsPanel);
self.amSubMenu = false;
self:AddSettingsMenuItem(self.settingsMenu, "Root");
self.settingsMenu:ShowMenu();
end
function Manager:AddSettingsMenuItem(parent, itemName, amSubMenu)
if (amSubMenu ~= nil) then
self.amSubMenu = amSubMenu;
end
local item = Turbine.UI.MenuItem(L:GetText(itemName), true, false);
parent:GetItems():Add(item);
if (itemName == "Root") then
local prevContext = L:SetContext("/GlobalMenu");
parent:GetItems():Clear();
self:AddSettingsMenuItem(parent, "HideAll");
if (not self.amSubMenu) then
L:SetContext("/GroupMenu");
Group.AddSettingsMenuItem(self, parent, "CreateNewBar");
Group.AddSettingsMenuItem(self, parent, "CreateNewSubgroup");
Group.AddSettingsMenuItem(self, parent, "Import");
end
if (#self.settings.deletedBarIDs + #self.settings.deletedGroupIDs > 0) then
self:AddSettingsMenuItem(parent, "Undelete");
end
L:SetContext("/GroupMenu");
Group.AddSettingsMenuItem(self, parent, "ArrangeBars");
Group.AddSettingsMenuItem(self, parent, "EventBehaviors");
L:SetContext("/GlobalMenu");
self:AddSettingsMenuItem(parent, "GlobalSettings");
if (self:HaveTrash()) then
self:AddSettingsMenuItem(parent, "EmptyTrash");
end
L:SetContext(prevContext);
elseif (itemName == "HideAll") then
item:SetChecked(self.settings.hidden);
item.Click = function(sender, args)
self:SetHidden(not self.settings.hidden);
end
elseif (itemName == "GlobalSettings") then
local prevContext = L:SetContext("/GlobalMenu/GlobalSettingsMenu");
self:AddSettingsMenuItem(item, "SnapToGrid");
self:AddSettingsMenuItem(item, "Language");
L:SetContext(prevContext);
elseif (itemName == "SnapToGrid") then
item:SetChecked(self.settings.snapToGrid);
item.Click = function(sender, args)
self.settings.snapToGrid = not self.settings.snapToGrid;
if (self.settings.snapToGrid) then
self:SnapToGrid();
end
end
elseif (itemName == "Language") then
local prevContext = L:SetContext("LanguageMenu");
self:AddSettingsMenuItem(item, "English");
self:AddSettingsMenuItem(item, "French");
self:AddSettingsMenuItem(item, "German");
self:AddSettingsMenuItem(item, "Russian");
L:SetContext(prevContext);
elseif (string.find("English|French|German|Russian", itemName)) then
local checked = (L:GetLanguage() == Turbine.Language[itemName]);
item:SetChecked(checked);
item:SetEnabled(not checked);
item.Click = function(sender, args)
local language = Turbine.Language[itemName];
self.settings.language = language;
L:SetLanguage(language);
self:SaveSettings(true);
end
elseif (itemName == "EmptyTrash") then
item.Click = function(sender, args)
self:EmptyTrash();
end
else
-- Item is not handled here; send it to Group:AddSettingsMenuItem().
parent:GetItems():RemoveAt(parent:GetItems():GetCount());
Group.AddSettingsMenuItem(self, parent, itemName, true);
end
end
function Manager:GetNearestGridPos(left, top)
local gridSize = self.settings.gridSize;
local displayBottom = Turbine.UI.Display:GetHeight() - 1;
local centerLeft = math.floor(0.5 + Turbine.UI.Display:GetWidth() / 2 + gridSize / 2) + 3;
local offsetLeft, offsetTop = left - centerLeft, displayBottom - top;
local newLeft = centerLeft + math.floor(0.5 + offsetLeft / gridSize) * gridSize;
local newTop = displayBottom - math.floor(0.5 + offsetTop / gridSize) * gridSize;
return newLeft, newTop;
end
function Manager:SetUnequipDestination(bagSlot)
self.preferredBagSlot = bagSlot;
end
function Manager:Unequip(itemSlot)
local lp = Turbine.Gameplay.LocalPlayer:GetInstance();
local equippedItems = lp:GetEquipment();
local item = equippedItems:GetItem(itemSlot);
if (item ~= nil) then
_G.Unequip(itemSlot, "*", self.preferredBagSlot);
end
end
function Manager:AddEventGenerator(object, eventName)
if (not self.eventGenerators[eventName]) then
self.eventGenerators[eventName] = {};
end
table.insert(self.eventGenerators[eventName], object);
local generatorID = #self.eventGenerators[eventName];
--Puts("Adding event generator " .. tostring(generatorID) .. " for event " .. Serialize(eventName) .. " from object " .. Serialize(object.settings.caption.text));
return generatorID;
end
function Manager:RemoveEventGenerator(generatorID, eventName)
local object = self.eventGenerators[eventName][generatorID];
--Puts("Removing event generator " .. tostring(generatorID) .. " for event " .. Serialize(eventName) .. " (was from object " .. Serialize(object.settings.caption.text));
table.remove(self.eventGenerators[eventName], generatorID);
if (#self.eventGenerators[eventName] == 0) then
self.eventGenerators[eventName] = nil;
end
end
-- Returns a list of bars that generates the specified event
function Manager:GetEventGenerators(eventName)
return self.eventGenerators[eventName];
end
-- Returns the names of all of the events generated by all bars
function Manager:GetEventNames()
local eventNames = {};
for k in keys(self.eventGenerators) do
table.insert(eventNames, k);
end
return eventNames;
end
function Manager:GetEventCallbacks()
return self.eventCallbacks;
end
function Manager:PropagateEvent(eventName)
local callbacks = self.eventCallbacks[eventName];
if (type(callbacks) == "table") then
--Puts("Propagating event \"" .. tostring(eventName) .. "\" to " .. tostring(#callbacks) .. " callback functions: " .. Serialize(callbacks));
for f = 1, #callbacks do
local func = callbacks[f];
func(eventName);
end
elseif (type(callbacks) == "function") then
--Puts("Propagating event \"" .. tostring(eventName) .. "\" to a single callback function: " .. Serialize(callbacks));
callbacks(eventName);
end
end