lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [SequenceBars/] [Manager.lua] - Blame information for rev 169

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

Line No. Rev Author Line
1 2 Thurallor-7095
Manager = class(Group);
2 Thurallor-7095
 
3 Thurallor-7095
function Manager:Constructor()
4 Thurallor-7095
    Turbine.UI.Window.Constructor(self);
5 Thurallor-7095
    self.constructing = true;
6 Thurallor-7095
 
7 Thurallor-7095
    self.manager = self;
8 20 Thurallor-7095
    self.watcher = Thurallor.Utils.Watcher;
9 2 Thurallor-7095
    self.groupID = "0";
10 Thurallor-7095
 
11 Thurallor-7095
    self.objects = {};
12 Thurallor-7095
    self.eventGenerators = {};
13 Thurallor-7095
    self.eventCallbacks = {};
14 16 Thurallor-7095
    self.propagatingEvent = {};
15 12 Thurallor-7095
    self.player = Turbine.Gameplay.LocalPlayer:GetInstance();
16 Thurallor-7095
    self.username = self.player:GetName();
17 122 Thurallor-7095
    self:SetUnequipDestination("1..." .. tostring(self.player:GetBackpack():GetSize()));
18 13 Thurallor-7095
    self.hudVisible = true;
19 16 Thurallor-7095
    self.includees = {};
20 Thurallor-7095
    self.includers = {};
21 143 Thurallor-7095
    self.lastActionTime = 0;
22 Thurallor-7095
    self.mouseX, self.mouseY = Turbine.UI.Display.GetMousePosition();
23 Thurallor-7095
 
24 2 Thurallor-7095
    -- Default settings
25 Thurallor-7095
    self.settings = {};
26 Thurallor-7095
    self.settings.type = "group";
27 Thurallor-7095
    self.settings.caption = {};
28 Thurallor-7095
    self.settings.snapToGrid = false;
29 Thurallor-7095
    self.settings.gridSize = 35;
30 Thurallor-7095
    self.settings.language = Turbine.Engine:GetLanguage();
31 Thurallor-7095
    local name = L:GetText("/Default/GlobalName");
32 Thurallor-7095
    self.settings.caption.text = string.gsub(name, "<name>", self.username);
33 Thurallor-7095
    self.settings.caption.width = 80;
34 Thurallor-7095
    self.settings.caption.height = 20;
35 Thurallor-7095
    self.settings.caption.font = Turbine.UI.Lotro.Font.TrajanPro15;
36 Thurallor-7095
    self.settings.color = "FFFFFF";
37 Thurallor-7095
    self.settings.barIDs = {};
38 Thurallor-7095
    self.settings.groupIDs = { "new" };
39 Thurallor-7095
    self.settings.deletedBarIDs = {};
40 Thurallor-7095
    self.settings.deletedGroupIDs = {};
41 Thurallor-7095
    self.settings.eventHandlers = {};
42 Thurallor-7095
    self.settings.eventsEnabled = false;
43 Thurallor-7095
    self.settings.groups = {};
44 Thurallor-7095
    self.settings.bars = {};
45 Thurallor-7095
    self.settings.nextObjectID = 1;
46 16 Thurallor-7095
    self.settings.pluginVersion = plugin:GetVersion();
47 Thurallor-7095
    self.settings.uiScale = 32; -- zoom level will be applied to make quickslots this size
48 Thurallor-7095
    self.settings.uiOpacity = 1.0;
49 30 Thurallor-7095
 
50 27 Thurallor-7095
    self.settings.displaySize = { Turbine.UI.Display.GetSize() };
51 2 Thurallor-7095
    self.globals = self.settings;
52 Thurallor-7095
    self:LoadSettings();
53 Thurallor-7095
end
54 Thurallor-7095
 
55 Thurallor-7095
function Manager:LoadSettings()
56 Thurallor-7095
    Turbine.PluginData.Load(Turbine.DataScope.Character, "SequenceBars", function(loadStr)
57 Thurallor-7095
        if (loadStr) then
58 162 Thurallor-7095
            -- Save backup
59 Thurallor-7095
            loadStr.backupTime = "#" .. Turbine.Engine.GetGameTime();
60 Thurallor-7095
            local dateInfo = Turbine.Engine.GetDate();
61 Thurallor-7095
            Turbine.PluginData.Save(Turbine.DataScope.Character, "SequenceBars_backup" .. dateInfo.DayOfWeek, loadStr);
62 Thurallor-7095
 
63 2 Thurallor-7095
            -- Workaround for Turbine localization bug -- Thanks, Lynx3d!
64 Thurallor-7095
            local settings = ImportTable(loadStr);
65 Thurallor-7095
            if (not settings) then
66 Thurallor-7095
                Turbine.Shell.WriteLine("Failed to parse SequenceBars.plugindata file!");
67 Thurallor-7095
                return;
68 Thurallor-7095
            end
69 Thurallor-7095
 
70 Thurallor-7095
            -- Previously-saved settings override the defaults
71 Thurallor-7095
            DeepTableCopy(settings, self.settings);
72 Thurallor-7095
        end
73 Thurallor-7095
 
74 Thurallor-7095
        -- Make color object from hex string
75 Thurallor-7095
        self.color = Thurallor.Utils.Color(1, 0, 0, 0);
76 Thurallor-7095
        self.color:SetHex(self.settings.color);
77 13 Thurallor-7095
 
78 2 Thurallor-7095
        -- Select language
79 18 Thurallor-7095
        self:SetLanguage(self.settings.language);
80 44 Thurallor-7095
 
81 Thurallor-7095
        _G.manualUpdatesNeeded = "";
82 2 Thurallor-7095
        self:LoadBars();
83 Thurallor-7095
        self:LoadGroups();
84 Thurallor-7095
        self:UpdateOptionsPanel();
85 7 Thurallor-7095
        self.settings.pluginVersion = tonumber(Plugins.SequenceBars:GetVersion());
86 2 Thurallor-7095
        self.constructing = nil;
87 7 Thurallor-7095
 
88 44 Thurallor-7095
        if (#_G.manualUpdatesNeeded > 0) then
89 Thurallor-7095
            _G.manualUpdatesNeeded = "Since you have upgraded to a new version of SequenceBars, your settings file needs to be updated.  The following item(s) cannot be updated automatically, so you will have to do it yourself:\n\n" .. _G.manualUpdatesNeeded;
90 Thurallor-7095
            Alert("Settings File Updated", _G.manualUpdatesNeeded, nil, Turbine.UI.Lotro.Font.Verdana14);
91 Thurallor-7095
            _G.manualUpdatesNeeded = "";
92 Thurallor-7095
        end
93 Thurallor-7095
 
94 13 Thurallor-7095
        self:SetWantsKeyEvents(true);
95 16 Thurallor-7095
        self:SetWantsEvents(self.settings.eventsEnabled);
96 Thurallor-7095
 
97 Thurallor-7095
        self.displaySizeCallback = function(display)
98 26 Thurallor-7095
            self.anchorCoords = nil;
99 127 Thurallor-7095
            self:SetGridDisplayEnable(self.showGrid);
100 16 Thurallor-7095
        end
101 Thurallor-7095
        AddCallback(Turbine.UI.Display, "SizeChanged", self.displaySizeCallback);
102 Thurallor-7095
 
103 28 Thurallor-7095
        -- In case the display size changed since the last time the plugin was used:
104 Thurallor-7095
        self.anchorCoords = nil;
105 Thurallor-7095
        self:SetWantsUpdates(true);
106 Thurallor-7095
 
107 7 Thurallor-7095
        self:PropagateEvent("Startup\n");
108 2 Thurallor-7095
    end);
109 Thurallor-7095
end
110 Thurallor-7095
 
111 Thurallor-7095
function Manager:Unload()
112 143 Thurallor-7095
    self:DoSave();
113 2 Thurallor-7095
    self.constructing = false;
114 Thurallor-7095
    self.editingCaption = true;
115 35 Thurallor-7095
 
116 Thurallor-7095
    -- The following may appear pointless, but failure to clean up (e.g. not unregistering event handlers) can cause crashes.
117 2 Thurallor-7095
    for objectID, object in pairs(self.objects) do
118 Thurallor-7095
--Puts("Destroying object " .. tostring(objectID));
119 Thurallor-7095
        if (object) then
120 Thurallor-7095
            object:Destroy();
121 Thurallor-7095
        end
122 Thurallor-7095
    end
123 Thurallor-7095
end
124 Thurallor-7095
 
125 Thurallor-7095
function Manager:SaveSettings(updateOptionsPanel)
126 Thurallor-7095
    if (updateOptionsPanel) then
127 Thurallor-7095
        self.updateOptionsPanel = true;
128 Thurallor-7095
    end
129 Thurallor-7095
    if (not self.constructing) then
130 Thurallor-7095
        -- Start the idle timer.
131 143 Thurallor-7095
        self.lastActionTime = Turbine.Engine.GetGameTime();
132 144 Thurallor-7095
        self.waitingForIdle = true;
133 147 Thurallor-7095
        self:SetWantsUpdates(true);
134 2 Thurallor-7095
    end
135 Thurallor-7095
end
136 Thurallor-7095
 
137 Thurallor-7095
function Manager:Update()
138 108 Thurallor-7095
 
139 Thurallor-7095
    -- Propagate queued events
140 Thurallor-7095
    if (next(self.propagatingEvent)) then
141 Thurallor-7095
        local events = self.propagatingEvent;
142 Thurallor-7095
        self.propagatingEvent = {};
143 Thurallor-7095
        for eventName, _ in pairs(events) do
144 Thurallor-7095
            DoCallbacks(self.eventCallbacks, eventName, eventName);
145 Thurallor-7095
        end
146 Thurallor-7095
    end
147 Thurallor-7095
 
148 Thurallor-7095
    -- Adjust bar layout based on new screen size
149 28 Thurallor-7095
    if (not self.anchorCoords) then
150 Thurallor-7095
        local speed = 0.2;
151 Thurallor-7095
        local prevWidth, prevHeight = unpack(self.settings.displaySize);
152 Thurallor-7095
        local width, height = Turbine.UI.Display:GetSize();
153 Thurallor-7095
        local newWidth = prevWidth + (width - prevWidth) * speed;
154 Thurallor-7095
        local newHeight = prevHeight + (height - prevHeight) * speed;
155 Thurallor-7095
        if (math.abs(newWidth - width) < 1) then
156 Thurallor-7095
            newWidth = width;
157 Thurallor-7095
        end
158 Thurallor-7095
        if (math.abs(newHeight - height) < 1) then
159 Thurallor-7095
            newHeight = height;
160 Thurallor-7095
        end
161 Thurallor-7095
        self.settings.displaySize = { newWidth, newHeight };
162 Thurallor-7095
        self:SaveSettings(false);
163 34 Thurallor-7095
        self:Redraw(true);
164 28 Thurallor-7095
        if ((newWidth ~= width) or (newHeight ~= height)) then
165 Thurallor-7095
            self.anchorCoords = nil;
166 Thurallor-7095
        end
167 Thurallor-7095
    end
168 108 Thurallor-7095
 
169 144 Thurallor-7095
    if (self.waitingForIdle) then
170 143 Thurallor-7095
        -- Mouse movements mean we're not idle
171 Thurallor-7095
        mouseX, mouseY = Turbine.UI.Display.GetMousePosition();
172 Thurallor-7095
        if ((mouseX ~= self.mouseX) or (mouseY ~= self.mouseY) or self.mouseLooking) then
173 Thurallor-7095
            self.lastActionTime = Turbine.Engine.GetGameTime();
174 Thurallor-7095
        end
175 Thurallor-7095
        self.mouseX, self.mouseY = mouseX, mouseY;
176 Thurallor-7095
 
177 144 Thurallor-7095
        local currentTime = Turbine.Engine.GetGameTime();
178 Thurallor-7095
        -- Options panel updates will occur when idle time reaches 0.25 s
179 Thurallor-7095
        if (self.updateOptionsPanel) then
180 Thurallor-7095
            if (currentTime >= self.lastActionTime + 0.25) then
181 Thurallor-7095
                if (not self.editingCaption) then
182 Thurallor-7095
                    self:UpdateOptionsPanel();
183 Thurallor-7095
                    self.updateOptionsPanel = false;
184 Thurallor-7095
                end
185 Thurallor-7095
            end
186 Thurallor-7095
 
187 143 Thurallor-7095
        -- Save will only occur when idle time reaches 10 s, and never in combat.
188 144 Thurallor-7095
        elseif ((currentTime >= self.lastActionTime + 10) and not self.player:IsInCombat()) then
189 162 Thurallor-7095
-- 14-Jul-2020: Data will now only be saved at logout.  Attempt to address occasional crashes that may be associated with frequent saving.
190 Thurallor-7095
--            self:DoSave();
191 144 Thurallor-7095
            self.waitingForIdle = false;
192 108 Thurallor-7095
        end
193 28 Thurallor-7095
    end
194 16 Thurallor-7095
end
195 2 Thurallor-7095
 
196 16 Thurallor-7095
function Manager:DoSave()
197 2 Thurallor-7095
--Puts("Saving...");
198 Thurallor-7095
    -- Workaround for Turbine localization bug -- Thanks, Lynx3d!
199 Thurallor-7095
    local saveData = ExportTable(self.settings);
200 143 Thurallor-7095
    Turbine.PluginData.Save(Turbine.DataScope.Character, "SequenceBars", saveData, function()
201 Thurallor-7095
--Puts("Save complete.");
202 Thurallor-7095
    end);
203 2 Thurallor-7095
end
204 Thurallor-7095
 
205 Thurallor-7095
function Manager:UpdateOptionsPanel()
206 Thurallor-7095
    if (not self.optionsPanel) then
207 Thurallor-7095
        self.optionsPanel = OptionsPanel(self);
208 Thurallor-7095
    end
209 12 Thurallor-7095
    self.optionsPanel:RefreshDirectory();
210 2 Thurallor-7095
end
211 Thurallor-7095
 
212 13 Thurallor-7095
function Manager:KeyDown(args)
213 143 Thurallor-7095
    -- Keypresses (and mouse-looks) mean we're not idle
214 Thurallor-7095
    self.lastActionTime = Turbine.Engine.GetGameTime();
215 Thurallor-7095
 
216 Thurallor-7095
    if (args.Action == Turbine.UI.Lotro.Action.RotateCharacter) then
217 Thurallor-7095
        self.mouseLooking = true;
218 Thurallor-7095
    end
219 Thurallor-7095
 
220 Thurallor-7095
    -- Respond to toggle UI command (usually F12)
221 13 Thurallor-7095
    if (args.Action == Turbine.UI.Lotro.Action.ToggleHUD) then
222 Thurallor-7095
        self.hudVisible = not self.hudVisible;
223 Thurallor-7095
        self:ApplyHiddenness();
224 Thurallor-7095
    end
225 Thurallor-7095
end
226 Thurallor-7095
 
227 143 Thurallor-7095
function Manager:KeyUp(args)
228 Thurallor-7095
    -- Keypresses (and mouse-looks) mean we're not idle
229 Thurallor-7095
    self.lastActionTime = Turbine.Engine.GetGameTime();
230 Thurallor-7095
 
231 Thurallor-7095
    if (args.Action == Turbine.UI.Lotro.Action.RotateCharacter) then
232 Thurallor-7095
        self.mouseLooking = false;
233 Thurallor-7095
    end
234 Thurallor-7095
end
235 Thurallor-7095
 
236 13 Thurallor-7095
function Manager:IsParentHidden()
237 Thurallor-7095
    return (not self.hudVisible);
238 Thurallor-7095
end
239 Thurallor-7095
 
240 7 Thurallor-7095
function Manager:ShellCommand(cmd, args)
241 Thurallor-7095
    if (string.match(args, "^" .. L:GetText("/ShellCommand/Options"))) then
242 13 Thurallor-7095
        self.optionsPanel:ShowGlobalSettings();
243 7 Thurallor-7095
    elseif (string.match(args, "^" .. L:GetText("/ShellCommand/Events"))) then
244 Thurallor-7095
        local eventNames = self:GetEventNames();
245 Thurallor-7095
        if (#eventNames > 0) then
246 Thurallor-7095
            Puts(table.concat(eventNames, "\n"));
247 Thurallor-7095
        end
248 Thurallor-7095
    elseif (string.match(args, "^" .. L:GetText("/ShellCommand/Event"))) then
249 Thurallor-7095
        local eventName = string.sub(args, string.find(args, " ") + 1);
250 Thurallor-7095
        Puts(" -> \"" .. eventName .. "\"");
251 Thurallor-7095
        self:PropagateEvent(eventName);
252 143 Thurallor-7095
    elseif (string.match(args, "^" .. L:GetText("/ShellCommand/Sort"))) then
253 122 Thurallor-7095
        local slots = string.sub(args, string.find(args, " ") + 1);
254 Thurallor-7095
        local series = Thurallor.Utils.Series(slots);
255 Thurallor-7095
        local backpack = Thurallor.Utils.Watcher.playerBackpackObject;
256 Thurallor-7095
        local safety = backpack:GetSize();
257 Thurallor-7095
        local items = {};
258 Thurallor-7095
        local function comp(a, b)
259 Thurallor-7095
            if (a:GetCategory() > b:GetCategory()) then
260 Thurallor-7095
                return true;
261 Thurallor-7095
            elseif (a:GetCategory() == b:GetCategory()) then
262 Thurallor-7095
                if (a:GetIconImageID() > b:GetIconImageID()) then
263 Thurallor-7095
                    return true;
264 Thurallor-7095
                elseif (a:GetIconImageID() == b:GetIconImageID()) then
265 Thurallor-7095
                    if (a:GetName() < b:GetName()) then
266 Thurallor-7095
                        return true;
267 Thurallor-7095
                    elseif (a:GetName() == b:GetName()) then
268 Thurallor-7095
                        if (a:GetQuantity() > b:GetQuantity()) then
269 Thurallor-7095
                            return true;
270 Thurallor-7095
                        end
271 Thurallor-7095
                    end
272 Thurallor-7095
                end
273 Thurallor-7095
            end
274 Thurallor-7095
            return false;
275 Thurallor-7095
        end
276 Thurallor-7095
        for bpSlot in series:numbers(safety) do
277 Thurallor-7095
            local item = backpack:GetItem(bpSlot);
278 Thurallor-7095
            if (item) then
279 Thurallor-7095
                item.slot = bpSlot;
280 Thurallor-7095
                table.insert(items, item);
281 Thurallor-7095
            end
282 Thurallor-7095
            table.sort(items, comp);
283 Thurallor-7095
        end
284 Thurallor-7095
        for bpSlot in series:numbers(safety) do
285 Thurallor-7095
            local item = table.remove(items, 1);
286 Thurallor-7095
            if (item and (item.slot ~= bpSlot)) then
287 Thurallor-7095
                backpack:PerformItemDrop(item, bpSlot, false);
288 Thurallor-7095
            end
289 Thurallor-7095
        end
290 Thurallor-7095
    else
291 Thurallor-7095
        -- Unknown command.
292 Thurallor-7095
        return false;
293 7 Thurallor-7095
    end
294 122 Thurallor-7095
    return true;
295 7 Thurallor-7095
end
296 Thurallor-7095
 
297 2 Thurallor-7095
function Manager:FindNewObjectID()
298 Thurallor-7095
    local id = self.settings.nextObjectID;
299 Thurallor-7095
    self.settings.nextObjectID = id + 1;
300 Thurallor-7095
    id = self.username .. "." .. tostring(id);
301 Thurallor-7095
    self.objects[id] = { "reserved" };
302 Thurallor-7095
    return id;
303 Thurallor-7095
end
304 Thurallor-7095
 
305 16 Thurallor-7095
function Manager:GetObject(objectID)
306 Thurallor-7095
    return self.objects[objectID];
307 Thurallor-7095
end
308 Thurallor-7095
 
309 2 Thurallor-7095
function Manager:TransferBar(barID, oldGroup, newGroup)
310 20 Thurallor-7095
    local foundPos = Search(oldGroup.settings.barIDs, barID);
311 2 Thurallor-7095
    if (foundPos) then
312 Thurallor-7095
        table.remove(oldGroup.settings.barIDs, foundPos);
313 Thurallor-7095
        table.insert(newGroup.settings.barIDs, barID);
314 Thurallor-7095
        local bar = self.objects[barID];
315 Thurallor-7095
        bar.parent = newGroup;
316 Thurallor-7095
        self:SaveSettings(true);
317 13 Thurallor-7095
        newGroup:ApplyHiddenness();
318 2 Thurallor-7095
    end
319 Thurallor-7095
end
320 Thurallor-7095
 
321 Thurallor-7095
function Manager:TransferGroup(groupID, oldGroup, newGroup)
322 20 Thurallor-7095
    local foundPos = Search(oldGroup.settings.groupIDs, groupID);
323 2 Thurallor-7095
    if (foundPos) then
324 Thurallor-7095
        table.remove(oldGroup.settings.groupIDs, foundPos);
325 Thurallor-7095
        table.insert(newGroup.settings.groupIDs, groupID);
326 Thurallor-7095
        local group = self.objects[groupID];
327 Thurallor-7095
        group.parent = newGroup;
328 Thurallor-7095
        self:SaveSettings(true);
329 13 Thurallor-7095
        newGroup:ApplyHiddenness();
330 2 Thurallor-7095
    end
331 Thurallor-7095
end
332 Thurallor-7095
 
333 Thurallor-7095
function Manager:EmptyTrash()
334 Thurallor-7095
    self.settings.deletedGroupIDs = {};
335 Thurallor-7095
    for groupID, settings in pairs(self.settings.groups) do
336 Thurallor-7095
        settings.deletedGroupIDs = {};
337 Thurallor-7095
        settings.deletedBarIDs = {};
338 Thurallor-7095
        if (not self.objects[groupID]) then
339 Thurallor-7095
            self.settings.groups[groupID] = nil;
340 Thurallor-7095
        end
341 Thurallor-7095
    end
342 7 Thurallor-7095
    self.settings.deletedBarIDs = {};
343 2 Thurallor-7095
    for barID, bar in pairs(self.settings.bars) do
344 Thurallor-7095
        if (not self.objects[barID]) then
345 Thurallor-7095
            self.settings.bars[barID] = nil;
346 Thurallor-7095
        end
347 Thurallor-7095
    end
348 Thurallor-7095
    self:SaveSettings(false);
349 Thurallor-7095
end
350 Thurallor-7095
 
351 5 Thurallor-7095
function Manager:ShowSettingsMenu(fromOptionsPanel)
352 2 Thurallor-7095
    -- Build the settings menu.
353 18 Thurallor-7095
    self.settingsMenu = Turbine.UI.ContextMenu();
354 5 Thurallor-7095
    Group.AddSettingsMenuItem(self, self.settingsMenu, "Root", fromOptionsPanel);
355 2 Thurallor-7095
    self.amSubMenu = false;
356 Thurallor-7095
    self:AddSettingsMenuItem(self.settingsMenu, "Root");
357 Thurallor-7095
    self.settingsMenu:ShowMenu();
358 Thurallor-7095
end
359 Thurallor-7095
 
360 Thurallor-7095
function Manager:AddSettingsMenuItem(parent, itemName, amSubMenu)
361 Thurallor-7095
    if (amSubMenu ~= nil) then
362 Thurallor-7095
        self.amSubMenu = amSubMenu;
363 Thurallor-7095
    end
364 Thurallor-7095
    local item = Turbine.UI.MenuItem(L:GetText(itemName), true, false);
365 Thurallor-7095
    parent:GetItems():Add(item);
366 18 Thurallor-7095
 
367 2 Thurallor-7095
    if (itemName == "Root") then
368 Thurallor-7095
        local prevContext = L:SetContext("/GlobalMenu");
369 Thurallor-7095
        parent:GetItems():Clear();
370 Thurallor-7095
        self:AddSettingsMenuItem(parent, "HideAll");
371 Thurallor-7095
        if (not self.amSubMenu) then
372 Thurallor-7095
            L:SetContext("/GroupMenu");
373 Thurallor-7095
            Group.AddSettingsMenuItem(self, parent, "CreateNewBar");
374 Thurallor-7095
            Group.AddSettingsMenuItem(self, parent, "CreateNewSubgroup");
375 Thurallor-7095
            Group.AddSettingsMenuItem(self, parent, "Import");
376 Thurallor-7095
        end
377 Thurallor-7095
        if (#self.settings.deletedBarIDs + #self.settings.deletedGroupIDs > 0) then
378 Thurallor-7095
            self:AddSettingsMenuItem(parent, "Undelete");
379 Thurallor-7095
        end
380 Thurallor-7095
        L:SetContext("/GroupMenu");
381 Thurallor-7095
        Group.AddSettingsMenuItem(self, parent, "ArrangeBars");
382 12 Thurallor-7095
        Group.AddSettingsMenuItem(self, parent, "GlobalEventBehaviors");
383 2 Thurallor-7095
        L:SetContext("/GlobalMenu");
384 Thurallor-7095
        self:AddSettingsMenuItem(parent, "GlobalSettings");
385 Thurallor-7095
        if (self:HaveTrash()) then
386 Thurallor-7095
            self:AddSettingsMenuItem(parent, "EmptyTrash");
387 Thurallor-7095
        end
388 Thurallor-7095
        L:SetContext(prevContext);
389 Thurallor-7095
    elseif (itemName == "HideAll") then
390 Thurallor-7095
        item:SetChecked(self.settings.hidden);
391 121 Thurallor-7095
        item.Click = function()
392 2 Thurallor-7095
            self:SetHidden(not self.settings.hidden);
393 Thurallor-7095
        end
394 Thurallor-7095
    elseif (itemName == "GlobalSettings") then
395 121 Thurallor-7095
        item.Click = function()
396 12 Thurallor-7095
            self.optionsPanel:ShowGlobalSettings();
397 2 Thurallor-7095
        end
398 Thurallor-7095
    elseif (itemName == "EmptyTrash") then
399 121 Thurallor-7095
        item.Click = function()
400 2 Thurallor-7095
            self:EmptyTrash();
401 Thurallor-7095
        end
402 Thurallor-7095
    else
403 Thurallor-7095
        -- Item is not handled here; send it to Group:AddSettingsMenuItem().
404 Thurallor-7095
        parent:GetItems():RemoveAt(parent:GetItems():GetCount());
405 Thurallor-7095
        Group.AddSettingsMenuItem(self, parent, itemName, true);
406 Thurallor-7095
    end
407 139 Thurallor-7095
    return item;
408 2 Thurallor-7095
end
409 Thurallor-7095
 
410 158 Thurallor-7095
function Manager:GetNearestGridPos(left, top, uiScale)
411 Thurallor-7095
    local gridSize = math.floor(0.5 + self.settings.gridSize * (uiScale / 32));
412 2 Thurallor-7095
    local displayBottom = Turbine.UI.Display:GetHeight() - 1;
413 Thurallor-7095
    local centerLeft = math.floor(0.5 + Turbine.UI.Display:GetWidth() / 2 + gridSize / 2) + 3;
414 Thurallor-7095
    local offsetLeft, offsetTop = left - centerLeft, displayBottom - top;
415 Thurallor-7095
    local newLeft = centerLeft + math.floor(0.5 + offsetLeft / gridSize) * gridSize;
416 Thurallor-7095
    local newTop = displayBottom - math.floor(0.5 + offsetTop / gridSize) * gridSize;
417 16 Thurallor-7095
    return newLeft, newTop, gridSize;
418 2 Thurallor-7095
end
419 Thurallor-7095
 
420 26 Thurallor-7095
function Manager:GetAnchorPosition(anchor)
421 Thurallor-7095
    if (not self.anchorCoords) then
422 28 Thurallor-7095
        local width, height = unpack (self.settings.displaySize);
423 26 Thurallor-7095
        local center = math.floor(0.5 + width / 2);
424 Thurallor-7095
        local middle = math.floor(0.5 + height / 2);
425 Thurallor-7095
        self.anchorCoords = {
426 Thurallor-7095
            TopLeft    = { 0, 0      }; TopCenter    = { center, 0      }; TopRight    = { width, 0      };
427 Thurallor-7095
            MiddleLeft = { 0, middle }; MiddleCenter = { center, middle }; MiddleRight = { width, middle };
428 Thurallor-7095
            BottomLeft = { 0, height }; BottomCenter = { center, height }; BottomRight = { width, height };
429 Thurallor-7095
        }
430 Thurallor-7095
    end
431 Thurallor-7095
    return unpack(self.anchorCoords[anchor]);
432 Thurallor-7095
end
433 Thurallor-7095
 
434 122 Thurallor-7095
function Manager:SetUnequipDestination(bagSlots)
435 Thurallor-7095
    self.preferredBagSlots = bagSlots;
436 Thurallor-7095
    self.preferredBagSlotSeries = Thurallor.Utils.Series(bagSlots);
437 6 Thurallor-7095
end
438 Thurallor-7095
 
439 122 Thurallor-7095
function Manager:Unequip(eqSlot)
440 Thurallor-7095
    local _, item = Thurallor.Utils.Watcher.GetEquippedItem(nil, eqSlot);
441 Thurallor-7095
    if (item == nil) then
442 Thurallor-7095
        return;
443 Thurallor-7095
    end
444 Thurallor-7095
 
445 Thurallor-7095
    local preferred_slots = self.preferredBagSlotSeries;
446 Thurallor-7095
    local backpack = Thurallor.Utils.Watcher.playerBackpackObject;
447 155 Thurallor-7095
    if (not backpack.cache) then
448 Thurallor-7095
        self.watcher.GetItemQuantity(nil); -- force cache hit
449 Thurallor-7095
    end
450 122 Thurallor-7095
    if (backpack.cache.recentlyFilled == nil) then
451 Thurallor-7095
        backpack.cache.recentlyFilled = {}; -- cache for keeping track of changes between ticks
452 Thurallor-7095
    end
453 142 Thurallor-7095
    local function trySlot(bpSlot)
454 122 Thurallor-7095
        if (not (backpack.cache.recentlyFilled[bpSlot] or backpack:GetItem(bpSlot))) then
455 Thurallor-7095
            backpack:PerformItemDrop(item, bpSlot);
456 Thurallor-7095
            backpack.cache.recentlyFilled[bpSlot] = item;
457 142 Thurallor-7095
--Puts("Unequipping " .. tostring(item:GetName()) .. " to " .. tostring(bpSlot));
458 Thurallor-7095
            return true;
459 Thurallor-7095
        end
460 Thurallor-7095
    end
461 Thurallor-7095
 
462 Thurallor-7095
    -- Search the preferred slots looking for an empty one.
463 Thurallor-7095
    local safety = backpack:GetSize();
464 Thurallor-7095
    local maxFullSlot = 1;
465 Thurallor-7095
    for bpSlot in preferred_slots:numbers(safety) do
466 Thurallor-7095
        if (trySlot(bpSlot)) then
467 122 Thurallor-7095
            return;
468 142 Thurallor-7095
        else
469 Thurallor-7095
            maxFullSlot = math.max(maxFullSlot, bpSlot);
470 114 Thurallor-7095
        end
471 20 Thurallor-7095
    end
472 142 Thurallor-7095
    --Puts(string.gsub(L:GetText("/BagSlotsFull"), "<slots>", self.preferredBagSlots));
473 Thurallor-7095
 
474 Thurallor-7095
    -- None of the preferred slots are empty.  Try bag slots after the preferred range.
475 Thurallor-7095
    for bpSlot = maxFullSlot + 1, safety do
476 Thurallor-7095
        if (trySlot(bpSlot)) then
477 Thurallor-7095
            return;
478 Thurallor-7095
        end
479 Thurallor-7095
    end
480 Thurallor-7095
 
481 Thurallor-7095
    -- Try bag slots before the preferred range.
482 Thurallor-7095
    for bpSlot = 1, maxFullSlot - 1 do
483 Thurallor-7095
        if (trySlot(bpSlot)) then
484 Thurallor-7095
            return;
485 Thurallor-7095
        end
486 Thurallor-7095
    end
487 Thurallor-7095
 
488 Thurallor-7095
    -- All bag slots are full!
489 Thurallor-7095
    Puts(L:GetText("/BagsFull"));
490 20 Thurallor-7095
end
491 Thurallor-7095
 
492 Thurallor-7095
-- Some trivial wrappers retained for backward compatibility
493 Thurallor-7095
function Manager:GetSkills()
494 Thurallor-7095
    return self.watcher.GetSkillsInfo();
495 Thurallor-7095
end
496 Thurallor-7095
function Manager:SkillReady(iconID)
497 Thurallor-7095
    return self.watcher.SkillReady(iconID);
498 Thurallor-7095
end
499 Thurallor-7095
function Manager:PlayerHasEffectCategory(category)
500 Thurallor-7095
    return self.watcher.PlayerHasEffectCategory(category);
501 Thurallor-7095
end
502 Thurallor-7095
function Manager:TargetHasEffectCategory(category)
503 Thurallor-7095
    return self.watcher.TargetHasEffectCategory(category);
504 Thurallor-7095
end
505 Thurallor-7095
 
506 12 Thurallor-7095
function Manager:SetLanguage(language)
507 Thurallor-7095
    self.settings.language = language;
508 Thurallor-7095
    L:SetLanguage(language);
509 18 Thurallor-7095
    if (language == Turbine.Language.Russian) then
510 Thurallor-7095
        SetCyrillicEnabled(true);
511 Thurallor-7095
    else
512 Thurallor-7095
        SetCyrillicEnabled(false);
513 Thurallor-7095
    end
514 Thurallor-7095
    if (self.optionsPanel) then
515 Thurallor-7095
        self.optionsPanel:Localize();
516 168 Thurallor-7095
        self.optionsPanel:ShowRefreshButton();
517 18 Thurallor-7095
    end
518 12 Thurallor-7095
    self:SaveSettings(false);
519 Thurallor-7095
end
520 Thurallor-7095
 
521 167 Thurallor-7095
function Manager:SetUseOnRightClick(useOnRightClick)
522 Thurallor-7095
    self.settings.useOnRightClick = useOnRightClick;
523 Thurallor-7095
    Group.SetUseOnRightClick(self, useOnRightClick);
524 Thurallor-7095
    self:SaveSettings(false);
525 Thurallor-7095
end
526 Thurallor-7095
 
527 12 Thurallor-7095
function Manager:SetSnapToGrid(snapToGrid)
528 Thurallor-7095
    self.settings.snapToGrid = snapToGrid;
529 Thurallor-7095
    if (snapToGrid) then
530 Thurallor-7095
        self:SnapToGrid();
531 Thurallor-7095
    end
532 16 Thurallor-7095
    self:SaveSettings(false);
533 12 Thurallor-7095
end
534 Thurallor-7095
 
535 127 Thurallor-7095
function Manager:SetGridDisplayEnable(enable)
536 Thurallor-7095
    self.showGrid = enable;
537 Thurallor-7095
    if (self.gridDisplay) then
538 Thurallor-7095
        self.gridDisplay:Close();
539 Thurallor-7095
        self.gridDisplay = nil;
540 Thurallor-7095
    end
541 Thurallor-7095
    if (enable) then
542 158 Thurallor-7095
        local left, top, scaledGridSize = self:GetNearestGridPos(0, 0, self.settings.uiScale);
543 127 Thurallor-7095
        left, top = left - scaledGridSize, top - scaledGridSize;
544 158 Thurallor-7095
        local width, height = self:GetNearestGridPos(Turbine.UI.Display:GetWidth(), Turbine.UI.Display:GetHeight(), self.settings.uiScale);
545 127 Thurallor-7095
        width, height = width + (2 * scaledGridSize), height + (2 * scaledGridSize);
546 Thurallor-7095
        local cellsWide, cellsHigh = width / scaledGridSize, height / scaledGridSize;
547 16 Thurallor-7095
        self.gridDisplay = Turbine.UI.Window();
548 127 Thurallor-7095
        self.gridDisplay:SetPosition(left, top);
549 Thurallor-7095
        self.gridDisplay:SetZOrder(-2147483647);
550 16 Thurallor-7095
        self.gridDisplay:SetVisible(true);
551 127 Thurallor-7095
        self.gridDisplay:SetOpacity(0.5);
552 16 Thurallor-7095
        self.gridDisplay:SetMouseVisible(false);
553 127 Thurallor-7095
        self.gridDisplay:SetBackground("Thurallor/SequenceBars/Images/grid.tga");
554 Thurallor-7095
        self.gridDisplay:SetSize(cellsWide * 35, cellsHigh * 35);
555 Thurallor-7095
        if (scaledGridSize ~= 35) then
556 Thurallor-7095
            self.gridDisplay:SetStretchMode(1);
557 Thurallor-7095
            self.gridDisplay:SetSize(width, height);
558 Thurallor-7095
        end
559 16 Thurallor-7095
    end
560 127 Thurallor-7095
end
561 Thurallor-7095
 
562 158 Thurallor-7095
function Manager:HighlightGrid(left, top, slotsRight, slotsDown, uiScale)
563 127 Thurallor-7095
    if (not self.gridHighlight) then
564 Thurallor-7095
        self.gridHighlight = Turbine.UI.Window();
565 Thurallor-7095
        self.gridHighlight:SetZOrder(-2147483647);
566 Thurallor-7095
        self.gridHighlight:SetVisible(true);
567 Thurallor-7095
        self.gridHighlight:SetMouseVisible(false);
568 Thurallor-7095
        self.gridHighlight:SetBackground(resources.Icon.Grid);
569 Thurallor-7095
        self.gridHighlight:SetStretchMode(0);
570 Thurallor-7095
        self.gridHighlight:SetSize(slotsRight * self.settings.gridSize, slotsDown * self.settings.gridSize);
571 Thurallor-7095
        self.gridHighlight:SetStretchMode(1);
572 Thurallor-7095
        self.gridHighlight.slotsRight, self.gridHighlight.slotsDown = slotsRight, slotsDown;
573 Thurallor-7095
    end
574 158 Thurallor-7095
    left, top, scaledGridSize = self:GetNearestGridPos(left, top, uiScale);
575 127 Thurallor-7095
    self.gridHighlight.prevLeft, self.gridHighlight.prevTop = left, top;
576 Thurallor-7095
    self.gridHighlight:SetSize(slotsRight * scaledGridSize, slotsDown * scaledGridSize);
577 Thurallor-7095
    self.gridHighlight:SetPosition(left, top);
578 16 Thurallor-7095
end
579 Thurallor-7095
 
580 127 Thurallor-7095
function Manager:UnhighlightGrid()
581 Thurallor-7095
    if (self.gridHighlight) then
582 Thurallor-7095
        self.gridHighlight:Close();
583 Thurallor-7095
        self.gridHighlight = nil;
584 16 Thurallor-7095
    end
585 Thurallor-7095
end
586 Thurallor-7095
 
587 127 Thurallor-7095
function Manager:ShowAnchorIcon(anchorPos, x, y)
588 Thurallor-7095
    if (anchorPos) then
589 Thurallor-7095
        if (not self.anchorIcon) then
590 Thurallor-7095
            local width, height = Turbine.UI.Display:GetSize();
591 Thurallor-7095
            local center, middle = math.floor(0.5 + width / 2), math.floor(0.5 + height / 2);
592 Thurallor-7095
            local coords = {
593 Thurallor-7095
                TopLeft =      { 0,           0           };
594 Thurallor-7095
                TopCenter =    { center - 32, 0           };
595 Thurallor-7095
                TopRight =     { width - 64,  0           };
596 Thurallor-7095
                MiddleLeft =   { 0,           middle - 44 };
597 Thurallor-7095
                MiddleCenter = { center - 32, middle - 44 };
598 Thurallor-7095
                MiddleRight =  { width - 64,  middle - 44 };
599 Thurallor-7095
                BottomLeft =   { 0,           height - 88 };
600 Thurallor-7095
                BottomCenter = { center - 32, height - 88 };
601 Thurallor-7095
                BottomRight =  { width - 64,  height - 88 };
602 Thurallor-7095
            }
603 Thurallor-7095
            local anchorX, anchorY = unpack(coords[anchorPos]);
604 Thurallor-7095
 
605 Thurallor-7095
            self.anchorIcon = Turbine.UI.Window();
606 Thurallor-7095
            self.anchorIcon:SetMouseVisible(false);
607 Thurallor-7095
            self.anchorIcon:SetBackground("Thurallor/SequenceBars/Images/anchor.tga");
608 Thurallor-7095
            self.anchorIcon:SetSize(64, 88);
609 Thurallor-7095
            self.anchorIcon:SetPosition(anchorX, anchorY);
610 Thurallor-7095
            self.anchorIcon:SetVisible(true);
611 Thurallor-7095
 
612 Thurallor-7095
            local color = Thurallor.Utils.Color();
613 Thurallor-7095
            color:SetHex("d8cf74"); -- primary color of anchor icon
614 Thurallor-7095
            self.anchorLine = Thurallor.UI.Line(anchorX + 31, anchorY + 12, 0, 0, 3, color);
615 Thurallor-7095
            self.anchorLine:SetMouseVisible(false);
616 Thurallor-7095
        end
617 Thurallor-7095
        self.anchorLine:SetEndPoint(x, y);
618 Thurallor-7095
    elseif (self.anchorIcon) then
619 Thurallor-7095
        self.anchorIcon:Close();
620 Thurallor-7095
        self.anchorLine:Close();
621 Thurallor-7095
        self.anchorIcon, self.anchorLine = nil, nil;
622 Thurallor-7095
    end
623 Thurallor-7095
end
624 Thurallor-7095
 
625 16 Thurallor-7095
function Manager:SetUIOpacity(opacity)
626 Thurallor-7095
    self.settings.uiOpacity = opacity;
627 Thurallor-7095
    self:Redraw(true);
628 Thurallor-7095
    self:SaveSettings(false);
629 Thurallor-7095
end
630 Thurallor-7095
 
631 Thurallor-7095
function Manager:SetUIScale(scale)
632 Thurallor-7095
    self.settings.uiScale = scale;
633 127 Thurallor-7095
    self:SetGridDisplayEnable(self.showGrid);
634 16 Thurallor-7095
    self:Redraw(true);
635 Thurallor-7095
    self:SaveSettings(false);
636 Thurallor-7095
end
637 Thurallor-7095
 
638 Thurallor-7095
function Manager:SetIncludees(includer, includees)
639 Thurallor-7095
--Puts(tostring(includer) .. " is including " .. Serialize(includees));
640 Thurallor-7095
    if (not includees) then
641 Thurallor-7095
        -- Destroying bar.  Notify includers.
642 Thurallor-7095
        self:NotifyIncluders(includer);
643 Thurallor-7095
    end
644 Thurallor-7095
 
645 Thurallor-7095
    -- Delete the previous includes mapping (if any)
646 Thurallor-7095
    local prevIncludes = self.includees[includer];
647 Thurallor-7095
    if (prevIncludes) then
648 Thurallor-7095
        for i = 1, #prevIncludes do
649 Thurallor-7095
            local includee = prevIncludes[i];
650 Thurallor-7095
            self.includers[includee][includer] = nil;
651 Thurallor-7095
--Puts(tostring(includee) .. " will no longer notify " .. tostring(includer));
652 Thurallor-7095
        end
653 Thurallor-7095
    end
654 Thurallor-7095
 
655 Thurallor-7095
    -- Create the new includes mapping (if any)
656 Thurallor-7095
    self.includees[includer] = includees;
657 Thurallor-7095
    if (includees) then
658 Thurallor-7095
        for i = 1, #includees, 1 do
659 Thurallor-7095
            local includee = includees[i];
660 Thurallor-7095
            if (not self.includers[includee]) then
661 Thurallor-7095
                self.includers[includee] = {};
662 Thurallor-7095
            end
663 Thurallor-7095
            self.includers[includee][includer] = true;
664 Thurallor-7095
--Puts(tostring(includee) .. " will notify " .. tostring(includer));
665 Thurallor-7095
        end
666 Thurallor-7095
    end
667 Thurallor-7095
end
668 Thurallor-7095
 
669 Thurallor-7095
-- This function gets called when a sequence changes, so any bars that include that sequence can be notified to update.
670 Thurallor-7095
function Manager:NotifyIncluders(includee)
671 Thurallor-7095
--Puts(tostring(includee) .. " changed");
672 Thurallor-7095
    if (not self.includers[includee]) then
673 Thurallor-7095
        return;
674 Thurallor-7095
    end
675 Thurallor-7095
    self.notifyList = {};
676 Thurallor-7095
    self:FindDependencies(includee);
677 Thurallor-7095
    for barID in keys(self.notifyList) do
678 Thurallor-7095
        if (barID ~= includee) then
679 Thurallor-7095
            local bar = self.objects[barID];
680 Thurallor-7095
            if (bar) then
681 Thurallor-7095
--Puts("Notifying " .. tostring(barID));
682 Thurallor-7095
                bar:ShortcutChanged();
683 Thurallor-7095
            end
684 Thurallor-7095
        end
685 Thurallor-7095
    end
686 Thurallor-7095
    self.notifyList = nil;
687 Thurallor-7095
end
688 Thurallor-7095
 
689 Thurallor-7095
function Manager:FindDependencies(includee)
690 Thurallor-7095
    if (self.includers[includee]) then
691 Thurallor-7095
        for includer in keys(self.includers[includee]) do
692 Thurallor-7095
            if (not self.notifyList[includer]) then
693 Thurallor-7095
                self.notifyList[includer] = true;
694 Thurallor-7095
                self:FindDependencies(includer);
695 Thurallor-7095
            end
696 Thurallor-7095
        end
697 Thurallor-7095
    end
698 Thurallor-7095
end
699 Thurallor-7095
 
700 2 Thurallor-7095
function Manager:AddEventGenerator(object, eventName)
701 Thurallor-7095
    if (not self.eventGenerators[eventName]) then
702 Thurallor-7095
        self.eventGenerators[eventName] = {};
703 Thurallor-7095
    end
704 Thurallor-7095
    table.insert(self.eventGenerators[eventName], object);
705 Thurallor-7095
    local generatorID = #self.eventGenerators[eventName];
706 Thurallor-7095
--Puts("Adding event generator " .. tostring(generatorID) .. " for event " .. Serialize(eventName) .. " from object " .. Serialize(object.settings.caption.text));
707 Thurallor-7095
    return generatorID;
708 Thurallor-7095
end
709 Thurallor-7095
 
710 Thurallor-7095
function Manager:RemoveEventGenerator(generatorID, eventName)
711 8 Thurallor-7095
--Puts("Removing event generator " .. tostring(generatorID) .. " for event " .. Serialize(eventName));
712 13 Thurallor-7095
    local eventGenerators = self.eventGenerators[eventName];
713 Thurallor-7095
    if (eventGenerators) then
714 Thurallor-7095
        local object = eventGenerators[generatorID];
715 Thurallor-7095
--Puts("  (was from object " .. Serialize(object.settings.caption.text) .. ")");
716 Thurallor-7095
        table.remove(eventGenerators, generatorID);
717 Thurallor-7095
        if (#eventGenerators == 0) then
718 Thurallor-7095
            self.eventGenerators[eventName] = nil;
719 Thurallor-7095
        end
720 Thurallor-7095
    else
721 Thurallor-7095
--Puts("Not registered!");
722 2 Thurallor-7095
    end
723 Thurallor-7095
end
724 Thurallor-7095
 
725 Thurallor-7095
-- Returns a list of bars that generates the specified event
726 Thurallor-7095
function Manager:GetEventGenerators(eventName)
727 Thurallor-7095
    return self.eventGenerators[eventName];
728 Thurallor-7095
end
729 Thurallor-7095
 
730 Thurallor-7095
-- Returns the names of all of the events generated by all bars
731 Thurallor-7095
function Manager:GetEventNames()
732 Thurallor-7095
    local eventNames = {};
733 Thurallor-7095
    for k in keys(self.eventGenerators) do
734 Thurallor-7095
        table.insert(eventNames, k);
735 Thurallor-7095
    end
736 Thurallor-7095
    return eventNames;
737 Thurallor-7095
end
738 Thurallor-7095
 
739 Thurallor-7095
function Manager:GetEventCallbacks()
740 Thurallor-7095
    return self.eventCallbacks;
741 Thurallor-7095
end
742 Thurallor-7095
 
743 Thurallor-7095
function Manager:PropagateEvent(eventName)
744 108 Thurallor-7095
    -- Enqueue event for processing at next Update cycle.  We use a hash table to avoid
745 Thurallor-7095
    -- generating the same event multiple times in the same tick, which would be useless
746 Thurallor-7095
    -- and could cause stack overflow.
747 16 Thurallor-7095
    self.propagatingEvent[eventName] = true;
748 2 Thurallor-7095
end
749 16 Thurallor-7095
 
750 Thurallor-7095
function Manager:Destroy()
751 Thurallor-7095
    self:SetWantsPlayerEvents(false);
752 Thurallor-7095
    Node.Destroy(self);
753 Thurallor-7095
end

All times are GMT -5. The time now is 06:38 PM.


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