lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [SequenceBars/] [Bar.lua] - Blame information for rev 177

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

Line No. Rev Author Line
1 8 Thurallor-7095
Bar = class(Node);
2 2 Thurallor-7095
 
3 Thurallor-7095
function Bar:Constructor(group, barID, settings)
4 Thurallor-7095
    Turbine.UI.Window.Constructor(self);
5 Thurallor-7095
    self.constructing = true;
6 13 Thurallor-7095
    self:SetZOrder(0);
7 Thurallor-7095
    self:SetMouseVisible(false);
8 20 Thurallor-7095
    self:SetAllowDrop(true);
9 Thurallor-7095
 
10 13 Thurallor-7095
    self.slotContainer = Turbine.UI.Control();
11 Thurallor-7095
    self.slotContainer:SetParent(self);
12 Thurallor-7095
    self.slotContainer:SetMouseVisible(false);
13 2 Thurallor-7095
 
14 Thurallor-7095
    self.parent = group;
15 Thurallor-7095
    self.manager = group.manager;
16 Thurallor-7095
    self.objectID = barID;
17 Thurallor-7095
    self.onLoad = onLoad;
18 16 Thurallor-7095
    self.slots = {};
19 Thurallor-7095
    self.visibleSlots = {};
20 Thurallor-7095
    self.cursorPos = 3;
21 Thurallor-7095
    self.cursorSlot = 1;
22 2 Thurallor-7095
    self.globals = self.manager.settings;
23 16 Thurallor-7095
    self.player = Turbine.Gameplay.LocalPlayer:GetInstance();
24 17 Thurallor-7095
    self.automaticClicks = 0;
25 116 Thurallor-7095
    self.wheelPosition = 0;
26 147 Thurallor-7095
    self.advancement = {};
27 17 Thurallor-7095
 
28 2 Thurallor-7095
    -- Default settings
29 Thurallor-7095
    local defaults = {};
30 Thurallor-7095
    defaults.type = "bar";
31 Thurallor-7095
    defaults.locked = false;
32 Thurallor-7095
    defaults.hidden = false;
33 7 Thurallor-7095
    defaults.color = Thurallor.Utils.Color();
34 Thurallor-7095
    defaults.color:SetHSV(math.random(), 1, 1);
35 Thurallor-7095
    defaults.color = defaults.color:GetHex();
36 2 Thurallor-7095
    defaults.cursorStyle = "SmallSquareGlow";
37 Thurallor-7095
    defaults.caption = { };
38 112 Thurallor-7095
    defaults.caption.visible = "Always";
39 Thurallor-7095
    defaults.caption.clickThru = nil;
40 2 Thurallor-7095
    defaults.caption.text = L:GetText("/Default/BarName");
41 Thurallor-7095
    defaults.caption.position = "beginning";
42 Thurallor-7095
    defaults.caption.width = 80;
43 5 Thurallor-7095
    defaults.caption.height = 35;
44 2 Thurallor-7095
    defaults.caption.font = Turbine.UI.Lotro.Font.TrajanPro15;
45 Thurallor-7095
    defaults.slotSize = 35; -- must be an even number
46 Thurallor-7095
    defaults.slotSpacing = 0;
47 Thurallor-7095
    defaults.orientation = "Right";
48 Thurallor-7095
    defaults.visibleSlots = 5;
49 Thurallor-7095
    defaults.cursorHomePosition = 2;
50 Thurallor-7095
    defaults.animation = { duration = 0.1 };
51 Thurallor-7095
    defaults.sequenceItemInfo = { {}, {}, {}, {}, {} };
52 Thurallor-7095
    defaults.position = { left = math.floor(Turbine.UI.Display:GetWidth() / 2); top = math.floor(Turbine.UI.Display:GetHeight() / 2 )};
53 26 Thurallor-7095
    defaults.anchor = "TopLeft";
54 8 Thurallor-7095
    defaults.eventHandlers = {};
55 Thurallor-7095
    defaults.eventsEnabled = false;
56 16 Thurallor-7095
    defaults.hideAutomatics = true;
57 Thurallor-7095
    defaults.hideInactiveBranches = true;
58 116 Thurallor-7095
    defaults.wheelSpeed = 0;
59 2 Thurallor-7095
 
60 Thurallor-7095
    -- Previously-saved settings override the defaults
61 Thurallor-7095
    DeepTableCopy(settings, defaults);
62 Thurallor-7095
    DeepTableCopy(defaults, settings);
63 Thurallor-7095
    self.settings = settings;
64 Thurallor-7095
 
65 Thurallor-7095
    self:ReapplySettings();
66 Thurallor-7095
    self.constructing = nil;
67 8 Thurallor-7095
    self:SetWantsEvents(self.settings.eventsEnabled);
68 2 Thurallor-7095
end
69 Thurallor-7095
 
70 Thurallor-7095
function Bar:ReapplySettings()
71 Thurallor-7095
 
72 Thurallor-7095
    -- Make color object from hex string
73 Thurallor-7095
    self.color = Thurallor.Utils.Color(1, 0, 0, 0);
74 Thurallor-7095
    self.color:SetHex(self.settings.color);
75 Thurallor-7095
 
76 8 Thurallor-7095
    -- For backward compatibility
77 Thurallor-7095
    self.settings.cursorStyle = string.gsub(self.settings.cursorStyle, "SilverFrame(%d)", "MetalFrame%1");
78 44 Thurallor-7095
    for s = 1, #self.settings.sequenceItemInfo, 1 do
79 135 Thurallor-7095
        info = self.settings.sequenceItemInfo[s] or {};
80 29 Thurallor-7095
        if (info.action) then
81 Thurallor-7095
            info.action = string.gsub(info.action, "item.eventName", "item.info.eventName");
82 Thurallor-7095
            info.action = string.gsub(info.action, "item.bagSlot", "item.info.bagSlot");
83 13 Thurallor-7095
        end
84 34 Thurallor-7095
        if ((info.class == "Turbine.UI.Lotro.Quickslot") and (info.background)) then
85 Thurallor-7095
            info.altIcon = info.background;
86 Thurallor-7095
            info.background = nil;
87 Thurallor-7095
        end
88 119 Thurallor-7095
        if (info.condName == "StanceSelected") then
89 Thurallor-7095
            if (string.match(info.condExpr, "GetClassAttributes")) then
90 Thurallor-7095
                info.condExpr = "return (Thurallor.Utils.Watcher.GetStance() == <stance>);";
91 Thurallor-7095
            end
92 Thurallor-7095
        end
93 41 Thurallor-7095
        if (info.condName and (string.find("SkillTrained|SkillNotTrained|SkillReady|SkillNotReady", info.condName))) then
94 Thurallor-7095
            if ((type(info.condArgs.skill) == "number") and (info.condArgs.skill == 0)) then
95 43 Thurallor-7095
                local skills = Thurallor.Utils.Watcher.GetTrainedSkillsInfo();
96 Thurallor-7095
                local name = skills.names[1];
97 Thurallor-7095
                local skill = skills.byName[name];
98 Thurallor-7095
                local skillInfo = skill:GetSkillInfo();
99 Thurallor-7095
                info.condArgs.skill = skillInfo:GetIconImageID();
100 41 Thurallor-7095
            end
101 Thurallor-7095
            if ((info.condName == "SkillNotReady") and string.find(info.condExpr, "SkillTrained")) then
102 43 Thurallor-7095
                info.condExpr = "return (not Thurallor.Utils.Watcher.SkillReady(<skillName>));";
103 41 Thurallor-7095
            end
104 Thurallor-7095
            if ((info.condName == "SkillTrained") and string.find(info.condExpr, "SkillReady")) then
105 Thurallor-7095
                info.condExpr = "return (Thurallor.Utils.Watcher.SkillTrained(<skillName>));";
106 Thurallor-7095
            end
107 43 Thurallor-7095
            info.condExpr = string.gsub(info.condExpr, "<skill>", "<skillName>");
108 44 Thurallor-7095
            if (info.condArgs.skill and (not info.condArgs.skillName)) then
109 41 Thurallor-7095
                local skills = Thurallor.Utils.Watcher.GetSkillsInfo();
110 Thurallor-7095
                local skill = skills.byIcon[info.condArgs.skill];
111 44 Thurallor-7095
                local name;
112 Thurallor-7095
                if (skill == nil) then
113 Thurallor-7095
                    local barName = self.settings.caption.text;
114 Thurallor-7095
                    local group = self.parent;
115 Thurallor-7095
                    while (group ~= self.manager) do
116 Thurallor-7095
                        barName = group.settings.caption.text .. ":" .. barName;
117 Thurallor-7095
                        group = group.parent;
118 Thurallor-7095
                    end
119 Thurallor-7095
                    _G.manualUpdatesNeeded = _G.manualUpdatesNeeded .. "• In bar \"" .. barName .. "\", in slot " .. s .. ", please reselect the skill from the menu.\n\n";
120 Thurallor-7095
                    name = skills.names[1];
121 Thurallor-7095
                else
122 Thurallor-7095
                    local skillInfo = skill:GetSkillInfo();
123 Thurallor-7095
                    name = skillInfo:GetName();
124 Thurallor-7095
                end
125 41 Thurallor-7095
                info.condArgs.skillName = "\"" .. name .. "\"";
126 Thurallor-7095
                info.condArgs.skill = nil;
127 Thurallor-7095
            end
128 Thurallor-7095
        end
129 114 Thurallor-7095
        if ((info.type == "SetUnequipDestination") and (type(info.bagSlot) == "number")) then
130 Thurallor-7095
            local maxSlot = self.player:GetBackpack():GetSize();
131 Thurallor-7095
            local str = tostring(info.bagSlot);
132 Thurallor-7095
            if (info.bagSlot < maxSlot) then
133 Thurallor-7095
                str = str .. ";" .. tostring(info.bagSlot + 1) .. "..." .. tostring(maxSlot);
134 Thurallor-7095
            end
135 Thurallor-7095
            if (info.bagSlot > 1) then
136 Thurallor-7095
                str = str .. ";1..." .. tostring(info.bagSlot - 1);
137 Thurallor-7095
            end
138 Thurallor-7095
            info.bagSlot = str;
139 Thurallor-7095
        end
140 13 Thurallor-7095
    end
141 29 Thurallor-7095
    for _, handler in pairs(self.settings.eventHandlers) do
142 Thurallor-7095
        if (handler.action) then
143 31 Thurallor-7095
            handler.action = string.gsub(handler.action, "self:SetHidden%(false%); self:BringToFront%(%); ", "self:SetHidden(false); ");
144 30 Thurallor-7095
            handler.action = string.gsub(handler.action, "self:SetHidden%(false%); self:Activate%(%); ", "self:SetHidden(false); ");
145 Thurallor-7095
            handler.action = string.gsub(handler.action, "self:Expand%(%); self:Activate%(%); ", "self:Expand(); ");
146 31 Thurallor-7095
            handler.action = string.gsub(handler.action, "self:Expand%(%); self:BringToFront%(%); ", "self:Expand(); ");
147 30 Thurallor-7095
            handler.action = string.gsub(handler.action, "self:MoveToMouseCursor%(%); self:Activate%(%); ", "self:MoveToMouseCursor%(%); ");
148 29 Thurallor-7095
        end
149 Thurallor-7095
    end
150 112 Thurallor-7095
        if (self.settings.caption.hidden) then
151 Thurallor-7095
                self.settings.caption.hidden = nil;
152 Thurallor-7095
                self.settings.caption.visible = "WhenMouseIsPresent";
153 Thurallor-7095
        end
154 Thurallor-7095
 
155 2 Thurallor-7095
    self:SetCursorStyle(self.settings.cursorStyle);
156 Thurallor-7095
    self:GetQuickSlots();
157 16 Thurallor-7095
    self:FindHiddenSlots();
158 2 Thurallor-7095
    self:Redraw();
159 Thurallor-7095
end
160 Thurallor-7095
 
161 30 Thurallor-7095
function Bar:Activate()
162 Thurallor-7095
    -- This used to be called in event handlers after Expand(), MoveToMouseCursor(), and SetHidden(false).
163 Thurallor-7095
    -- Don't want to use Turbine.UI.Window.Activate() because that would steal focus from the chat window.
164 Thurallor-7095
end
165 Thurallor-7095
 
166 29 Thurallor-7095
-- Bring this bar in front of all other bars.
167 Thurallor-7095
function Bar:BringToFront()
168 Thurallor-7095
    -- Don't want to use Turbine.UI.Window.Activate() because that would steal focus from the chat window.
169 Thurallor-7095
    self:SetZOrder(1);
170 Thurallor-7095
    self:SetZOrder(0);
171 Thurallor-7095
end
172 Thurallor-7095
 
173 2 Thurallor-7095
function Bar:CanHaveChildren()
174 Thurallor-7095
    return false;
175 Thurallor-7095
end
176 Thurallor-7095
 
177 Thurallor-7095
function Bar:Contains(object)
178 Thurallor-7095
    return false;
179 Thurallor-7095
end
180 Thurallor-7095
 
181 Thurallor-7095
function Bar:SetColor(color)
182 8 Thurallor-7095
    Node.SetColor(self, color);
183 34 Thurallor-7095
    self:Redraw(true);
184 2 Thurallor-7095
    self:SetCursorStyle();
185 Thurallor-7095
    if (self.sequenceEditor) then
186 Thurallor-7095
        self.sequenceEditor:Redraw();
187 Thurallor-7095
    end
188 Thurallor-7095
end
189 Thurallor-7095
 
190 Thurallor-7095
function Bar:SetName(caption)
191 8 Thurallor-7095
    Node.SetName(self, caption);
192 34 Thurallor-7095
    self:Redraw(true);
193 2 Thurallor-7095
    if (self.sequenceEditor) then
194 Thurallor-7095
        self.sequenceEditor:SetText(caption);
195 Thurallor-7095
    end
196 Thurallor-7095
    if (self.exportWindow) then
197 Thurallor-7095
        self.exportWindow:SetText(caption);
198 Thurallor-7095
    end
199 Thurallor-7095
end
200 Thurallor-7095
 
201 Thurallor-7095
function Bar:SetCaptionSize(width, height)
202 9 Thurallor-7095
    Node.SetCaptionSize(self, width, height);
203 34 Thurallor-7095
    self:Redraw(true);
204 13 Thurallor-7095
    self:OffsetPosition(0, 0);
205 2 Thurallor-7095
end
206 Thurallor-7095
 
207 Thurallor-7095
function Bar:SetCaptionFont(font)
208 Thurallor-7095
    self.settings.caption.font = font;
209 Thurallor-7095
    self:SaveSettings(false);
210 34 Thurallor-7095
    self:Redraw(true);
211 2 Thurallor-7095
end
212 Thurallor-7095
 
213 112 Thurallor-7095
function Bar:SetCaptionVisible(visible)
214 Thurallor-7095
    self.settings.caption.visible = visible;
215 2 Thurallor-7095
    self:SaveSettings(false);
216 34 Thurallor-7095
    self:Redraw(true);
217 2 Thurallor-7095
end
218 Thurallor-7095
 
219 112 Thurallor-7095
function Bar:SetCaptionClickThru(clickThru)
220 Thurallor-7095
        if (clickThru == false) then
221 Thurallor-7095
                clickThru = nil;
222 Thurallor-7095
        end
223 Thurallor-7095
        self.settings.caption.clickThru = clickThru;
224 Thurallor-7095
    self:SaveSettings(false);
225 Thurallor-7095
    self:Redraw(true);
226 Thurallor-7095
end
227 Thurallor-7095
 
228 2 Thurallor-7095
function Bar:ApplyHiddenness()
229 Thurallor-7095
    local hidden = self:IsHidden();
230 21 Thurallor-7095
    if ((not hidden) and (not self:IsVisible())) then
231 Thurallor-7095
        self.visibleSlots = {};
232 Thurallor-7095
    end
233 Thurallor-7095
    self:SetCursorSlot(self.cursorSlot);
234 2 Thurallor-7095
    self:SetVisible(not hidden);
235 Thurallor-7095
end
236 Thurallor-7095
 
237 26 Thurallor-7095
function Bar:Collapse()
238 Thurallor-7095
    if (self.settings.collapsed) then
239 Thurallor-7095
        return;
240 Thurallor-7095
    end
241 121 Thurallor-7095
    if (self.Log) then
242 Thurallor-7095
        DoCallbacks(self, "Log", {"collapsing", "BAR"});
243 Thurallor-7095
    end
244 26 Thurallor-7095
    self.settings.collapsed = self.cursorPos;
245 Thurallor-7095
    self:Redraw(true);
246 27 Thurallor-7095
    local x1, y1 = self:GetSlotCoords(1);
247 Thurallor-7095
    if ((self.settings.orientation == "Up") or (self.settings.orientation == "Left")) then
248 Thurallor-7095
        x1, y1 = self:GetSlotCoords(self.settings.visibleSlots);
249 Thurallor-7095
    end
250 Thurallor-7095
    local x2, y2 = self:GetSlotCoords(self.settings.cursorHomePosition);
251 Thurallor-7095
    self:OffsetPosition(x2 - x1, y2 - y1);
252 26 Thurallor-7095
    self:SetCursorPos(1);
253 Thurallor-7095
    self:SetCursorSlot(self.cursorSlot);
254 Thurallor-7095
    self:SaveSettings(false);
255 Thurallor-7095
end
256 Thurallor-7095
 
257 Thurallor-7095
function Bar:IsCollapsed()
258 Thurallor-7095
    return ((self.settings.visibleSlots == 1) or (self.settings.collapsed ~= nil));
259 Thurallor-7095
end
260 Thurallor-7095
 
261 Thurallor-7095
function Bar:Expand()
262 Thurallor-7095
    if (not self.settings.collapsed) then
263 Thurallor-7095
        return;
264 Thurallor-7095
    end
265 121 Thurallor-7095
    if (self.Log) then
266 Thurallor-7095
        DoCallbacks(self, "Log", {"expanding", "BAR"});
267 Thurallor-7095
    end
268 26 Thurallor-7095
    local cursorPos = math.min(self.settings.collapsed, self.settings.visibleSlots);
269 Thurallor-7095
    self.settings.collapsed = nil;
270 Thurallor-7095
    self:Redraw(true);
271 27 Thurallor-7095
    local x1, y1 = self:GetSlotCoords(1);
272 Thurallor-7095
    if ((self.settings.orientation == "Up") or (self.settings.orientation == "Left")) then
273 Thurallor-7095
        x1, y1 = self:GetSlotCoords(self.settings.visibleSlots);
274 Thurallor-7095
    end
275 Thurallor-7095
    local x2, y2 = self:GetSlotCoords(self.settings.cursorHomePosition);
276 Thurallor-7095
    self:OffsetPosition(x1 - x2, y1 - y2);
277 26 Thurallor-7095
    self:SetCursorPos(cursorPos);
278 Thurallor-7095
    self:SetCursorSlot(self.cursorSlot);
279 Thurallor-7095
    self:SaveSettings(false);
280 Thurallor-7095
end
281 Thurallor-7095
 
282 Thurallor-7095
function Bar:IsExpanded()
283 Thurallor-7095
    return ((self.settings.visibleSlots == 1) or (self.settings.collapsed == nil));
284 Thurallor-7095
end
285 Thurallor-7095
 
286 2 Thurallor-7095
-- Updates the sequence item when a user drags a shortcut onto the sequence editor
287 121 Thurallor-7095
function Bar:ShortcutChanged()
288 Thurallor-7095
    if (self.Log) then
289 Thurallor-7095
        DoCallbacks(self, "Log", {"modified with sequence editor", "BAR"});
290 Thurallor-7095
    end
291 2 Thurallor-7095
    self:SaveSettings(false);
292 Thurallor-7095
    self:GetQuickSlots();
293 16 Thurallor-7095
    self:FindHiddenSlots();
294 Thurallor-7095
    self:Reset();
295 2 Thurallor-7095
end
296 Thurallor-7095
 
297 16 Thurallor-7095
-- Initialize "hidden" and "folded" flags
298 Thurallor-7095
function Bar:FindHiddenSlots()
299 Thurallor-7095
    for i = 1, #self.slots, 1 do
300 Thurallor-7095
        local slot = self.slots[i];
301 Thurallor-7095
        slot.folded = false;
302 Thurallor-7095
        if (self.settings.hideAutomatics and slot.info.automatic) then
303 Thurallor-7095
            slot.hidden = true;
304 Thurallor-7095
        else
305 Thurallor-7095
            slot.hidden = false;
306 Thurallor-7095
        end
307 Thurallor-7095
    end
308 Thurallor-7095
end
309 Thurallor-7095
 
310 Thurallor-7095
function Bar:GetSequence()
311 Thurallor-7095
    return self.sequence;
312 Thurallor-7095
end
313 Thurallor-7095
 
314 167 Thurallor-7095
function Bar:SetUseOnRightClick(useOnRightClick)
315 Thurallor-7095
    for _, slot in pairs(self.slots) do
316 Thurallor-7095
        slot:SetUseOnRightClick(useOnRightClick);
317 Thurallor-7095
    end
318 Thurallor-7095
end
319 Thurallor-7095
 
320 2 Thurallor-7095
-- Creates (or recreates) the array of objects (e.g. Quickslot) according to self.settings.sequenceItemInfo
321 Thurallor-7095
function Bar:GetQuickSlots()
322 16 Thurallor-7095
    -- Hide and destroy existing clickable objects, if any
323 Thurallor-7095
    for s = 1, #self.slots, 1 do
324 Thurallor-7095
        self.slots[s]:SetParent(nil);
325 Thurallor-7095
    end
326 Thurallor-7095
 
327 Thurallor-7095
    -- Unregister as event(s) generator.  We will re-register for each generated event as we loop through the sequence below.
328 177 Thurallor-7095
    self.manager:SetEventGenerators(false, self);
329 2 Thurallor-7095
 
330 117 Thurallor-7095
    local wantsMouseWheelEvents = self.settings.wheelSpeed and (self.settings.wheelSpeed > 0);
331 Thurallor-7095
    self.sequence = Sequence(self, self.settings.sequenceItemInfo, wantsMouseWheelEvents);
332 16 Thurallor-7095
    self.manager:SetIncludees(self.objectID, self.sequence:GetIncludes());
333 Thurallor-7095
 
334 Thurallor-7095
    -- Register as generator of event(s)
335 177 Thurallor-7095
    self.manager:SetEventGenerators(true, self, self.sequence:GetEvents());
336 16 Thurallor-7095
 
337 Thurallor-7095
    -- Iterate through the sequence configuring the clickable objects.
338 Thurallor-7095
    self.slots = self.sequence:GetSlots(); -- returns array of Slot instances
339 Thurallor-7095
    for s = 1, #self.slots, 1 do
340 Thurallor-7095
        local slot = self.slots[s];
341 Thurallor-7095
        local info = slot.info;
342 36 Thurallor-7095
        self:ConfigureSlot(slot, s);
343 20 Thurallor-7095
        AddCallback(slot, "MouseClick", function(sender, args)
344 167 Thurallor-7095
            if (self.globals.useOnRightClick or args.Button == Turbine.UI.MouseButton.Left) then
345 121 Thurallor-7095
                if (self.Log) then
346 Thurallor-7095
                    DoCallbacks(self, "Log", {"clicked slot " .. tostring(sender.s), "MOUSE"});
347 Thurallor-7095
                end
348 20 Thurallor-7095
                self:SlotClick(sender.s, false);
349 13 Thurallor-7095
            end
350 20 Thurallor-7095
        end);
351 2 Thurallor-7095
    end
352 36 Thurallor-7095
 
353 Thurallor-7095
    -- Create a "reset" slot to be displayed when all other slots are folded
354 43 Thurallor-7095
    if (not self.resetSlot) then
355 Thurallor-7095
        local info = { type = "Reset"; class = "Turbine.UI.Control"; background = resources.Icon.Reset };
356 Thurallor-7095
        self.resetSlot = Slot(info);
357 Thurallor-7095
    end
358 36 Thurallor-7095
    self:ConfigureSlot(self.resetSlot, #self.slots);
359 Thurallor-7095
    AddCallback(self.resetSlot, "MouseClick", function(sender, args)
360 Thurallor-7095
        if (args.Button == Turbine.UI.MouseButton.Left) then
361 121 Thurallor-7095
            if (self.Log) then
362 Thurallor-7095
                DoCallbacks(self, "Log", {"clicked reset button", "MOUSE"});
363 Thurallor-7095
            end
364 36 Thurallor-7095
            self:Reset();
365 Thurallor-7095
        end
366 Thurallor-7095
    end);
367 43 Thurallor-7095
 
368 Thurallor-7095
    -- Create a "gears" slot to be displayed when running continuously
369 Thurallor-7095
    if (not self.gearsSlot) then
370 Thurallor-7095
        self.gearsSlot = Gears(false);
371 Thurallor-7095
    end
372 Thurallor-7095
    self:ConfigureSlot(self.gearsSlot, #self.slots);
373 2 Thurallor-7095
end
374 Thurallor-7095
 
375 36 Thurallor-7095
function Bar:ConfigureSlot(slot, s)
376 43 Thurallor-7095
    slot:SetZOrder(2);
377 Thurallor-7095
    slot:SetActionEnabled(true);
378 Thurallor-7095
    slot:SetAllowDrop(false);
379 Thurallor-7095
    slot:SetDraggable(false);
380 167 Thurallor-7095
    slot:SetUseOnRightClick(self.globals.useOnRightClick);
381 43 Thurallor-7095
    slot.bar = self;
382 Thurallor-7095
    slot.s = s;
383 36 Thurallor-7095
    slot.MouseClick = nil; -- avoid multiple callbacks when the slot is reconfigured
384 Thurallor-7095
    slot.MouseEnter = nil;
385 116 Thurallor-7095
    slot.MouseWheel = nil;
386 43 Thurallor-7095
    AddCallback(slot, "MouseClick", function(sender, args)
387 Thurallor-7095
        -- Right-click displays the settings menu.
388 167 Thurallor-7095
        if (not self.globals.useOnRightClick and (args.Button == Turbine.UI.MouseButton.Right)) then
389 43 Thurallor-7095
            self:ShowSettingsMenu();
390 Thurallor-7095
        end
391 Thurallor-7095
    end);
392 121 Thurallor-7095
    AddCallback(slot, "MouseEnter", function()
393 43 Thurallor-7095
        self:MouseArrive();
394 Thurallor-7095
    end);
395 116 Thurallor-7095
    AddCallback(slot, "MouseWheel", function(sender, args)
396 117 Thurallor-7095
        args.s = s;
397 116 Thurallor-7095
        self:MouseWheel(args);
398 Thurallor-7095
    end);
399 43 Thurallor-7095
end
400 36 Thurallor-7095
 
401 16 Thurallor-7095
function Bar:Redraw(noReset)
402 26 Thurallor-7095
    if (self.settings.collapsed) then
403 Thurallor-7095
        self.displaySlots = 1;
404 Thurallor-7095
    else
405 Thurallor-7095
        self.displaySlots = self.settings.visibleSlots;
406 Thurallor-7095
    end
407 Thurallor-7095
    local slotsLongDimension = (2 * self.cursorMargin) + (self.displaySlots + 1) * self.settings.slotSize + self.displaySlots * self.settings.slotSpacing;
408 13 Thurallor-7095
    local slotsShortDimension = (2 * self.cursorMargin) + self.settings.slotSize;
409 2 Thurallor-7095
 
410 13 Thurallor-7095
    local captionMargin = 4;
411 Thurallor-7095
    local captionWidth, captionHeight = self.settings.caption.width, self.settings.caption.height;
412 16 Thurallor-7095
    local barWidth, barHeight, slotsWidth, slotsHeight, captionLeft, captionTop;
413 2 Thurallor-7095
    if ((self.settings.orientation == "Up") or (self.settings.orientation == "Down")) then
414 13 Thurallor-7095
        slotsWidth, slotsHeight = slotsShortDimension, slotsLongDimension;
415 Thurallor-7095
 
416 Thurallor-7095
        -- Position slots and caption horizontally; set bar width
417 Thurallor-7095
        if (slotsWidth < captionWidth) then
418 Thurallor-7095
            barWidth = captionWidth;
419 16 Thurallor-7095
            self.slotsLeft = math.floor((barWidth - slotsWidth) / 2);
420 13 Thurallor-7095
            captionLeft = 0;
421 Thurallor-7095
        elseif (slotsWidth > captionWidth) then
422 Thurallor-7095
            barWidth = slotsWidth;
423 16 Thurallor-7095
            self.slotsLeft = 0;
424 13 Thurallor-7095
            captionLeft = math.floor((barWidth - captionWidth) / 2);
425 Thurallor-7095
        else -- (slotsWidth == captionWidth)
426 16 Thurallor-7095
            barWidth, self.slotsLeft, captionLeft = slotsWidth, 0, 0;
427 13 Thurallor-7095
        end
428 Thurallor-7095
 
429 Thurallor-7095
        -- Position slots and caption vertically; set bar height
430 Thurallor-7095
        if (self.settings.orientation == "Up") then
431 Thurallor-7095
            if (self.settings.caption.position == "beginning") then
432 16 Thurallor-7095
                self.slotsTop = 0;
433 13 Thurallor-7095
                captionTop = slotsHeight - self.cursorMargin + captionMargin;
434 Thurallor-7095
                barHeight = math.max(slotsHeight, captionTop + captionHeight);
435 Thurallor-7095
            else -- (self.settings.caption.position == "end")
436 Thurallor-7095
                captionTop = math.max(0, self.cursorMargin + self.settings.slotSize - (captionHeight + captionMargin));
437 16 Thurallor-7095
                self.slotsTop = math.max((captionHeight + captionMargin) - (self.cursorMargin + self.settings.slotSize), 0);
438 Thurallor-7095
                barHeight = self.slotsTop + slotsHeight;
439 13 Thurallor-7095
            end
440 Thurallor-7095
        else -- (self.settings.orientation == "Down")
441 Thurallor-7095
            if (self.settings.caption.position == "beginning") then
442 Thurallor-7095
                captionTop = math.max(0, self.cursorMargin - (captionHeight + captionMargin));
443 16 Thurallor-7095
                self.slotsTop = math.max((captionHeight + captionMargin) - self.cursorMargin, 0);
444 Thurallor-7095
                barHeight = self.slotsTop + slotsHeight;
445 13 Thurallor-7095
            else -- (self.settings.caption.position == "end")
446 16 Thurallor-7095
                self.slotsTop = 0;
447 13 Thurallor-7095
                captionTop = slotsHeight - self.cursorMargin - self.settings.slotSize + captionMargin;
448 Thurallor-7095
                barHeight = math.max(slotsHeight, captionTop + captionHeight);
449 Thurallor-7095
            end
450 Thurallor-7095
        end
451 Thurallor-7095
    else -- ((self.settings.orientation == "Left") or (self.settings.orientation == "Right")) then
452 Thurallor-7095
        slotsWidth, slotsHeight = slotsLongDimension, slotsShortDimension;
453 Thurallor-7095
 
454 Thurallor-7095
        -- Position slots and caption vertically; set bar height
455 Thurallor-7095
        if (slotsHeight < captionHeight) then
456 Thurallor-7095
            barHeight = captionHeight;
457 16 Thurallor-7095
            self.slotsTop = math.floor((barHeight - slotsHeight) / 2);
458 13 Thurallor-7095
            captionTop = 0;
459 Thurallor-7095
        elseif (slotsHeight > captionHeight) then
460 Thurallor-7095
            barHeight = slotsHeight;
461 16 Thurallor-7095
            self.slotsTop = 0;
462 13 Thurallor-7095
            captionTop = math.floor((barHeight - captionHeight) / 2);
463 Thurallor-7095
        else -- (slotsHeight == captionHeight)
464 16 Thurallor-7095
            barHeight, self.slotsTop, captionTop = slotsHeight, 0, 0;
465 13 Thurallor-7095
        end
466 Thurallor-7095
 
467 Thurallor-7095
        -- Position slots and caption horizontally; set bar width
468 Thurallor-7095
        if (self.settings.orientation == "Left") then
469 Thurallor-7095
            if (self.settings.caption.position == "beginning") then
470 16 Thurallor-7095
                self.slotsLeft = 0;
471 13 Thurallor-7095
                captionLeft = slotsWidth - self.cursorMargin + captionMargin;
472 Thurallor-7095
                barWidth = math.max(slotsWidth, captionLeft + captionWidth);
473 Thurallor-7095
            else -- (self.settings.caption.position == "end")
474 Thurallor-7095
                captionLeft = math.max(0, self.cursorMargin + self.settings.slotSize - (captionWidth + captionMargin));
475 16 Thurallor-7095
                self.slotsLeft = math.max((captionLeft + captionWidth + captionMargin) - (self.cursorMargin + self.settings.slotSize), 0);
476 Thurallor-7095
                barWidth = self.slotsLeft + slotsWidth;
477 13 Thurallor-7095
            end
478 Thurallor-7095
        else -- (self.settings.orientation == "Right")
479 Thurallor-7095
            if (self.settings.caption.position == "beginning") then
480 Thurallor-7095
                captionLeft = math.max(0, self.cursorMargin - (captionWidth + captionMargin));
481 16 Thurallor-7095
                self.slotsLeft = math.max((captionWidth + captionMargin) - self.cursorMargin, 0);
482 Thurallor-7095
                barWidth = self.slotsLeft + slotsWidth;
483 13 Thurallor-7095
            else -- (self.settings.caption.position == "end")
484 16 Thurallor-7095
                self.slotsLeft = 0;
485 13 Thurallor-7095
                captionLeft = slotsWidth - self.cursorMargin - self.settings.slotSize + captionMargin;
486 Thurallor-7095
                barWidth = math.max(slotsWidth, captionLeft + captionWidth);
487 Thurallor-7095
            end
488 Thurallor-7095
        end
489 2 Thurallor-7095
    end
490 16 Thurallor-7095
 
491 13 Thurallor-7095
    self.slotContainer:SetSize(slotsWidth, slotsHeight);
492 16 Thurallor-7095
    self.slotContainer:SetPosition(self.slotsLeft, self.slotsTop);
493 13 Thurallor-7095
    self:DrawCaption();
494 Thurallor-7095
    self.caption:SetSize(captionWidth, captionHeight);
495 Thurallor-7095
    self.caption:SetPosition(captionLeft, captionTop);
496 16 Thurallor-7095
 
497 Thurallor-7095
    self:SetStretchMode(0);
498 Thurallor-7095
    self:SetSize(barWidth, barHeight);
499 Thurallor-7095
    self:SetStretchMode(1);
500 158 Thurallor-7095
    self:SetSize(barWidth * self:GetScale() / 32, barHeight * self:GetScale() / 32);
501 16 Thurallor-7095
 
502 26 Thurallor-7095
    self:SetPosition();
503 158 Thurallor-7095
    self:SetOpacity(self:GetTransparency());
504 2 Thurallor-7095
 
505 16 Thurallor-7095
    -- Draw cursor icon and slots.
506 Thurallor-7095
    if (not noReset) then
507 Thurallor-7095
        self:Reset();
508 Thurallor-7095
    end
509 2 Thurallor-7095
 
510 Thurallor-7095
    self:ApplyHiddenness();
511 Thurallor-7095
end
512 Thurallor-7095
 
513 Thurallor-7095
function Bar:Reset()
514 121 Thurallor-7095
    if (self.Log) then
515 Thurallor-7095
        DoCallbacks(self, "Log", {"reset", "BAR"})
516 Thurallor-7095
    end
517 16 Thurallor-7095
    self.sequence:UnfoldAllSlots();
518 2 Thurallor-7095
    self.animationStopped = false;
519 26 Thurallor-7095
    local cursorPos = self.settings.cursorHomePosition;
520 Thurallor-7095
    if (self.settings.collapsed) then
521 Thurallor-7095
        self.settings.collapsed = self.settings.cursorHomePosition;
522 Thurallor-7095
        cursorPos = 1;
523 Thurallor-7095
    end
524 Thurallor-7095
    self:SetCursorPos(cursorPos);
525 Thurallor-7095
    self.clickedPos = cursorPos;
526 38 Thurallor-7095
    self.clickedSlot = 1;
527 16 Thurallor-7095
    self:SetCursorSlot(1);
528 43 Thurallor-7095
    self.gearsSlot:SetDelaying(false);
529 143 Thurallor-7095
    self:UnregisterAdvanceCallback(); -- In case we were waiting for advancement when the bar was reset
530 16 Thurallor-7095
    if (self.slots[1] and self.slots[1].info.automatic) then
531 20 Thurallor-7095
        self:SlotClick(1, true);
532 16 Thurallor-7095
    end
533 2 Thurallor-7095
end
534 Thurallor-7095
 
535 Thurallor-7095
-- Moves the cursor to the specified position on the bar
536 16 Thurallor-7095
function Bar:SetCursorPos(pos)
537 2 Thurallor-7095
    local resource = resources.Cursor[self.settings.cursorStyle];
538 Thurallor-7095
    local left, top = self:GetSlotCoords(pos);
539 Thurallor-7095
    left = left - self.cursorMargin + resource.xOffset;
540 Thurallor-7095
    top = top - self.cursorMargin + resource.yOffset;
541 13 Thurallor-7095
    self.cursor.left, self.cursor.top = left, top;
542 2 Thurallor-7095
    self.cursor:SetPosition(left, top);
543 16 Thurallor-7095
    self.cursorPos = pos;
544 2 Thurallor-7095
end
545 Thurallor-7095
 
546 Thurallor-7095
function Bar:DrawCaption()
547 Thurallor-7095
    if (not self.caption) then
548 13 Thurallor-7095
        self.caption = Turbine.UI.Control();
549 Thurallor-7095
        self.caption:SetParent(self);
550 Thurallor-7095
        self.caption:SetZOrder(10);
551 20 Thurallor-7095
        self.caption:SetMouseVisible(true);
552 Thurallor-7095
 
553 Thurallor-7095
        -- While mouse is over caption, highlight the label to indicate that it can be clicked.
554 Thurallor-7095
        function self.caption.MouseEnter(caption)
555 Thurallor-7095
            caption.label:SetFontStyle(Turbine.UI.FontStyle.None);
556 112 Thurallor-7095
                        caption.label:SetOutlineColor(self.color); -- boldface effect
557 Thurallor-7095
                        caption.label:SetFontStyle(Turbine.UI.FontStyle.Outline);
558 20 Thurallor-7095
            caption.label:SetVisible(true);
559 Thurallor-7095
        end
560 Thurallor-7095
        function self.caption.MouseLeave(caption)
561 Thurallor-7095
            caption.label:SetFontStyle(Turbine.UI.FontStyle.None);
562 Thurallor-7095
            caption.label:SetOutlineColor(Turbine.UI.Color(0.75, 0, 0, 0));
563 Thurallor-7095
            caption.label:SetFontStyle(Turbine.UI.FontStyle.Outline);
564 112 Thurallor-7095
            caption.label:SetVisible(self.settings.caption.visible == "Always");
565 20 Thurallor-7095
        end
566 Thurallor-7095
 
567 Thurallor-7095
        function self.caption.MouseClick(caption, args)
568 Thurallor-7095
            if (self.mouseMoved) then
569 Thurallor-7095
                self.mouseMoved = false;
570 Thurallor-7095
                return;
571 Thurallor-7095
            end
572 Thurallor-7095
 
573 Thurallor-7095
            -- Left-click resets the sequence back to the beginning.
574 Thurallor-7095
            if (args.Button == Turbine.UI.MouseButton.Left) then
575 Thurallor-7095
                self:Reset();
576 Thurallor-7095
            end
577 Thurallor-7095
 
578 Thurallor-7095
            -- Right-click displays the settings menu.
579 Thurallor-7095
            if (args.Button == Turbine.UI.MouseButton.Right) then
580 Thurallor-7095
                self:ShowSettingsMenu();
581 Thurallor-7095
            end
582 Thurallor-7095
        end
583 Thurallor-7095
        function self.caption.MouseDoubleClick(caption, args)
584 Thurallor-7095
            -- Left-double-click opens the caption editor.
585 Thurallor-7095
            if (args.Button == Turbine.UI.MouseButton.Left) then
586 Thurallor-7095
                self:EditCaption();
587 Thurallor-7095
            end
588 Thurallor-7095
 
589 Thurallor-7095
            -- Right-double-click would open the sequence editor, but
590 Thurallor-7095
            -- since right-click opens the settings menu, right-double
591 Thurallor-7095
            -- -click isn't possible.
592 Thurallor-7095
        end
593 Thurallor-7095
 
594 Thurallor-7095
        -- MouseDown, MouseUp, and MouseMove are used to move the window (if not locked)
595 Thurallor-7095
        function self.caption.MouseDown(caption, args)
596 Thurallor-7095
            if (args.Button == Turbine.UI.MouseButton.Left) then
597 Thurallor-7095
                self.mouseDown = true;
598 143 Thurallor-7095
                self.mouseMoved = false;
599 20 Thurallor-7095
                self.originalMouseX, self.originalMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
600 Thurallor-7095
            end
601 Thurallor-7095
        end
602 Thurallor-7095
        function self.caption.MouseUp(caption, args)
603 Thurallor-7095
            if (args.Button == Turbine.UI.MouseButton.Left) then
604 Thurallor-7095
                self.mouseDown = false;
605 143 Thurallor-7095
                if (self.mouseMoved and not self.settings.locked) then
606 20 Thurallor-7095
                    if (self.parent:GetBarsMoveTogether()) then
607 Thurallor-7095
                        self.parent:SnapToGrid("up");
608 Thurallor-7095
                    else
609 Thurallor-7095
                        self:SnapToGrid();
610 Thurallor-7095
                    end
611 Thurallor-7095
                    self:SaveSettings(false);
612 127 Thurallor-7095
                    self.manager:UnhighlightGrid();
613 Thurallor-7095
                    self.manager:ShowAnchorIcon(nil);
614 20 Thurallor-7095
                end
615 Thurallor-7095
            end
616 Thurallor-7095
        end
617 Thurallor-7095
        function self.caption.MouseMove(caption, args)
618 Thurallor-7095
            if (self.mouseDown and not self.settings.locked) then
619 Thurallor-7095
                self.mouseMoved = true;
620 Thurallor-7095
                local newMouseX, newMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
621 Thurallor-7095
                local deltaX, deltaY = newMouseX - self.originalMouseX, newMouseY - self.originalMouseY;
622 Thurallor-7095
                self.originalMouseX, self.originalMouseY = newMouseX, newMouseY;
623 Thurallor-7095
 
624 Thurallor-7095
                -- See if we need to move other bars along with this one.
625 Thurallor-7095
                if (self.parent:GetBarsMoveTogether()) then
626 Thurallor-7095
                    self.parent:OffsetPosition(deltaX, deltaY, "up");
627 Thurallor-7095
                else
628 Thurallor-7095
                    self:OffsetPosition(deltaX, deltaY);
629 Thurallor-7095
                end
630 Thurallor-7095
 
631 127 Thurallor-7095
                -- Highlight grid if "Snap to grid" is enabled.
632 20 Thurallor-7095
                if (self.globals.snapToGrid) then
633 Thurallor-7095
                    local left, top, width, height = self:GetPosition();
634 Thurallor-7095
                    if ((self.settings.orientation == "Right") or (self.settings.orientation == "Left")) then
635 26 Thurallor-7095
                        width = self.displaySlots;
636 20 Thurallor-7095
                        height = 1;
637 Thurallor-7095
                    else
638 Thurallor-7095
                        width = 1;
639 26 Thurallor-7095
                        height = self.displaySlots;
640 20 Thurallor-7095
                    end
641 158 Thurallor-7095
                    self.manager:HighlightGrid(left, top, width, height, self:GetScale());
642 20 Thurallor-7095
                end
643 127 Thurallor-7095
 
644 Thurallor-7095
                -- Display anchor icon to indicate position reference
645 Thurallor-7095
                local left, top = self:GetSlotsScreenCoords();
646 Thurallor-7095
                self.manager:ShowAnchorIcon(self.settings.anchor, left, top);
647 20 Thurallor-7095
            end
648 Thurallor-7095
        end
649 Thurallor-7095
        function self.caption.DragDrop(caption)
650 Thurallor-7095
            self:EditSequence();
651 Thurallor-7095
        end
652 2 Thurallor-7095
    end
653 Thurallor-7095
    local caption = self.caption;
654 13 Thurallor-7095
    if (not caption.label) then
655 Thurallor-7095
        caption.label = Turbine.UI.Label();
656 Thurallor-7095
        caption.label:SetParent(caption);
657 Thurallor-7095
        caption.label:SetMouseVisible(false);
658 Thurallor-7095
    end
659 Thurallor-7095
    local label = caption.label;
660 112 Thurallor-7095
        caption:SetMouseVisible((not self.settings.caption.clickThru) and (self.settings.caption.visible ~= "Never"));
661 13 Thurallor-7095
 
662 Thurallor-7095
    local alignment;
663 Thurallor-7095
    local where = self.settings.orientation;
664 2 Thurallor-7095
    if (self.settings.caption.position == "end") then
665 Thurallor-7095
        local swap = {Up = "Down"; Down = "Up"; Left = "Right"; Right = "Left"};
666 Thurallor-7095
        where = swap[where];
667 Thurallor-7095
    end
668 Thurallor-7095
    if (where == "Up") then
669 Thurallor-7095
        alignment = Turbine.UI.ContentAlignment.TopCenter;
670 Thurallor-7095
    elseif (where == "Down") then
671 Thurallor-7095
        alignment = Turbine.UI.ContentAlignment.BottomCenter;
672 Thurallor-7095
    elseif (where == "Right") then
673 Thurallor-7095
        alignment = Turbine.UI.ContentAlignment.MiddleRight;
674 Thurallor-7095
    else -- "Left"
675 Thurallor-7095
        alignment = Turbine.UI.ContentAlignment.MiddleLeft;
676 Thurallor-7095
    end
677 Thurallor-7095
 
678 Thurallor-7095
    label:SetText(self.settings.caption.text);
679 112 Thurallor-7095
    label:SetVisible((self.settings.caption.visible == "Always") or ((self.settings.caption.visible == "WhenMouseIsPresent") and self.mouseInside));
680 2 Thurallor-7095
    self:FormatCaptionLabel(label, alignment);
681 Thurallor-7095
    if (self.captionEditor and self.captionEditor:WantsCaptionUpdates()) then
682 Thurallor-7095
        local textBox = self.captionEditor:GetTextBox();
683 Thurallor-7095
        self:FormatCaptionLabel(textBox, alignment);
684 Thurallor-7095
        self.captionEditor:Redraw();
685 Thurallor-7095
    end
686 20 Thurallor-7095
end
687 2 Thurallor-7095
 
688 20 Thurallor-7095
function Bar:MouseArrive()
689 Thurallor-7095
    if (self.mouseInside) then
690 Thurallor-7095
        -- Already inside; do nothing.
691 Thurallor-7095
        return;
692 2 Thurallor-7095
    end
693 20 Thurallor-7095
    self.mouseInside = true;
694 42 Thurallor-7095
    self.parent:MouseArrive(self.objectID);
695 112 Thurallor-7095
        self:BringToFront();
696 Thurallor-7095
        if (self.settings.caption.visible == "WhenMouseIsPresent") then
697 Thurallor-7095
                self.caption.label:SetVisible(true);
698 Thurallor-7095
        end
699 121 Thurallor-7095
    if (self.Log) then
700 Thurallor-7095
        DoCallbacks(self, "Log", {"arrived", "MOUSE"});
701 Thurallor-7095
    end
702 20 Thurallor-7095
    DoCallbacks(self, "MouseArrived");
703 Thurallor-7095
    self:SetWantsUpdates(true);
704 2 Thurallor-7095
end
705 Thurallor-7095
 
706 42 Thurallor-7095
function Bar:MouseInside(mouseLeft, mouseTop)
707 Thurallor-7095
    if (self:IsHidden()) then
708 Thurallor-7095
        return false;
709 Thurallor-7095
    end
710 Thurallor-7095
    local left, top, width, height = self:GetSlotsScreenCoords();
711 Thurallor-7095
    local spacing = 1;
712 Thurallor-7095
    left = left - spacing;
713 Thurallor-7095
    top = top - spacing;
714 Thurallor-7095
    local right = left + width + 2 * spacing;
715 Thurallor-7095
    local bottom = top + height + 2 * spacing;
716 Thurallor-7095
    return ((mouseLeft >= left) and (mouseLeft < right) and (mouseTop >= top) and (mouseTop < bottom));
717 Thurallor-7095
end
718 Thurallor-7095
 
719 20 Thurallor-7095
function Bar:MouseDepart()
720 Thurallor-7095
    self.mouseInside = false;
721 42 Thurallor-7095
    self.parent:MouseDepart(self.objectID);
722 112 Thurallor-7095
        if (self.settings.caption.visible == "WhenMouseIsPresent") then
723 Thurallor-7095
                self.caption.label:SetVisible(false);
724 Thurallor-7095
        end
725 121 Thurallor-7095
    if (self.Log) then
726 Thurallor-7095
        DoCallbacks(self, "Log", {"departed", "MOUSE"});
727 Thurallor-7095
    end
728 20 Thurallor-7095
    DoCallbacks(self, "MouseDeparted");
729 Thurallor-7095
end
730 Thurallor-7095
 
731 116 Thurallor-7095
function Bar:MouseWheel(args)
732 Thurallor-7095
    local dir = args.Direction;
733 117 Thurallor-7095
    local prevSlot = args.s;
734 Thurallor-7095
    local mousePos = prevSlot and (prevSlot > 0) and self.slots[prevSlot].pos;
735 116 Thurallor-7095
 
736 Thurallor-7095
    -- Increment wheel position according to chosen wheel speed
737 Thurallor-7095
    self.wheelPosition = self.wheelPosition + (dir * self.settings.wheelSpeed);
738 Thurallor-7095
    if (math.abs(self.wheelPosition) < 1) then
739 Thurallor-7095
        -- More wheel motion is needed
740 Thurallor-7095
        return;
741 Thurallor-7095
    end
742 Thurallor-7095
    dir = self.wheelPosition;
743 Thurallor-7095
    self.wheelPosition = 0;
744 121 Thurallor-7095
    if (self.Log) then
745 Thurallor-7095
        if (dir > 0) then
746 Thurallor-7095
            DoCallbacks(self, "Log", {"wheel moved forward", "MOUSE"});
747 Thurallor-7095
        else
748 Thurallor-7095
            DoCallbacks(self, "Log", {"wheel moved backward", "MOUSE"});
749 Thurallor-7095
        end
750 Thurallor-7095
    end
751 116 Thurallor-7095
 
752 Thurallor-7095
    -- Find next or previous visible slot
753 117 Thurallor-7095
    local s = self.cursorSlot;
754 116 Thurallor-7095
    repeat
755 Thurallor-7095
        s = s + dir;
756 Thurallor-7095
        if (s > #self.slots) then
757 Thurallor-7095
            s = 1;
758 Thurallor-7095
        elseif (s < 1) then
759 Thurallor-7095
            s = #self.slots;
760 Thurallor-7095
        end
761 Thurallor-7095
        slot = self.slots[s];
762 Thurallor-7095
        if ((s == self.cursorSlot) or (not slot)) then
763 Thurallor-7095
            -- No other visible slots; do nothing.
764 Thurallor-7095
            return;
765 Thurallor-7095
        end
766 Thurallor-7095
    until (not (slot.hidden or slot.isFolded));
767 Thurallor-7095
 
768 Thurallor-7095
    -- Notify slot under cursor that the mouse has exited, to turn off the highlight
769 117 Thurallor-7095
    if (prevSlot) then
770 116 Thurallor-7095
        DoCallbacks(self.slots[prevSlot], "MouseLeave");
771 Thurallor-7095
    end
772 Thurallor-7095
    self:SetCursorSlot(s);
773 117 Thurallor-7095
 
774 Thurallor-7095
    -- Make sure the item under the cursor is always clickable.  This hack is
775 Thurallor-7095
    -- necessary because as the slot moves, no MouseEnter event occurs and
776 Thurallor-7095
    -- hence no MouseClick events can be received.
777 Thurallor-7095
    for object, pos in pairs(self.visibleSlots) do
778 Thurallor-7095
        if (pos == mousePos) then
779 Thurallor-7095
            object:SetVisible(false);
780 Thurallor-7095
            object:SetVisible(true);
781 Thurallor-7095
            break;
782 Thurallor-7095
        end
783 Thurallor-7095
    end
784 116 Thurallor-7095
end
785 Thurallor-7095
 
786 2 Thurallor-7095
function Bar:EditCaption()
787 Thurallor-7095
    if (self.captionEditor == nil) then
788 Thurallor-7095
        self.captionEditor = CaptionEditor("BarCaption", self, self.caption.label:GetWidth(), self.caption.label:GetHeight(), self.settings.caption.text);
789 121 Thurallor-7095
        self.captionEditor.Closed = function()
790 2 Thurallor-7095
            self.captionEditor = nil;
791 Thurallor-7095
        end
792 Thurallor-7095
    end
793 Thurallor-7095
end
794 Thurallor-7095
 
795 Thurallor-7095
function Bar:EditSequence()
796 Thurallor-7095
    if (self.sequenceEditor == nil) then
797 Thurallor-7095
        self.sequenceEditor = SequenceEditor(self, self.settings);
798 121 Thurallor-7095
        self.sequenceEditor.Closed = function()
799 2 Thurallor-7095
            self.sequenceEditor = nil;
800 Thurallor-7095
        end
801 Thurallor-7095
    end
802 Thurallor-7095
end
803 Thurallor-7095
 
804 121 Thurallor-7095
function Bar:OpenDebugWindow()
805 Thurallor-7095
    local title = L:GetText("/BarMenu/Debug") .. ": " .. self.settings.caption.text;
806 Thurallor-7095
    local debugWindow = Thurallor.UI.LogWindow(title, { self });
807 Thurallor-7095
    debugWindow:SetBackColor(self.color);
808 Thurallor-7095
    debugWindow:SetTrace("MOUSE", "Mouse actions", true);
809 Thurallor-7095
    debugWindow:SetTrace("BAR", "Bar status changes", true);
810 146 Thurallor-7095
    debugWindow:SetTrace("ADVANCE", "Bar advancement", true);
811 121 Thurallor-7095
    debugWindow:SetTrace("SPECIAL-SLOT", "Special slot actions", true);
812 Thurallor-7095
    debugWindow:SetTrace("EVENT", "Event behaviours", true);
813 Thurallor-7095
    debugWindow:SetVisible(true);
814 Thurallor-7095
    debugWindow:AppendText("Debugging started");
815 Thurallor-7095
 
816 Thurallor-7095
    -- Forward log information fron the Gears object to the DebugWindow.
817 Thurallor-7095
    self.gearsSlot.Log = function(_, args)
818 Thurallor-7095
        if (self.Log == nil) then
819 Thurallor-7095
            -- All debug windows closed.
820 Thurallor-7095
            self.gearsSlot.Log = nil;
821 Thurallor-7095
        else
822 Thurallor-7095
            DoCallbacks(self, "Log", args);
823 Thurallor-7095
        end
824 Thurallor-7095
    end
825 Thurallor-7095
end
826 Thurallor-7095
 
827 2 Thurallor-7095
function Bar:FormatCaptionLabel(control, alignment)
828 Thurallor-7095
    control:SetFont(self.settings.caption.font);
829 Thurallor-7095
    control:SetForeColor(self.color);
830 Thurallor-7095
    control:SetFontStyle(Turbine.UI.FontStyle.Outline);
831 Thurallor-7095
    control:SetOutlineColor(Turbine.UI.Color(0.75, 0, 0, 0));
832 Thurallor-7095
    control:SetTextAlignment(alignment);
833 Thurallor-7095
    control:SetWidth(self.settings.caption.width);
834 Thurallor-7095
    control:SetHeight(self.settings.caption.height);
835 169 Thurallor-7095
    control:SetText(control:GetText());
836 2 Thurallor-7095
end
837 Thurallor-7095
 
838 8 Thurallor-7095
function Bar:MoveToMouseCursor()
839 125 Thurallor-7095
    -- If animating, go head and complete the animation instantaneously.
840 Thurallor-7095
    -- User is going to want to click the slot immediately; and we need
841 Thurallor-7095
    -- to know where the slot is going to end up in order to reposition the
842 Thurallor-7095
    -- bar properly.
843 Thurallor-7095
    if (self.animationStartTime) then
844 Thurallor-7095
        self:Animate(self.settings.animation.duration);
845 Thurallor-7095
    end
846 Thurallor-7095
 
847 111 Thurallor-7095
    -- PointToScreen doesn't work with scaled windows, so we have to do the calculations ourselves.
848 Thurallor-7095
    local winLeft, winTop = Turbine.UI.Window.GetPosition(self);
849 Thurallor-7095
    local containerX, containerY = self.slotContainer:GetPosition();
850 158 Thurallor-7095
    local scale = self:GetScale() / 32;
851 111 Thurallor-7095
    containerX = containerX * scale;
852 Thurallor-7095
    containerY = containerY * scale;
853 Thurallor-7095
    local cursorX, cursorY = self.cursor:GetPosition();
854 Thurallor-7095
    cursorX = cursorX * scale + containerX + winLeft;
855 Thurallor-7095
    cursorY = cursorY * scale + containerY + winTop;
856 Thurallor-7095
    local cursorWidth = self.cursor:GetWidth() * scale;
857 Thurallor-7095
    local cursorHeight = self.cursor:GetSize() * scale;
858 Thurallor-7095
    local cursorCenter = (cursorX + math.floor(cursorWidth / 2));
859 Thurallor-7095
    local cursorMiddle = (cursorY + math.floor(cursorHeight / 2));
860 Thurallor-7095
    local mouseX, mouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
861 8 Thurallor-7095
    self:OffsetPosition(mouseX - cursorCenter, mouseY - cursorMiddle);
862 31 Thurallor-7095
    Turbine.UI.Window.Activate(self);
863 125 Thurallor-7095
 
864 Thurallor-7095
    -- Make sure the item under the cursor is always clickable.  This hack is
865 Thurallor-7095
    -- necessary because as the slot moves, no MouseEnter event occurs and
866 Thurallor-7095
    -- hence no MouseClick events can be received.
867 Thurallor-7095
    self.slots[self.cursorSlot]:SetVisible(false);
868 Thurallor-7095
    self.slots[self.cursorSlot]:SetVisible(true);
869 8 Thurallor-7095
end
870 Thurallor-7095
 
871 13 Thurallor-7095
-- Bar is positioned with respect to the topmost/leftmost quickslot.
872 Thurallor-7095
function Bar:GetSlotsScreenCoords()
873 Thurallor-7095
    local winLeft, winTop = Turbine.UI.Window.GetPosition(self);
874 Thurallor-7095
    local firstLeft, firstTop = self:GetSlotCoords(1);
875 26 Thurallor-7095
    local lastLeft, lastTop = self:GetSlotCoords(self.displaySlots);
876 13 Thurallor-7095
    local slotLeft, slotTop = math.min(firstLeft, lastLeft), math.min(firstTop, lastTop);
877 Thurallor-7095
    local slotRight = math.max(firstLeft, lastLeft) + self.settings.slotSize;
878 Thurallor-7095
    local slotBottom = math.max(firstTop, lastTop) + self.settings.slotSize;
879 158 Thurallor-7095
    local scale = self:GetScale() / 32;
880 16 Thurallor-7095
    -- If animating, use destination position (self.slotsLeft, self.slotsTop) rather than actual current position (self.slotContainer:GetPosition).
881 Thurallor-7095
    local left = winLeft + scale * (self.slotsLeft + slotLeft);
882 Thurallor-7095
    local top = winTop + scale * (self.slotsTop + slotTop);
883 Thurallor-7095
    local width = scale * (slotRight - slotLeft);
884 Thurallor-7095
    local height = scale * (slotBottom - slotTop);
885 13 Thurallor-7095
    return left, top, width, height;
886 Thurallor-7095
end
887 Thurallor-7095
 
888 Thurallor-7095
function Bar:SetPosition(left, top)
889 26 Thurallor-7095
    local anchorLeft, anchorTop = self.manager:GetAnchorPosition(self.settings.anchor);
890 27 Thurallor-7095
    local changed = true;
891 26 Thurallor-7095
    if (left == nil) then
892 Thurallor-7095
        left = self.settings.position.left + anchorLeft;
893 Thurallor-7095
        top = self.settings.position.top + anchorTop;
894 27 Thurallor-7095
        changed = false;
895 26 Thurallor-7095
    end
896 13 Thurallor-7095
    local winLeft, winTop = Turbine.UI.Window.GetPosition(self);
897 Thurallor-7095
    local slotLeft, slotTop = self:GetSlotsScreenCoords();
898 Thurallor-7095
    local leftOffset, topOffset = slotLeft - winLeft, slotTop - winTop;
899 Thurallor-7095
    Turbine.UI.Window.SetPosition(self, left - leftOffset, top - topOffset);
900 27 Thurallor-7095
    if (changed) then
901 Thurallor-7095
        self.settings.position = { left = left - anchorLeft; top = top - anchorTop };
902 Thurallor-7095
        self:SaveSettings(false);
903 Thurallor-7095
    end
904 13 Thurallor-7095
end
905 Thurallor-7095
 
906 26 Thurallor-7095
function Bar:SetAnchorPoint(anchor)
907 Thurallor-7095
    local left, top = self:GetPosition();
908 Thurallor-7095
    self.settings.anchor = anchor;
909 Thurallor-7095
    self:SetPosition(left, top);
910 13 Thurallor-7095
end
911 Thurallor-7095
 
912 26 Thurallor-7095
-- Returns the position with respect to the top, left corner of the screen, regardless of anchor point.
913 13 Thurallor-7095
function Bar:GetPosition()
914 26 Thurallor-7095
    local anchorLeft, anchorTop = self.manager:GetAnchorPosition(self.settings.anchor);
915 Thurallor-7095
    return anchorLeft + self.settings.position.left, anchorTop + self.settings.position.top;
916 13 Thurallor-7095
end
917 Thurallor-7095
 
918 2 Thurallor-7095
function Bar:OffsetPosition(deltaX, deltaY)
919 16 Thurallor-7095
    local left, top = self:GetPosition();
920 Thurallor-7095
    self:SetPosition(left + deltaX, top + deltaY);
921 2 Thurallor-7095
end
922 Thurallor-7095
 
923 Thurallor-7095
function Bar:SnapToGrid()
924 26 Thurallor-7095
    if (self:IsLocked() or (not self.globals.snapToGrid)) then
925 2 Thurallor-7095
        return;
926 Thurallor-7095
    end
927 13 Thurallor-7095
    local left, top = self:GetSlotsScreenCoords();
928 158 Thurallor-7095
    local newLeft, newTop = self.parent.manager:GetNearestGridPos(left, top, self:GetScale());
929 16 Thurallor-7095
    self:SetPosition(newLeft, newTop);
930 2 Thurallor-7095
    self:SaveSettings(false);
931 Thurallor-7095
end
932 Thurallor-7095
 
933 13 Thurallor-7095
function Bar:AddSettingsMenuItem(parent, itemName, fromOptionsPanel)
934 2 Thurallor-7095
    local item = Turbine.UI.MenuItem(L:GetText(itemName), true, false);
935 Thurallor-7095
    parent:GetItems():Add(item);
936 Thurallor-7095
 
937 Thurallor-7095
    if (itemName == "Root") then
938 Thurallor-7095
        local prevContext = L:SetContext("/BarMenu");
939 Thurallor-7095
        parent:GetItems():Clear();
940 13 Thurallor-7095
        if (fromOptionsPanel and (not self:IsHidden())) then
941 2 Thurallor-7095
            self:AddSettingsMenuItem(parent, "Find");
942 Thurallor-7095
        end
943 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Hide");
944 26 Thurallor-7095
        if (self.settings.visibleSlots > 1) then
945 Thurallor-7095
            if (self:IsCollapsed()) then
946 Thurallor-7095
                self:AddSettingsMenuItem(parent, "Expand");
947 Thurallor-7095
            else
948 Thurallor-7095
                self:AddSettingsMenuItem(parent, "Collapse");
949 Thurallor-7095
            end
950 Thurallor-7095
        end
951 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Position");
952 2 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Clone");
953 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Delete");
954 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Export");
955 Thurallor-7095
        self:AddSettingsMenuItem(parent, "EditSequence");
956 8 Thurallor-7095
        self:AddSettingsMenuItem(parent, "EventBehaviors");
957 2 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Settings");
958 121 Thurallor-7095
        self:AddSettingsMenuItem(parent, "Debug");
959 13 Thurallor-7095
        if (not fromOptionsPanel) then
960 28 Thurallor-7095
            if (self.parent ~= self.manager) then
961 Thurallor-7095
                self:AddSettingsMenuItem(parent, "Group");
962 Thurallor-7095
            end
963 2 Thurallor-7095
            Group.AddSettingsMenuItem(self.parent, parent, "Global", true);
964 5 Thurallor-7095
            self:AddSettingsMenuItem(parent, "Directory");
965 2 Thurallor-7095
        end
966 Thurallor-7095
        L:SetContext(prevContext);
967 121 Thurallor-7095
    elseif (itemName == "Debug") then
968 Thurallor-7095
        item:SetText(item:GetText() .. "...");
969 Thurallor-7095
        item.Click = function()
970 Thurallor-7095
            self:OpenDebugWindow();
971 Thurallor-7095
        end
972 26 Thurallor-7095
    elseif (itemName == "Expand") then
973 121 Thurallor-7095
        item.Click = function()
974 26 Thurallor-7095
            self:Expand();
975 Thurallor-7095
        end
976 Thurallor-7095
    elseif (itemName == "Collapse") then
977 121 Thurallor-7095
        item.Click = function()
978 26 Thurallor-7095
            self:Collapse();
979 Thurallor-7095
        end
980 5 Thurallor-7095
    elseif (itemName == "Directory") then
981 121 Thurallor-7095
        item.Click = function()
982 177 Thurallor-7095
            self.manager:ShowDirectory("bars");
983 5 Thurallor-7095
        end
984 2 Thurallor-7095
    elseif (itemName == "Export") then
985 121 Thurallor-7095
        item.Click = function()
986 2 Thurallor-7095
            self:Export();
987 Thurallor-7095
        end
988 Thurallor-7095
    elseif (itemName == "Find") then
989 121 Thurallor-7095
        item.Click = function()
990 2 Thurallor-7095
            self:Find();
991 Thurallor-7095
        end
992 Thurallor-7095
    elseif (itemName == "Hide") then
993 Thurallor-7095
        item:SetChecked(self.settings.hidden);
994 121 Thurallor-7095
        item.Click = function()
995 2 Thurallor-7095
            self:SetHidden(not self.settings.hidden);
996 Thurallor-7095
        end
997 26 Thurallor-7095
    elseif (itemName == "Position") then
998 Thurallor-7095
        local prevContext = L:SetContext("PositionMenu");
999 Thurallor-7095
        self:AddSettingsMenuItem(item, "LockPosition");
1000 Thurallor-7095
        self:AddSettingsMenuItem(item, "RelativeTo");
1001 Thurallor-7095
        L:SetContext(prevContext);
1002 2 Thurallor-7095
    elseif (itemName == "LockPosition") then
1003 Thurallor-7095
        item:SetChecked(self.settings.locked);
1004 121 Thurallor-7095
        item.Click = function()
1005 2 Thurallor-7095
            self:SetLocked(not self.settings.locked);
1006 Thurallor-7095
        end
1007 26 Thurallor-7095
    elseif (itemName == "RelativeTo") then
1008 Thurallor-7095
        local prevContext = L:SetContext("RelativeToMenu");
1009 Thurallor-7095
        for text in values(L:GetSortedTexts()) do
1010 Thurallor-7095
            local anchor = L:GetItem(text);
1011 Thurallor-7095
            local newItem = self:AddSettingsMenuItem(item, anchor);
1012 Thurallor-7095
            newItem:SetChecked(anchor == self.settings.anchor);
1013 31 Thurallor-7095
            newItem:SetEnabled(anchor ~= self.settings.anchor);
1014 121 Thurallor-7095
            newItem.Click = function()
1015 26 Thurallor-7095
                self:SetAnchorPoint(anchor);
1016 Thurallor-7095
            end
1017 Thurallor-7095
        end
1018 Thurallor-7095
        L:SetContext(prevContext);
1019 2 Thurallor-7095
    elseif (itemName == "EditSequence") then
1020 Thurallor-7095
        item:SetEnabled(not self.sequenceEditor);
1021 121 Thurallor-7095
        item.Click = function()
1022 2 Thurallor-7095
            self:EditSequence();
1023 Thurallor-7095
        end
1024 8 Thurallor-7095
    elseif (itemName == "EventBehaviors") then
1025 Thurallor-7095
        local prevContext = L:SetContext("/EventBehaviorsMenu");
1026 Thurallor-7095
        if (self.settings.eventsEnabled) then
1027 Thurallor-7095
            if (#self.settings.eventHandlers > 0) then
1028 Thurallor-7095
                self:AddSettingsMenuItem(item, "CurrentBehaviors");
1029 Thurallor-7095
            end
1030 Thurallor-7095
            self:AddSettingsMenuItem(item, "AddBehavior");
1031 Thurallor-7095
            self:AddSettingsMenuItem(item, "DisableEvents");
1032 Thurallor-7095
        else
1033 Thurallor-7095
            self:AddSettingsMenuItem(item, "EnableEvents");
1034 Thurallor-7095
        end
1035 Thurallor-7095
        L:SetContext(prevContext);
1036 Thurallor-7095
    elseif (itemName == "EnableEvents") then
1037 Thurallor-7095
        item.Click = function()
1038 177 Thurallor-7095
            self:SetEventHandlersEnabled(true);
1039 8 Thurallor-7095
        end
1040 Thurallor-7095
    elseif (itemName == "DisableEvents") then
1041 Thurallor-7095
        item.Click = function()
1042 177 Thurallor-7095
            self:SetEventHandlersEnabled(false);
1043 8 Thurallor-7095
        end
1044 Thurallor-7095
    elseif (itemName == "CurrentBehaviors") then
1045 Thurallor-7095
        if (self.settings.eventHandlers) then
1046 Thurallor-7095
            for h = 1, #self.settings.eventHandlers do
1047 Thurallor-7095
                local handler = self.settings.eventHandlers[h];
1048 Thurallor-7095
                local handlerItem = Turbine.UI.MenuItem(handler.description, true, false);
1049 Thurallor-7095
                item:GetItems():Add(handlerItem);
1050 Thurallor-7095
                local removeItem = Turbine.UI.MenuItem(L:GetText("Remove"), true, false);
1051 Thurallor-7095
                handlerItem:GetItems():Add(removeItem);
1052 Thurallor-7095
                removeItem.Click = function()
1053 Thurallor-7095
                    self:RemoveEventHandler(h);
1054 Thurallor-7095
                end
1055 Thurallor-7095
            end
1056 Thurallor-7095
        end
1057 Thurallor-7095
    elseif (itemName == "AddBehavior") then
1058 20 Thurallor-7095
        local prevContext = L:SetContext("/EventBehaviorsMenu/Actions");
1059 8 Thurallor-7095
        self:AddSettingsMenuItem(item, "ShowBar");
1060 Thurallor-7095
        self:AddSettingsMenuItem(item, "HideBar");
1061 Thurallor-7095
        self:AddSettingsMenuItem(item, "ResetBar");
1062 16 Thurallor-7095
        self.availableEvents = self.manager:GetEventNames();
1063 8 Thurallor-7095
        self:AddSettingsMenuItem(item, "MoveToCursor");
1064 26 Thurallor-7095
        self:AddSettingsMenuItem(item, "ExpandBar");
1065 Thurallor-7095
        self:AddSettingsMenuItem(item, "CollapseBar");
1066 128 Thurallor-7095
        self:AddSettingsMenuItem(item, "SetTransparency");
1067 43 Thurallor-7095
        self:AddSettingsMenuItem(item, "StartExecuting");
1068 Thurallor-7095
        self:AddSettingsMenuItem(item, "StopExecuting");
1069 20 Thurallor-7095
        L:SetContext(prevContext);
1070 128 Thurallor-7095
    elseif (itemName == "SetTransparency") then
1071 Thurallor-7095
        local prevContext = L:SetContext("/BarMenu/SettingsMenu/TransparencyMenu");
1072 Thurallor-7095
        local subItem = self:AddSettingsMenuItem(item, "SetTransparency:");
1073 Thurallor-7095
        subItem.itemName = "SetTransparency";
1074 Thurallor-7095
        subItem:SetText(L:GetText("UseGlobalSetting"));
1075 Thurallor-7095
        subItem.argName = L:GetText("default");
1076 Thurallor-7095
        subItem.argValue = "nil";
1077 Thurallor-7095
        for i = 0, 10 do
1078 Thurallor-7095
            subItem = self:AddSettingsMenuItem(item, "SetTransparency:");
1079 Thurallor-7095
            subItem.itemName = "SetTransparency";
1080 Thurallor-7095
            subItem.argName = L:GetText("PartiallyTransparent"):gsub("<pct>", i * 10);
1081 Thurallor-7095
            if (i == 0) then
1082 Thurallor-7095
                subItem:SetText(L:GetText("FullyTransparent"));
1083 Thurallor-7095
                subItem.argValue = "0";
1084 Thurallor-7095
            elseif (i == 10) then
1085 Thurallor-7095
                subItem:SetText(L:GetText("FullyOpaque"));
1086 Thurallor-7095
                subItem.argValue = "1";
1087 Thurallor-7095
            else
1088 Thurallor-7095
                subItem:SetText(subItem.argName);
1089 Thurallor-7095
                subItem.argValue = "0." .. i;
1090 Thurallor-7095
            end
1091 Thurallor-7095
        end
1092 Thurallor-7095
        L:SetContext(prevContext);
1093 Thurallor-7095
    elseif (string.find("|SetTransparency:|ShowBar|HideBar|ResetBar|MoveToCursor|ExpandBar|CollapseBar|StartExecuting|StopExecuting|", "|" .. itemName .. "|")) then
1094 20 Thurallor-7095
        local prevContext = L:SetContext("/EventBehaviorsMenu/Triggers");
1095 8 Thurallor-7095
        item.itemName = itemName;
1096 20 Thurallor-7095
        self.availableEvents = self.manager:GetEventNames();
1097 Thurallor-7095
 
1098 Thurallor-7095
        -- Show only the options that make sense
1099 31 Thurallor-7095
        if (itemName ~= "MoveToCursor") then
1100 43 Thurallor-7095
            if ((itemName ~= "ResetBar") and (itemName ~= "StopExecuting")) then
1101 34 Thurallor-7095
                self:AddSettingsMenuItem(item, "AtStartup");
1102 Thurallor-7095
            end
1103 31 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenCombatBegins");
1104 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenCombatEnds");
1105 Thurallor-7095
        end
1106 43 Thurallor-7095
        self:AddSettingsMenuItem(item, "WhenTargetChanges");
1107 128 Thurallor-7095
        if (string.find("|SetTransparency:|ResetBar|ExpandBar|StartExecuting|", "|" .. itemName .. "|")) then
1108 20 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenMouseArrives");
1109 26 Thurallor-7095
        end
1110 128 Thurallor-7095
        if (string.find("|SetTransparency:|HideBar|ResetBar|CollapseBar|StopExecuting|", "|" .. itemName .. "|")) then
1111 20 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenMouseDeparts");
1112 Thurallor-7095
        end
1113 128 Thurallor-7095
        if (string.find("|SetTransparency:|ShowBar|ResetBar|MoveToCursor|StartExecuting|StopExecuting|", "|" .. itemName .. "|")) then
1114 35 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenTraitTreeChanges");
1115 111 Thurallor-7095
            self:AddSettingsMenuItem(item, "WhenStanceChanges");
1116 35 Thurallor-7095
        end
1117 165 Thurallor-7095
        self:AddSettingsMenuItem(item, "WhenYouAreIncapacitated");
1118 Thurallor-7095
        self:AddSettingsMenuItem(item, "WhenYouAreRevived");
1119 33 Thurallor-7095
        self:AddSettingsMenuItem(item, "WhenEventOccurs");
1120 20 Thurallor-7095
        L:SetContext(prevContext);
1121 8 Thurallor-7095
    elseif (itemName == "WhenEventOccurs") then
1122 33 Thurallor-7095
        if (#self.availableEvents > 0) then
1123 Thurallor-7095
            for e = 1, #self.availableEvents do
1124 Thurallor-7095
                local eventName = self.availableEvents[e];
1125 Thurallor-7095
                local eventNameItem = Turbine.UI.MenuItem(eventName, true, false);
1126 Thurallor-7095
                item:GetItems():Add(eventNameItem);
1127 Thurallor-7095
                eventNameItem.Click = function()
1128 128 Thurallor-7095
                    self:AddEventHandler("WhenEventOccurs:" .. eventName, parent.itemName, parent.argValue, parent.argName);
1129 33 Thurallor-7095
                end
1130 8 Thurallor-7095
            end
1131 33 Thurallor-7095
        else
1132 Thurallor-7095
            local noEventsItem = Turbine.UI.MenuItem(L:GetText("/EventBehaviorsMenu/NoEventsDefined"), false, false);
1133 Thurallor-7095
            item:GetItems():Add(noEventsItem);
1134 8 Thurallor-7095
        end
1135 177 Thurallor-7095
        local eventDirectoryItem = Turbine.UI.MenuItem("( . . . )", true, false);
1136 Thurallor-7095
        eventDirectoryItem.Click = function()
1137 Thurallor-7095
            self.manager:ShowDirectory("events");
1138 Thurallor-7095
        end
1139 Thurallor-7095
        item:GetItems():Add(eventDirectoryItem);
1140 165 Thurallor-7095
    elseif (string.find("|AtStartup|WhenTargetChanges|WhenCombatBegins|WhenCombatEnds|WhenMouseArrives|WhenMouseDeparts|WhenTraitTreeChanges|WhenStanceChanges|WhenYouAreIncapacitated|WhenYouAreRevived|", "|" .. itemName .. "|")) then
1141 8 Thurallor-7095
        item.Click = function()
1142 128 Thurallor-7095
            self:AddEventHandler(itemName, parent.itemName, parent.argValue, parent.argName);
1143 8 Thurallor-7095
        end
1144 2 Thurallor-7095
    elseif (itemName == "Settings") then
1145 Thurallor-7095
        local prevContext = L:SetContext("SettingsMenu");
1146 Thurallor-7095
        self:AddSettingsMenuItem(item, "Orientation");
1147 Thurallor-7095
        if ((self.settings.orientation == "Up") or (self.settings.orientation == "Down")) then
1148 Thurallor-7095
            self:AddSettingsMenuItem(item, "Height");
1149 Thurallor-7095
        else
1150 Thurallor-7095
            self:AddSettingsMenuItem(item, "Width");
1151 Thurallor-7095
        end
1152 Thurallor-7095
        self:AddSettingsMenuItem(item, "Cursor");
1153 116 Thurallor-7095
        self:AddSettingsMenuItem(item, "MouseWheel");
1154 2 Thurallor-7095
        self:AddSettingsMenuItem(item, "Caption");
1155 Thurallor-7095
        self:AddSettingsMenuItem(item, "Color");
1156 128 Thurallor-7095
        self:AddSettingsMenuItem(item, "Transparency");
1157 158 Thurallor-7095
        self:AddSettingsMenuItem(item, "Scale");
1158 2 Thurallor-7095
        self:AddSettingsMenuItem(item, "Animation");
1159 16 Thurallor-7095
        self:AddSettingsMenuItem(item, "HideAutomatics");
1160 Thurallor-7095
        self:AddSettingsMenuItem(item, "HideInactiveBranches");
1161 43 Thurallor-7095
        self:AddSettingsMenuItem(item, "ContinuousExecution");
1162 2 Thurallor-7095
        L:SetContext(prevContext);
1163 43 Thurallor-7095
    elseif (itemName == "ContinuousExecution") then
1164 Thurallor-7095
        item:SetChecked(self.settings.continuous);
1165 121 Thurallor-7095
        item.Click = function()
1166 43 Thurallor-7095
            self.settings.continuous = not self.settings.continuous;
1167 Thurallor-7095
            if (self.settings.continuous) then
1168 Thurallor-7095
                -- Enforce hiding of automatics and inactive branches
1169 Thurallor-7095
                self.settings.hideAutomatics = true;
1170 Thurallor-7095
                self.settings.hideInactiveBranches = true;
1171 Thurallor-7095
            else
1172 Thurallor-7095
                self.gearsSlot:SetRunning(false);
1173 Thurallor-7095
            end
1174 Thurallor-7095
            self:SaveSettings(false);
1175 Thurallor-7095
            self:ReapplySettings();
1176 Thurallor-7095
        end
1177 16 Thurallor-7095
    elseif (itemName == "HideAutomatics") then
1178 Thurallor-7095
        item:SetChecked(self.settings.hideAutomatics);
1179 121 Thurallor-7095
        item.Click = function()
1180 16 Thurallor-7095
            self.settings.hideAutomatics = not self.settings.hideAutomatics;
1181 43 Thurallor-7095
            if (not self.settings.hideAutomatics) then
1182 Thurallor-7095
                -- Continuous mode not allowed if showing automatics
1183 Thurallor-7095
                if (self.settings.continuous) then
1184 Thurallor-7095
                    self.gearsSlot:SetRunning(false);
1185 Thurallor-7095
                    self.settings.continuous = false;
1186 Thurallor-7095
                end
1187 Thurallor-7095
            end
1188 16 Thurallor-7095
            self:SaveSettings(false);
1189 Thurallor-7095
            self:ReapplySettings();
1190 Thurallor-7095
        end
1191 Thurallor-7095
    elseif (itemName == "HideInactiveBranches") then
1192 Thurallor-7095
        item:SetChecked(self.settings.hideInactiveBranches);
1193 121 Thurallor-7095
        item.Click = function()
1194 16 Thurallor-7095
            self.settings.hideInactiveBranches = not self.settings.hideInactiveBranches;
1195 43 Thurallor-7095
            if (not self.settings.hideInactiveBranches) then
1196 Thurallor-7095
                -- Continuous mode not allowed if showing inactive branches
1197 Thurallor-7095
                if (self.settings.continuous) then
1198 Thurallor-7095
                    self.gearsSlot:SetRunning(false);
1199 Thurallor-7095
                    self.settings.continuous = false;
1200 Thurallor-7095
                end
1201 Thurallor-7095
            end
1202 16 Thurallor-7095
            self:SaveSettings(false);
1203 Thurallor-7095
            self:ReapplySettings();
1204 Thurallor-7095
        end
1205 2 Thurallor-7095
    elseif (itemName == "Color") then
1206 Thurallor-7095
        item:SetEnabled(not self.colorPicker);
1207 121 Thurallor-7095
        item.Click = function()
1208 2 Thurallor-7095
            self:EditColor();
1209 Thurallor-7095
        end
1210 128 Thurallor-7095
    elseif (itemName == "Transparency") then
1211 Thurallor-7095
        local prevContext = L:SetContext("/BarMenu/SettingsMenu/TransparencyMenu");
1212 Thurallor-7095
        local checked = (self.settings.opacity == nil);
1213 158 Thurallor-7095
        local globalItem = Turbine.UI.MenuItem(L:GetText("UseGlobalSetting"), true, checked);
1214 Thurallor-7095
        globalItem.Click = function(obj)
1215 Thurallor-7095
            obj:SetChecked(true);
1216 128 Thurallor-7095
            self:SetTransparency(nil);
1217 Thurallor-7095
        end
1218 158 Thurallor-7095
        item:GetItems():Add(globalItem);
1219 Thurallor-7095
 
1220 Thurallor-7095
        checked = not checked;
1221 Thurallor-7095
        local labelItem = Turbine.UI.MenuItem("", true, checked);
1222 Thurallor-7095
        globalItem.labelItem = labelItem;
1223 Thurallor-7095
        labelItem.globalItem = globalItem;
1224 Thurallor-7095
        labelItem.UpdateLabel = function(obj)
1225 Thurallor-7095
            local prevContext = L:SetContext("/BarMenu/SettingsMenu/TransparencyMenu");
1226 Thurallor-7095
            local transparency = self:GetTransparency();
1227 Thurallor-7095
            local text;
1228 Thurallor-7095
            if (transparency == 0) then
1229 Thurallor-7095
                text = L:GetText("FullyTransparent");
1230 Thurallor-7095
            elseif (transparency == 1) then
1231 Thurallor-7095
                text = L:GetText("FullyOpaque");
1232 128 Thurallor-7095
            else
1233 158 Thurallor-7095
                text = L:GetText("PartiallyTransparent"):gsub("<pct>", math.floor(0.5 + transparency * 100));
1234 128 Thurallor-7095
            end
1235 158 Thurallor-7095
            obj.Label:SetText(text);
1236 Thurallor-7095
            L:SetContext(prevContext);
1237 128 Thurallor-7095
        end
1238 158 Thurallor-7095
        labelItem:UpdateLabel();
1239 Thurallor-7095
        labelItem.Click = function(obj)
1240 Thurallor-7095
            obj.KeepOpen = true;
1241 Thurallor-7095
            obj:SetChecked(true);
1242 Thurallor-7095
            self:SetTransparency(self:GetTransparency());
1243 Thurallor-7095
            obj.globalItem:SetChecked(false);
1244 Thurallor-7095
        end
1245 Thurallor-7095
        item:GetItems():Add(labelItem);
1246 Thurallor-7095
 
1247 160 Thurallor-7095
        local sliderItem = Turbine.UI.MenuItem("                                        ", false, false);
1248 158 Thurallor-7095
        local slider = Turbine.UI.Lotro.ScrollBar();
1249 Thurallor-7095
        slider.labelItem = labelItem;
1250 Thurallor-7095
        slider.globalItem = globalItem;
1251 Thurallor-7095
        globalItem.slider = slider;
1252 Thurallor-7095
        slider:SetSize(200, 10);
1253 Thurallor-7095
        slider:SetBackground("Thurallor/SequenceBars/Images/scrollbar_background_horiz.tga");
1254 Thurallor-7095
        slider:SetBlendMode(Turbine.UI.BlendMode.Overlay);
1255 Thurallor-7095
        slider:SetParent(sliderItem.Label);
1256 Thurallor-7095
        slider:SetMinimum(0);
1257 Thurallor-7095
        slider:SetMaximum(100);
1258 Thurallor-7095
        slider:SetSmallChange(1);
1259 Thurallor-7095
        slider:SetLargeChange(10);
1260 Thurallor-7095
        slider:SetValue(math.floor(0.5 + self:GetTransparency() * 100));
1261 Thurallor-7095
        slider.ValueChanged = function(obj)
1262 Thurallor-7095
            self:SetTransparency(obj:GetValue() / 100);
1263 Thurallor-7095
            obj.labelItem:UpdateLabel();
1264 Thurallor-7095
            obj.labelItem:SetChecked(true);
1265 Thurallor-7095
            obj.globalItem:SetChecked(false);
1266 Thurallor-7095
        end
1267 Thurallor-7095
        item:GetItems():Add(sliderItem);
1268 128 Thurallor-7095
        L:SetContext(prevContext);
1269 158 Thurallor-7095
    elseif (itemName == "Scale") then
1270 Thurallor-7095
        local prevContext = L:SetContext("/BarMenu/SettingsMenu/ScaleMenu");
1271 Thurallor-7095
        local checked = (self.settings.scale == nil);
1272 Thurallor-7095
        local globalItem = Turbine.UI.MenuItem(L:GetText("UseGlobalSetting"), true, checked);
1273 Thurallor-7095
        globalItem.Click = function(obj)
1274 Thurallor-7095
            obj:SetChecked(true);
1275 Thurallor-7095
            self:SetScale(nil);
1276 Thurallor-7095
        end
1277 Thurallor-7095
        item:GetItems():Add(globalItem);
1278 Thurallor-7095
 
1279 Thurallor-7095
        checked = not checked;
1280 Thurallor-7095
        local labelItem = Turbine.UI.MenuItem("", true, checked);
1281 Thurallor-7095
        globalItem.labelItem = labelItem;
1282 Thurallor-7095
        labelItem.globalItem = globalItem;
1283 Thurallor-7095
        labelItem.UpdateLabel = function(obj)
1284 Thurallor-7095
            local scale = self:GetScale();
1285 Thurallor-7095
            obj.Label:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/UiScale") .. ": " .. string.format("%d", scale * 100 / 32) .. "%");
1286 Thurallor-7095
        end
1287 Thurallor-7095
        labelItem:UpdateLabel();
1288 Thurallor-7095
        labelItem.Click = function(obj)
1289 Thurallor-7095
            obj.KeepOpen = true;
1290 Thurallor-7095
            obj:SetChecked(true);
1291 Thurallor-7095
            self:SetScale(self:GetScale());
1292 Thurallor-7095
            obj.globalItem:SetChecked(false);
1293 Thurallor-7095
        end
1294 Thurallor-7095
        item:GetItems():Add(labelItem);
1295 Thurallor-7095
 
1296 160 Thurallor-7095
        local sliderItem = Turbine.UI.MenuItem("                                        ", false, false);
1297 158 Thurallor-7095
        local slider = Turbine.UI.Lotro.ScrollBar();
1298 Thurallor-7095
        slider.labelItem = labelItem;
1299 Thurallor-7095
        slider.globalItem = globalItem;
1300 Thurallor-7095
        globalItem.slider = slider;
1301 Thurallor-7095
        slider:SetSize(200, 10);
1302 Thurallor-7095
        slider:SetBackground("Thurallor/SequenceBars/Images/scrollbar_background_horiz.tga");
1303 Thurallor-7095
        slider:SetBlendMode(Turbine.UI.BlendMode.Overlay);
1304 Thurallor-7095
        slider:SetParent(sliderItem.Label);
1305 Thurallor-7095
        slider:SetMinimum(13);
1306 Thurallor-7095
        slider:SetMaximum(96);
1307 Thurallor-7095
        slider:SetSmallChange(1);
1308 Thurallor-7095
        slider:SetLargeChange(10);
1309 Thurallor-7095
        slider:SetValue(self:GetScale());
1310 Thurallor-7095
        slider.ValueChanged = function(obj)
1311 Thurallor-7095
            self:SetScale(obj:GetValue());
1312 Thurallor-7095
            obj.labelItem:UpdateLabel();
1313 Thurallor-7095
            obj.labelItem:SetChecked(true);
1314 Thurallor-7095
            obj.globalItem:SetChecked(false);
1315 Thurallor-7095
        end
1316 Thurallor-7095
        item:GetItems():Add(sliderItem);
1317 Thurallor-7095
        L:SetContext(prevContext);
1318 116 Thurallor-7095
    elseif (itemName == "MouseWheel") then
1319 Thurallor-7095
        local prevContext = L:SetContext("MouseWheelMenu");
1320 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelDisabled");
1321 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelForwardFast");
1322 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelForwardSlow");
1323 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelForwardVerySlow");
1324 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelReverseFast");
1325 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelReverseSlow");
1326 Thurallor-7095
        self:AddSettingsMenuItem(item, "WheelReverseVerySlow");
1327 Thurallor-7095
        L:SetContext(prevContext);
1328 Thurallor-7095
    elseif (string.find("|WheelDisabled|WheelForwardFast|WheelForwardSlow|WheelForwardVerySlow|WheelReverseFast|WheelReverseSlow|WheelReverseVerySlow|", "|" .. itemName .. "|")) then
1329 Thurallor-7095
        local wheelSpeed = { ["WheelDisabled"] = 0; ["WheelForwardFast"] = 1; ["WheelForwardSlow"] = 0.5; ["WheelForwardVerySlow"] = 0.2; ["WheelReverseFast"] = -1; ["WheelReverseSlow"] = -0.5; ["WheelReverseVerySlow"] = -0.2; };
1330 Thurallor-7095
        local checked = (self.settings.wheelSpeed == wheelSpeed[itemName]);
1331 Thurallor-7095
        item:SetChecked(checked);
1332 Thurallor-7095
        item:SetEnabled(not checked);
1333 121 Thurallor-7095
        item.Click = function()
1334 116 Thurallor-7095
            self.wheelPosition = 0;
1335 Thurallor-7095
            self.settings.wheelSpeed = wheelSpeed[itemName];
1336 117 Thurallor-7095
            self:ReapplySettings();
1337 116 Thurallor-7095
        end
1338 2 Thurallor-7095
    elseif (itemName == "Animation") then
1339 Thurallor-7095
        local prevContext = L:SetContext("AnimationMenu");
1340 Thurallor-7095
        self:AddSettingsMenuItem(item, "Instantaneous");
1341 Thurallor-7095
        self:AddSettingsMenuItem(item, "Fast");
1342 Thurallor-7095
        self:AddSettingsMenuItem(item, "Slow");
1343 Thurallor-7095
        self:AddSettingsMenuItem(item, "VerySlow");
1344 Thurallor-7095
        self:AddSettingsMenuItem(item, "Disabled");
1345 Thurallor-7095
        L:SetContext(prevContext);
1346 11 Thurallor-7095
    elseif (string.find("|Instantaneous|Fast|Slow|VerySlow|Disabled|", "|" .. itemName .. "|")) then
1347 2 Thurallor-7095
        local duration = { ["Instantaneous"] = 0; ["Fast"] = 0.05; ["Slow"] = 0.1; ["VerySlow"] = 0.5; ["Disabled"] = -1; };
1348 Thurallor-7095
        local checked = (self.settings.animation.duration == duration[itemName]);
1349 Thurallor-7095
        item:SetChecked(checked);
1350 Thurallor-7095
        item:SetEnabled(not checked);
1351 121 Thurallor-7095
        item.Click = function()
1352 2 Thurallor-7095
            self:SetAnimationSpeed(duration[itemName]);
1353 Thurallor-7095
        end
1354 Thurallor-7095
    elseif (itemName == "Orientation") then
1355 Thurallor-7095
        local prevContext = L:SetContext("OrientationMenu");
1356 Thurallor-7095
        self:AddSettingsMenuItem(item, "Up");
1357 Thurallor-7095
        self:AddSettingsMenuItem(item, "Right");
1358 Thurallor-7095
        self:AddSettingsMenuItem(item, "Left");
1359 Thurallor-7095
        self:AddSettingsMenuItem(item, "Down");
1360 Thurallor-7095
        L:SetContext(prevContext);
1361 Thurallor-7095
    elseif ((itemName == "Up") or (itemName == "Down") or (itemName == "Left") or (itemName == "Right")) then
1362 Thurallor-7095
        local checked = (self.settings.orientation == itemName);
1363 Thurallor-7095
        item:SetChecked(checked);
1364 Thurallor-7095
        item:SetEnabled(not checked);
1365 121 Thurallor-7095
        item.Click = function()
1366 2 Thurallor-7095
            self.settings.orientation = itemName;
1367 Thurallor-7095
            self:SaveSettings(false);
1368 Thurallor-7095
            self:Redraw();
1369 6 Thurallor-7095
            self:MoveOntoScreen();
1370 2 Thurallor-7095
        end
1371 11 Thurallor-7095
    elseif ((itemName == "Width") or (itemName == "Height")) then
1372 2 Thurallor-7095
        local size = self.settings.visibleSlots;
1373 6 Thurallor-7095
        local displayWidth, displayHeight = Turbine.UI.Display.GetSize();
1374 Thurallor-7095
        local minSize = 1, maxSize;
1375 Thurallor-7095
        if ((self.settings.orientation == "Up") or (self.settings.orientation == "Down")) then
1376 Thurallor-7095
            maxSize = math.floor(displayHeight / self.settings.slotSize);
1377 Thurallor-7095
        else
1378 Thurallor-7095
            maxSize = math.floor(displayWidth / self.settings.slotSize);
1379 Thurallor-7095
        end
1380 158 Thurallor-7095
        local prevContext = L:SetContext("/BarMenu/SettingsMenu/HeightWidthMenu");
1381 Thurallor-7095
 
1382 Thurallor-7095
        local labelItem = Turbine.UI.MenuItem("", true, false);
1383 Thurallor-7095
        labelItem.UpdateLabel = function(obj)
1384 Thurallor-7095
            local size = self.settings.visibleSlots;
1385 Thurallor-7095
            local text;
1386 Thurallor-7095
            if (size == 1) then
1387 Thurallor-7095
                text = L:GetText("/BarMenu/SettingsMenu/HeightWidthMenu/Slot");
1388 13 Thurallor-7095
            else
1389 158 Thurallor-7095
                text = L:GetText("/BarMenu/SettingsMenu/HeightWidthMenu/Slots");
1390 2 Thurallor-7095
            end
1391 158 Thurallor-7095
            text = text:gsub("<num>", tostring(size));
1392 Thurallor-7095
            obj.Label:SetText(text);
1393 2 Thurallor-7095
        end
1394 158 Thurallor-7095
        labelItem:UpdateLabel();
1395 Thurallor-7095
        labelItem.Click = function(obj)
1396 Thurallor-7095
            obj.KeepOpen = true;
1397 Thurallor-7095
        end
1398 Thurallor-7095
        item:GetItems():Add(labelItem);
1399 Thurallor-7095
 
1400 160 Thurallor-7095
        local sliderItem = Turbine.UI.MenuItem("                                        ", false, false);
1401 158 Thurallor-7095
        local slider = Turbine.UI.Lotro.ScrollBar();
1402 Thurallor-7095
        slider.labelItem = labelItem;
1403 Thurallor-7095
        slider:SetSize(200, 10);
1404 Thurallor-7095
        slider:SetBackground("Thurallor/SequenceBars/Images/scrollbar_background_horiz.tga");
1405 Thurallor-7095
        slider:SetBlendMode(Turbine.UI.BlendMode.Overlay);
1406 Thurallor-7095
        slider:SetParent(sliderItem.Label);
1407 Thurallor-7095
        slider:SetMinimum(minSize);
1408 Thurallor-7095
        slider:SetMaximum(maxSize);
1409 Thurallor-7095
        slider:SetSmallChange(1);
1410 Thurallor-7095
        slider:SetLargeChange(5);
1411 Thurallor-7095
        slider:SetValue(size);
1412 Thurallor-7095
        slider.ValueChanged = function(obj)
1413 160 Thurallor-7095
            local size = obj:GetValue();
1414 Thurallor-7095
            self.cursorHomePosNudger:SetMaxValue(size);
1415 Thurallor-7095
            if (size < self.settings.cursorHomePosition) then
1416 Thurallor-7095
                self.settings.cursorHomePosition = size;
1417 158 Thurallor-7095
            end
1418 160 Thurallor-7095
            self:ResizeBar(size);
1419 Thurallor-7095
            self:MoveOntoScreen();
1420 158 Thurallor-7095
            obj.labelItem:UpdateLabel();
1421 Thurallor-7095
        end
1422 Thurallor-7095
        item:GetItems():Add(sliderItem);
1423 2 Thurallor-7095
        L:SetContext(prevContext);
1424 Thurallor-7095
    elseif (itemName == "Cursor") then
1425 Thurallor-7095
        local prevContext = L:SetContext("CursorMenu");
1426 Thurallor-7095
        self:AddSettingsMenuItem(item, "Style");
1427 Thurallor-7095
        self:AddSettingsMenuItem(item, "HomePosition");
1428 Thurallor-7095
        L:SetContext(prevContext);
1429 Thurallor-7095
    elseif (itemName == "HomePosition") then
1430 160 Thurallor-7095
        local homePos = self.settings.cursorHomePosition;
1431 Thurallor-7095
        local minPos, maxPos = 1, self.settings.visibleSlots;
1432 Thurallor-7095
        local labelItem = Turbine.UI.MenuItem(L:GetText("/BarMenu/SettingsMenu/CursorMenu/HomePositionMenu/Slot"):gsub("<num>", ""), true, false);
1433 Thurallor-7095
        labelItem.Click = function(obj)
1434 Thurallor-7095
            obj.KeepOpen = true;
1435 2 Thurallor-7095
        end
1436 160 Thurallor-7095
        item:GetItems():Add(labelItem);
1437 Thurallor-7095
 
1438 Thurallor-7095
        local nudgerItem = Turbine.UI.MenuItem(" ", false, false);
1439 Thurallor-7095
        local nudger = Thurallor.UI.Nudger(nudgerItem, Turbine.UI.Lotro.Font.TrajanPro14, homePos, minPos, maxPos);
1440 Thurallor-7095
        nudger:SetWidth(30);
1441 Thurallor-7095
        nudger:SetPosition(25, 5);
1442 Thurallor-7095
        nudger.ValueChanged = function(obj)
1443 Thurallor-7095
            self:Expand();
1444 Thurallor-7095
            self.settings.cursorHomePosition = obj:GetValue();
1445 Thurallor-7095
            self:SaveSettings(false);
1446 Thurallor-7095
            self:Redraw();
1447 Thurallor-7095
        end
1448 Thurallor-7095
        self.cursorHomePosNudger = nudger;
1449 Thurallor-7095
 
1450 Thurallor-7095
        nudgerItem:SetHeight(nudger:GetHeight() + 5);
1451 Thurallor-7095
        nudgerItem.SetSize = function() end; -- don't allow the size to be adjusted by ContextMenu
1452 Thurallor-7095
        local container = item:GetItems();
1453 Thurallor-7095
        container:Add(nudgerItem);
1454 Thurallor-7095
        container:Add(Turbine.UI.MenuItem(" ", false, false));
1455 Thurallor-7095
        container:Add(Turbine.UI.MenuItem(" ", false, false));
1456 2 Thurallor-7095
    elseif (itemName == "Style") then
1457 Thurallor-7095
        local prevContext = L:SetContext("StyleMenu");
1458 11 Thurallor-7095
        local styles = {};
1459 2 Thurallor-7095
        for name, info in pairs(resources.Cursor) do
1460 Thurallor-7095
            local checked = (name == self.settings.cursorStyle);
1461 11 Thurallor-7095
            local text = L:GetText(name);
1462 Thurallor-7095
            local style = Turbine.UI.MenuItem(text, not checked, checked);
1463 Thurallor-7095
            styles[text] = style;
1464 121 Thurallor-7095
            style.Click = function()
1465 2 Thurallor-7095
                self:SetCursorStyle(name);
1466 Thurallor-7095
                self:SaveSettings(false);
1467 Thurallor-7095
                self:Redraw();
1468 Thurallor-7095
            end
1469 Thurallor-7095
        end
1470 11 Thurallor-7095
        -- Display alphabetically.
1471 Thurallor-7095
        for text in sorted_keys(styles) do
1472 Thurallor-7095
            item:GetItems():Add(styles[text]);
1473 Thurallor-7095
        end
1474 2 Thurallor-7095
        L:SetContext(prevContext);
1475 Thurallor-7095
    elseif (itemName == "Caption") then
1476 Thurallor-7095
        local prevContext = L:SetContext("CaptionMenu");
1477 Thurallor-7095
        self:AddSettingsMenuItem(item, "Edit");
1478 26 Thurallor-7095
        self:AddSettingsMenuItem(item, "CaptionPosition");
1479 112 Thurallor-7095
        self:AddSettingsMenuItem(item, "CaptionVisible");
1480 Thurallor-7095
        self:AddSettingsMenuItem(item, "CaptionClickable");
1481 2 Thurallor-7095
        L:SetContext(prevContext);
1482 Thurallor-7095
    elseif (itemName == "Edit") then
1483 Thurallor-7095
        item:SetEnabled(not self.captionEditor);
1484 121 Thurallor-7095
        item.Click = function()
1485 2 Thurallor-7095
            self:EditCaption();
1486 Thurallor-7095
        end
1487 112 Thurallor-7095
    elseif (itemName == "CaptionClickable") then
1488 Thurallor-7095
        item:SetChecked((not self.settings.caption.clickThru) and (self.settings.caption.visible ~= "Never"));
1489 Thurallor-7095
        item:SetEnabled(self.settings.caption.visible ~= "Never");
1490 121 Thurallor-7095
        item.Click = function()
1491 112 Thurallor-7095
            self:SetCaptionClickThru(not self.settings.caption.clickThru);
1492 2 Thurallor-7095
        end
1493 112 Thurallor-7095
    elseif (itemName == "CaptionVisible") then
1494 Thurallor-7095
        local prevContext = L:SetContext("CaptionVisibleMenu");
1495 Thurallor-7095
                for _, option in pairs(L:GetItems()) do
1496 Thurallor-7095
                        local subItem = Turbine.UI.MenuItem(L:GetText(option), true, (self.settings.caption.visible == option));
1497 Thurallor-7095
                        subItem.Click = function()
1498 Thurallor-7095
                                self:SetCaptionVisible(option);
1499 Thurallor-7095
                        end
1500 Thurallor-7095
                        item:GetItems():Add(subItem);
1501 Thurallor-7095
                end
1502 Thurallor-7095
        L:SetContext(prevContext);
1503 26 Thurallor-7095
    elseif (itemName == "CaptionPosition") then
1504 Thurallor-7095
        local prevContext = L:SetContext("CaptionPositionMenu");
1505 2 Thurallor-7095
        if ((self.settings.orientation == "Up") or (self.settings.orientation == "Down")) then
1506 Thurallor-7095
            self:AddSettingsMenuItem(item, "Top");
1507 Thurallor-7095
            self:AddSettingsMenuItem(item, "Bottom");
1508 Thurallor-7095
        else -- "Left" or "Right"
1509 Thurallor-7095
            self:AddSettingsMenuItem(item, "LeftSide");
1510 Thurallor-7095
            self:AddSettingsMenuItem(item, "RightSide");
1511 Thurallor-7095
        end
1512 Thurallor-7095
        L:SetContext(prevContext);
1513 11 Thurallor-7095
    elseif (string.find("|Top|Bottom|LeftSide|RightSide|", "|" .. itemName .. "|")) then
1514 2 Thurallor-7095
        local beginPosMap = { Left = "RightSide"; Right = "LeftSide"; Up = "Bottom"; Down = "Top" };
1515 Thurallor-7095
        local amBeginPos = (itemName == beginPosMap[self.settings.orientation]);
1516 Thurallor-7095
        local beginPosSelected = (self.settings.caption.position == "beginning");
1517 Thurallor-7095
        local checked = (amBeginPos and beginPosSelected) or (not amBeginPos and not beginPosSelected);
1518 Thurallor-7095
        local myOrientation = (amBeginPos and "beginning") or "end";
1519 Thurallor-7095
        item:SetChecked(checked);
1520 Thurallor-7095
        item:SetEnabled(not checked);
1521 121 Thurallor-7095
        item.Click = function()
1522 2 Thurallor-7095
            self.settings.caption.position = myOrientation;
1523 Thurallor-7095
            self:SaveSettings(false);
1524 34 Thurallor-7095
            self:Redraw(true);
1525 6 Thurallor-7095
            self:MoveOntoScreen();
1526 2 Thurallor-7095
        end
1527 Thurallor-7095
    elseif (itemName == "Clone") then
1528 121 Thurallor-7095
        item.Click = function()
1529 2 Thurallor-7095
            self.parent:CloneBar(self.objectID);
1530 Thurallor-7095
        end
1531 Thurallor-7095
    elseif (itemName == "Group") then
1532 Thurallor-7095
        self.parent.AddSettingsMenuItem(self.parent, item, "Root", true, self);
1533 Thurallor-7095
    elseif (itemName == "Delete") then
1534 121 Thurallor-7095
        item.Click = function()
1535 2 Thurallor-7095
            self.parent:DeleteBar(self.objectID);
1536 Thurallor-7095
        end
1537 Thurallor-7095
    end
1538 26 Thurallor-7095
    return item;
1539 2 Thurallor-7095
end
1540 Thurallor-7095
 
1541 128 Thurallor-7095
function Bar:SetTransparency(opacity)
1542 Thurallor-7095
    self.settings.opacity = opacity;
1543 Thurallor-7095
    self:SaveSettings();
1544 158 Thurallor-7095
    self:Redraw(true);
1545 128 Thurallor-7095
end
1546 Thurallor-7095
 
1547 158 Thurallor-7095
function Bar:GetTransparency()
1548 Thurallor-7095
    return self.settings.opacity or self.globals.uiOpacity;
1549 Thurallor-7095
end
1550 Thurallor-7095
 
1551 Thurallor-7095
function Bar:SetScale(scale)
1552 Thurallor-7095
    self.settings.scale = scale;
1553 Thurallor-7095
    self:SaveSettings();
1554 Thurallor-7095
    self:Redraw(true);
1555 Thurallor-7095
end
1556 Thurallor-7095
 
1557 Thurallor-7095
function Bar:GetScale()
1558 Thurallor-7095
    return self.settings.scale or self.globals.uiScale;
1559 Thurallor-7095
end
1560 Thurallor-7095
 
1561 2 Thurallor-7095
function Bar:ResizeBar(size)
1562 27 Thurallor-7095
    self:Expand();
1563 2 Thurallor-7095
    self.settings.visibleSlots = size;
1564 Thurallor-7095
    if (self.settings.cursorHomePosition > size) then
1565 Thurallor-7095
        self.settings.cursorHomePosition = size;
1566 Thurallor-7095
    end
1567 Thurallor-7095
    self:SaveSettings(false);
1568 Thurallor-7095
    self:Redraw();
1569 Thurallor-7095
end
1570 Thurallor-7095
 
1571 Thurallor-7095
function Bar:SetCursorStyle(style)
1572 Thurallor-7095
    if (style == nil) then
1573 Thurallor-7095
        style = self.settings.cursorStyle;
1574 Thurallor-7095
    end
1575 Thurallor-7095
    self.settings.cursorStyle = style;
1576 Thurallor-7095
    local resource = resources.Cursor[style];
1577 Thurallor-7095
 
1578 Thurallor-7095
    if (self.cursor) then
1579 13 Thurallor-7095
        self.cursor:SetParent(nil);
1580 2 Thurallor-7095
        self.cursor = nil;
1581 Thurallor-7095
    end
1582 13 Thurallor-7095
    self.cursor = Turbine.UI.Control();
1583 Thurallor-7095
    self.cursor:SetParent(self.slotContainer);
1584 2 Thurallor-7095
    self.cursor:SetMouseVisible(false);
1585 Thurallor-7095
    if (resource.ApplyColor) then
1586 Thurallor-7095
        self.cursor:SetBackColor(self.color);
1587 Thurallor-7095
    end
1588 Thurallor-7095
    local background = resources.Cursor[style].Background;
1589 Thurallor-7095
    if (background) then
1590 Thurallor-7095
        self.cursor:SetBackground(resource.Background);
1591 Thurallor-7095
        self.cursorWidth, self.cursorHeight = GetAssetSize(resource.Background);
1592 Thurallor-7095
        self.cursor:SetSize(self.cursorWidth, self.cursorHeight);
1593 Thurallor-7095
        -- for now, presume square shape
1594 Thurallor-7095
        self.cursorSize = math.ceil(self.cursorWidth / 2) * 2;
1595 Thurallor-7095
    else
1596 Thurallor-7095
        self.cursorSize = 36;
1597 Thurallor-7095
    end
1598 Thurallor-7095
    if (resource.BackColorBlendMode) then
1599 Thurallor-7095
        self.cursor:SetBackColorBlendMode(resource.BackColorBlendMode);
1600 Thurallor-7095
    end
1601 Thurallor-7095
    if (resource.BlendMode) then
1602 Thurallor-7095
        self.cursor:SetBlendMode(resource.BlendMode);
1603 Thurallor-7095
    end
1604 Thurallor-7095
    if (resource.ZOrder) then
1605 13 Thurallor-7095
        self.cursor:SetZOrder(2 + resource.ZOrder);
1606 2 Thurallor-7095
    end
1607 13 Thurallor-7095
--    self.cursor:SetVisible(not self:IsHidden());
1608 2 Thurallor-7095
    if (not resource.xOffset) then
1609 Thurallor-7095
        resource.xOffset = 0;
1610 Thurallor-7095
    end
1611 Thurallor-7095
    if (not resource.yOffset) then
1612 Thurallor-7095
        resource.yOffset = 0;
1613 Thurallor-7095
    end
1614 13 Thurallor-7095
 
1615 Thurallor-7095
    self.cursorMargin = math.ceil((self.cursorSize - self.settings.slotSize) / 2);
1616 16 Thurallor-7095
    self:SetCursorPos(self.cursorPos);
1617 2 Thurallor-7095
end
1618 Thurallor-7095
 
1619 Thurallor-7095
function Bar:SetLocked(state)
1620 Thurallor-7095
    self.settings.locked = state;
1621 Thurallor-7095
    self:SaveSettings(false);
1622 Thurallor-7095
end
1623 Thurallor-7095
 
1624 Thurallor-7095
function Bar:IsLocked()
1625 Thurallor-7095
    return self.settings.locked;
1626 Thurallor-7095
end
1627 Thurallor-7095
 
1628 16 Thurallor-7095
-- Scrolls the sequence such that the specified slot appears under the cursor
1629 Thurallor-7095
function Bar:SetCursorSlot(slot)
1630 20 Thurallor-7095
 
1631 21 Thurallor-7095
    local prevVisibleSlots = self.visibleSlots;
1632 16 Thurallor-7095
    self.visibleSlots = {};
1633 2 Thurallor-7095
 
1634 16 Thurallor-7095
    -- If advanced past the end of the sequence, start over at the beginning.
1635 Thurallor-7095
    if (slot > #self.slots) then
1636 Thurallor-7095
        slot = 1;
1637 2 Thurallor-7095
    end
1638 37 Thurallor-7095
 
1639 16 Thurallor-7095
    -- Find non-hidden slots to the left of the cursor
1640 36 Thurallor-7095
    local gameTime = Turbine.Engine.GetGameTime();
1641 16 Thurallor-7095
    local pos = self.cursorPos - 1;
1642 Thurallor-7095
    local s = slot - 1;
1643 Thurallor-7095
    while ((pos > 0) and (s > 0)) do
1644 Thurallor-7095
        local object = self.slots[s];
1645 36 Thurallor-7095
        if (not (object.hidden or (self.settings.hideInactiveBranches and self.sequence:SlotIsFolded(s, gameTime)))) then
1646 21 Thurallor-7095
            self.visibleSlots[object] = pos;
1647 16 Thurallor-7095
            pos = pos - 1;
1648 2 Thurallor-7095
        end
1649 16 Thurallor-7095
        s = s - 1;
1650 2 Thurallor-7095
    end
1651 16 Thurallor-7095
 
1652 Thurallor-7095
    self.cursorSlot = slot;
1653 Thurallor-7095
 
1654 Thurallor-7095
    -- Find non-hidden slots to the right of the cursor.
1655 Thurallor-7095
    -- Re-evaluate all conditionals except those to the left of the cursor.
1656 Thurallor-7095
    pos = self.cursorPos;
1657 Thurallor-7095
    s = slot;
1658 26 Thurallor-7095
    while ((pos <= self.displaySlots) and (s <= #self.slots)) do
1659 16 Thurallor-7095
        local object = self.slots[s];
1660 Thurallor-7095
        if (object.info.type == "If") then
1661 146 Thurallor-7095
            local success, condResult = pcall(object.condFunc, object, self.manager.player);
1662 Thurallor-7095
            object.condResult = (success and condResult) or false; -- nil => false
1663 16 Thurallor-7095
        end
1664 36 Thurallor-7095
        if (not (object.hidden or (self.settings.hideInactiveBranches and self.sequence:SlotIsFolded(s, gameTime)))) then
1665 21 Thurallor-7095
            self.visibleSlots[object] = pos;
1666 16 Thurallor-7095
            pos = pos + 1;
1667 Thurallor-7095
        end
1668 Thurallor-7095
        s = s + 1;
1669 Thurallor-7095
    end
1670 37 Thurallor-7095
 
1671 43 Thurallor-7095
    -- If no slots displayed, display the "reset" icon or "gears" if running continuously
1672 36 Thurallor-7095
    if (pos == self.cursorPos) then
1673 43 Thurallor-7095
        if (self.settings.continuous) then
1674 Thurallor-7095
            self.visibleSlots[self.gearsSlot] = pos;
1675 Thurallor-7095
        else
1676 Thurallor-7095
            self.visibleSlots[self.resetSlot] = pos;
1677 Thurallor-7095
        end
1678 36 Thurallor-7095
    end
1679 20 Thurallor-7095
 
1680 21 Thurallor-7095
    -- Make the old slots invisible
1681 20 Thurallor-7095
--if (self.settings.caption.text == "AoE Tank") then
1682 21 Thurallor-7095
--    Puts("prevVisibleSlots = " .. PrettyPrint(prevVisibleSlots, "", 1));
1683 20 Thurallor-7095
--end
1684 21 Thurallor-7095
    for object, pos in pairs(prevVisibleSlots) do
1685 Thurallor-7095
        if (not self.visibleSlots[object]) then
1686 Thurallor-7095
            object:SetParent(nil);
1687 Thurallor-7095
            object.pos = nil;
1688 Thurallor-7095
        end
1689 Thurallor-7095
    end
1690 17 Thurallor-7095
 
1691 21 Thurallor-7095
    -- Make the new slots visible
1692 Thurallor-7095
--if (self.settings.caption.text == "AoE Tank") then
1693 Thurallor-7095
--    Puts("self.visibleSlots = " .. PrettyPrint(prevVisibleSlots, "", 1));
1694 Thurallor-7095
--end
1695 Thurallor-7095
    if (not self.settings.hidden) then
1696 Thurallor-7095
        for object, pos in pairs(self.visibleSlots) do
1697 Thurallor-7095
            if (not prevVisibleSlots[object]) then
1698 Thurallor-7095
                object:SetParent(self.slotContainer);
1699 Thurallor-7095
            end
1700 Thurallor-7095
            local left, top = self:GetSlotCoords(pos);
1701 16 Thurallor-7095
            object:SetPosition(left - 1, top  - 1);
1702 21 Thurallor-7095
            object.pos = pos;
1703 16 Thurallor-7095
        end
1704 Thurallor-7095
    end
1705 2 Thurallor-7095
end
1706 Thurallor-7095
 
1707 43 Thurallor-7095
function Bar:StartExecuting()
1708 Thurallor-7095
    self.gearsSlot:SetRunning(true);
1709 Thurallor-7095
end
1710 Thurallor-7095
 
1711 Thurallor-7095
function Bar:StopExecuting()
1712 121 Thurallor-7095
    if (self.Log) then
1713 Thurallor-7095
        DoCallbacks(self, "Log", {"halting continuous execution", "BAR"});
1714 Thurallor-7095
    end
1715 43 Thurallor-7095
    self.gearsSlot:SetRunning(false);
1716 Thurallor-7095
end
1717 Thurallor-7095
 
1718 20 Thurallor-7095
function Bar:SlotClick(s, automatic)
1719 43 Thurallor-7095
 
1720 16 Thurallor-7095
    local slot = self.slots[s];
1721 34 Thurallor-7095
    if (automatic) then
1722 37 Thurallor-7095
        if (self.firstAutomaticClick) then
1723 Thurallor-7095
            if (self.wrapped and (s >= self.firstAutomaticClick)) then
1724 Thurallor-7095
                self.firstAutomaticClick = nil;
1725 43 Thurallor-7095
 
1726 Thurallor-7095
                -- If running continuously, tell the Gears object to perform a click at the next update ("Tick")
1727 Thurallor-7095
                if (self.settings.continuous) then
1728 Thurallor-7095
                    self.gearsSlot.Tick = function()
1729 Thurallor-7095
                        self.gearsSlot.Tick = nil; -- only once
1730 Thurallor-7095
                        local slot = self.slots[self.cursorSlot];
1731 Thurallor-7095
                        if (slot.info.automatic) then
1732 Thurallor-7095
                            self:SlotClick(s, true);
1733 Thurallor-7095
                        end
1734 Thurallor-7095
                    end
1735 Thurallor-7095
                end
1736 37 Thurallor-7095
                return;
1737 Thurallor-7095
            end
1738 Thurallor-7095
        else
1739 34 Thurallor-7095
            self.firstAutomaticClick = s;
1740 37 Thurallor-7095
            self.wrapped = false;
1741 34 Thurallor-7095
        end
1742 Thurallor-7095
    else
1743 Thurallor-7095
        self.firstAutomaticClick = nil;
1744 20 Thurallor-7095
        self.clickedPos = slot.pos;
1745 26 Thurallor-7095
        self.clickedSlot = s;
1746 20 Thurallor-7095
    end
1747 Thurallor-7095
 
1748 17 Thurallor-7095
    -- Do the action associated with the slot, if any
1749 Thurallor-7095
    if (slot.actionFunc) then
1750 121 Thurallor-7095
        if (self.Log) then
1751 Thurallor-7095
            DoCallbacks(self, "Log", {"(slot " .. tostring(s) .. ") executing: " .. slot.info.type, "SPECIAL-SLOT"});
1752 Thurallor-7095
            if (slot.info.type == "GenerateEvent") then
1753 Thurallor-7095
                DoCallbacks(self, "Log", {"generated: " .. slot.info.eventName, "EVENT"});
1754 Thurallor-7095
            end
1755 Thurallor-7095
        end
1756 146 Thurallor-7095
        pcall(slot.actionFunc, slot, s);
1757 17 Thurallor-7095
    end
1758 Thurallor-7095
 
1759 146 Thurallor-7095
    -- Process conditionals (if/then/else) and Lua scripts.
1760 17 Thurallor-7095
    if (slot.info.type == "If") then
1761 146 Thurallor-7095
        local success, condResult = pcall(slot.condFunc, slot, self.manager.player);
1762 Thurallor-7095
        slot.condResult = (success and condResult) or false; -- nil => false
1763 121 Thurallor-7095
        if (self.Log) then
1764 Thurallor-7095
            DoCallbacks(self, "Log", {"(slot " .. tostring(s) .. ") evaluating conditional: " .. tostring(slot.condResult), "SPECIAL-SLOT"});
1765 Thurallor-7095
        end
1766 17 Thurallor-7095
        if (not slot.condResult) then
1767 Thurallor-7095
            if (slot.elseSlot) then
1768 Thurallor-7095
                s = slot.elseSlot - 1;
1769 Thurallor-7095
            elseif (slot.endIfSlot) then
1770 16 Thurallor-7095
                s = slot.endIfSlot - 1;
1771 Thurallor-7095
            end
1772 2 Thurallor-7095
        end
1773 17 Thurallor-7095
    elseif (slot.info.type == "Else") then
1774 Thurallor-7095
        doElse = true;
1775 Thurallor-7095
        if (slot.ifSlot) then
1776 Thurallor-7095
            doElse = not self.slots[slot.ifSlot].condResult;
1777 6 Thurallor-7095
        end
1778 17 Thurallor-7095
        if (slot.endIfSlot and not doElse) then
1779 Thurallor-7095
            s = slot.endIfSlot - 1;
1780 Thurallor-7095
        end
1781 Thurallor-7095
    end
1782 20 Thurallor-7095
 
1783 34 Thurallor-7095
    local nextSlot = s + 1;
1784 Thurallor-7095
 
1785 20 Thurallor-7095
    -- If a previous advancement callback was never called, unregister it.
1786 Thurallor-7095
    self:UnregisterAdvanceCallback();
1787 16 Thurallor-7095
 
1788 20 Thurallor-7095
    if (slot.info.advanceEvent) then
1789 Thurallor-7095
        if (slot.info.advanceEvent == "ItemEquipped") then
1790 143 Thurallor-7095
            if (not IsEquipped(slot:GetItemName())) then
1791 Thurallor-7095
                slot.advanceFunc["ItemEquipped"] = function()
1792 146 Thurallor-7095
                    self:UnregisterAdvanceCallback();
1793 143 Thurallor-7095
--                    if (IsEquipped(slot:GetItemName()) then
1794 146 Thurallor-7095
                        self:AdvanceToSlot(nextSlot, "item equipped");
1795 143 Thurallor-7095
--                    end
1796 Thurallor-7095
                end
1797 Thurallor-7095
                AddCallback(Thurallor.Utils.Watcher, "ItemEquipped", slot.advanceFunc["ItemEquipped"]);
1798 147 Thurallor-7095
                table.insert(self.advancement, { object = Thurallor.Utils.Watcher, event = "ItemEquipped", func = slot.advanceFunc["ItemEquipped"] });
1799 34 Thurallor-7095
            end
1800 Thurallor-7095
        elseif (slot.info.advanceEvent == "DelayComplete") then
1801 143 Thurallor-7095
            slot.advanceFunc["Reset"] = function()
1802 146 Thurallor-7095
                self:UnregisterAdvanceCallback();
1803 Thurallor-7095
                self:AdvanceToSlot(nextSlot, "delay complete");
1804 43 Thurallor-7095
                if (self.settings.continuous) then
1805 Thurallor-7095
                    self.gearsSlot:SetDelaying(false);
1806 Thurallor-7095
                end
1807 20 Thurallor-7095
            end
1808 143 Thurallor-7095
            AddCallback(slot, "Reset", slot.advanceFunc["Reset"]);
1809 147 Thurallor-7095
            table.insert(self.advancement, { object = slot, event = "Reset", func = slot.advanceFunc["Reset"] });
1810 143 Thurallor-7095
        elseif (slot.info.advanceEvent == "SkillExecuted") then
1811 151 Thurallor-7095
            local skillNames = slot:GetSkillNames();
1812 Thurallor-7095
            if (skillNames) then
1813 Thurallor-7095
                local skill = slot:GetSkill();
1814 Thurallor-7095
                if (skill) then
1815 Thurallor-7095
 
1816 Thurallor-7095
                                        -- For most skills, we can use the ResetTimeChanged event to detect execution.
1817 154 Thurallor-7095
                    if (not slot.info.executeDetectByChat) then
1818 151 Thurallor-7095
                        slot.advanceFunc["ResetTimeChanged"] = function()
1819 146 Thurallor-7095
                            self:UnregisterAdvanceCallback();
1820 151 Thurallor-7095
                            self:AdvanceToSlot(nextSlot, "skill executed (cooldown reset detected)");
1821 143 Thurallor-7095
                        end
1822 151 Thurallor-7095
                        AddCallback(skill, "ResetTimeChanged", slot.advanceFunc["ResetTimeChanged"]);
1823 Thurallor-7095
                        table.insert(self.advancement, { object = skill, event = "ResetTimeChanged", func = slot.advanceFunc["ResetTimeChanged"] });
1824 Thurallor-7095
 
1825 Thurallor-7095
                    -- For other skills, we can wait for chat message indicating skill has fired.
1826 154 Thurallor-7095
                    else
1827 151 Thurallor-7095
                        for _, altName in pairs(skillNames) do
1828 Thurallor-7095
                            slot.advanceFunc[altName] = function(_, args)
1829 Thurallor-7095
                                if ((args.ChatType == Turbine.ChatType.PlayerCombat) and (string.find(args.Message, altName, 1, true))) then
1830 Thurallor-7095
                                    self:UnregisterAdvanceCallback();
1831 Thurallor-7095
                                    self:AdvanceToSlot(nextSlot, "skill executed (observed in combat log)");
1832 Thurallor-7095
                                end
1833 Thurallor-7095
                            end
1834 Thurallor-7095
                            AddCallback(Turbine.Chat, "Received", slot.advanceFunc[altName]);
1835 Thurallor-7095
                            table.insert(self.advancement, { object = Turbine.Chat, event = "Received", func = slot.advanceFunc[altName] });
1836 Thurallor-7095
                        end
1837 Thurallor-7095
 
1838 143 Thurallor-7095
                    end
1839 151 Thurallor-7095
                    -- Toggle skills only have a chat message when activated; when deactivated, they get a ResetTimeChanged
1840 Thurallor-7095
                    -- event.  Shouldn't be a problem, since by that time we won't be watching any more.
1841 Thurallor-7095
                else
1842 Thurallor-7095
                    -- The skill is unlearned, so it won't ever execute.
1843 Thurallor-7095
                    table.insert(self.advancement, { object = Turbine.Chat, event = "Never" });
1844 143 Thurallor-7095
                end
1845 151 Thurallor-7095
            else
1846 Thurallor-7095
                Puts("Unknown skill in slot " .. s .. "; don't know how to detect its execution");
1847 143 Thurallor-7095
            end
1848 20 Thurallor-7095
        end
1849 Thurallor-7095
    end
1850 113 Thurallor-7095
 
1851 114 Thurallor-7095
        -- If skill requires a target, don't advance.
1852 136 Thurallor-7095
        if (slot.info.requireTarget) then
1853 Thurallor-7095
        if ((slot.info.type == "SelectTarget") and (slot.entity == nil)) then
1854 146 Thurallor-7095
            if (self.Log) then
1855 Thurallor-7095
                DoCallbacks(self, "Log", {"failed: selection failed", "ADVANCE"});
1856 Thurallor-7095
            end
1857 136 Thurallor-7095
            return;
1858 Thurallor-7095
        elseif (Thurallor.Utils.Watcher.targetObject == nil) then
1859 146 Thurallor-7095
            if (self.Log) then
1860 Thurallor-7095
                DoCallbacks(self, "Log", {"failed: target required", "ADVANCE"});
1861 Thurallor-7095
            end
1862 143 Thurallor-7095
            self:UnregisterAdvanceCallback();
1863 136 Thurallor-7095
            return;
1864 Thurallor-7095
        end
1865 113 Thurallor-7095
        end
1866 34 Thurallor-7095
 
1867 20 Thurallor-7095
    -- Advance immediately.
1868 147 Thurallor-7095
    if (not next(self.advancement)) then
1869 143 Thurallor-7095
        self:AdvanceToSlot(nextSlot);
1870 Thurallor-7095
    end
1871 20 Thurallor-7095
end
1872 Thurallor-7095
 
1873 34 Thurallor-7095
function Bar:StartSlotCooldown(s, delay)
1874 Thurallor-7095
    local slot = self.slots[s];
1875 Thurallor-7095
    slot.hiddenAfterReset = slot.hidden;
1876 43 Thurallor-7095
    if (self.settings.continuous) then
1877 Thurallor-7095
        self.gearsSlot:SetDelaying(true);
1878 Thurallor-7095
    else
1879 Thurallor-7095
        slot.hidden = false;
1880 Thurallor-7095
        self:SetCursorPos(self.clickedPos);
1881 Thurallor-7095
        self:SetCursorSlot(s);
1882 Thurallor-7095
    end
1883 34 Thurallor-7095
    slot:StartCooldown(delay);
1884 Thurallor-7095
end
1885 Thurallor-7095
 
1886 20 Thurallor-7095
function Bar:UnregisterAdvanceCallback()
1887 147 Thurallor-7095
    if (next(self.advancement)) then
1888 143 Thurallor-7095
        for _, info in pairs(self.advancement) do
1889 Thurallor-7095
            RemoveCallback(info.object, info.event, info.func);
1890 Thurallor-7095
        end
1891 147 Thurallor-7095
        self.advancement = {};
1892 20 Thurallor-7095
    end
1893 Thurallor-7095
end
1894 Thurallor-7095
 
1895 146 Thurallor-7095
function Bar:AdvanceToSlot(s, cause)
1896 20 Thurallor-7095
 
1897 17 Thurallor-7095
    if (s > #self.slots) then
1898 37 Thurallor-7095
        self.wrapped = true;
1899 17 Thurallor-7095
        s = 1;
1900 Thurallor-7095
    end
1901 34 Thurallor-7095
    local slot = self.slots[s];
1902 Thurallor-7095
 
1903 121 Thurallor-7095
    if (self.Log) then
1904 146 Thurallor-7095
        if (cause) then
1905 Thurallor-7095
            DoCallbacks(self, "Log", {"to slot " .. tostring(s) .. ", caused by: " .. cause, "ADVANCE"});
1906 Thurallor-7095
        else
1907 Thurallor-7095
            DoCallbacks(self, "Log", {"to slot " .. tostring(s), "ADVANCE"});
1908 Thurallor-7095
        end
1909 121 Thurallor-7095
    end
1910 Thurallor-7095
 
1911 38 Thurallor-7095
    -- If the user didn't click on the currently selected slot, move the cursor.
1912 34 Thurallor-7095
    if (self.clickedPos ~= self.cursorPos) then
1913 Thurallor-7095
        self:SetCursorPos(self.clickedPos);
1914 Thurallor-7095
    end
1915 Thurallor-7095
 
1916 38 Thurallor-7095
    -- If the next slot is automatic, auto-click it.
1917 34 Thurallor-7095
    if (slot.info.automatic) then
1918 Thurallor-7095
        self:SetCursorSlot(s);
1919 25 Thurallor-7095
        return self:SlotClick(s, true);
1920 17 Thurallor-7095
    end
1921 16 Thurallor-7095
 
1922 38 Thurallor-7095
    -- If animation is disabled via settings, or stopped via a "Stop" slot, refold the slots and do nothing further.
1923 16 Thurallor-7095
    if ((self.settings.animation.duration == -1) or self.animationStopped) then
1924 26 Thurallor-7095
        self:SetCursorSlot(self.clickedSlot);
1925 16 Thurallor-7095
        return;
1926 2 Thurallor-7095
    end
1927 16 Thurallor-7095
 
1928 Thurallor-7095
    -- Do animation.
1929 34 Thurallor-7095
    self:SetCursorSlot(s);
1930 16 Thurallor-7095
    if (self.settings.animation.duration > 0) then
1931 Thurallor-7095
        self:Animate(0);
1932 Thurallor-7095
    end
1933 2 Thurallor-7095
end
1934 Thurallor-7095
 
1935 Thurallor-7095
function Bar:Update()
1936 17 Thurallor-7095
    if (self.animationStartTime) then
1937 Thurallor-7095
        local timeDelta = Turbine.Engine.GetGameTime() - self.animationStartTime;
1938 Thurallor-7095
        if (timeDelta > 0) then
1939 Thurallor-7095
            self:Animate(timeDelta);
1940 Thurallor-7095
        end
1941 2 Thurallor-7095
    end
1942 24 Thurallor-7095
--    if (self.delayedClick) then
1943 Thurallor-7095
--        self:SlotClick(self.delayedClick, true);
1944 Thurallor-7095
--    end
1945 20 Thurallor-7095
    if (self.mouseInside) then
1946 Thurallor-7095
        local mouseLeft, mouseTop = Turbine.UI.Display:GetMousePosition();
1947 42 Thurallor-7095
        if (not self:MouseInside(mouseLeft, mouseTop)) then
1948 20 Thurallor-7095
            self:MouseDepart();
1949 Thurallor-7095
        end
1950 Thurallor-7095
    end
1951 24 Thurallor-7095
    if ((not self.animationStartTime) and (not self.mouseInside)) then
1952 Thurallor-7095
-- and (not self.delayedClick)
1953 17 Thurallor-7095
        self:SetWantsUpdates(false);
1954 Thurallor-7095
    end
1955 2 Thurallor-7095
end
1956 Thurallor-7095
 
1957 Thurallor-7095
function Bar:SetAnimationSpeed(duration)
1958 Thurallor-7095
    self.settings.animation.duration = duration;
1959 Thurallor-7095
    self:SaveSettings(false);
1960 Thurallor-7095
end
1961 Thurallor-7095
 
1962 Thurallor-7095
-- Achieves the scrolling effect.  Gets called by Bar:Update().
1963 Thurallor-7095
function Bar:Animate(timeDelta)
1964 Thurallor-7095
    local progress = timeDelta / self.settings.animation.duration;
1965 Thurallor-7095
    if (progress == 0) then
1966 Thurallor-7095
        self.animationStartTime = Turbine.Engine.GetGameTime();
1967 Thurallor-7095
        self.animationDistance = self.settings.slotSize + self.settings.slotSpacing;
1968 Thurallor-7095
        self:SetWantsUpdates(true);
1969 20 Thurallor-7095
    elseif (progress >= 1) then
1970 2 Thurallor-7095
        progress = 1;
1971 20 Thurallor-7095
        self.animationStartTime = nil;
1972 2 Thurallor-7095
    end
1973 Thurallor-7095
    local displacement = math.floor(self.animationDistance * (1 - progress));
1974 Thurallor-7095
    if (self.settings.orientation == "Up") then
1975 13 Thurallor-7095
        self.slotContainer:SetTop(self.slotsTop - displacement);
1976 2 Thurallor-7095
    elseif (self.settings.orientation == "Down") then
1977 13 Thurallor-7095
        self.slotContainer:SetTop(self.slotsTop + displacement);
1978 2 Thurallor-7095
    elseif (self.settings.orientation == "Left") then
1979 13 Thurallor-7095
        self.slotContainer:SetLeft(self.slotsLeft - displacement);
1980 2 Thurallor-7095
    elseif (self.settings.orientation == "Right") then
1981 13 Thurallor-7095
        self.slotContainer:SetLeft(self.slotsLeft + displacement);
1982 2 Thurallor-7095
    end
1983 6 Thurallor-7095
 
1984 Thurallor-7095
    -- Make sure the item under the cursor is always clickable.  This hack is
1985 Thurallor-7095
    -- necessary because as the slot moves, no MouseEnter event occurs and
1986 Thurallor-7095
    -- hence no MouseClick events can be received.
1987 16 Thurallor-7095
    self.slots[self.cursorSlot]:SetVisible(false);
1988 Thurallor-7095
    self.slots[self.cursorSlot]:SetVisible(true);
1989 2 Thurallor-7095
end
1990 Thurallor-7095
 
1991 Thurallor-7095
function Bar:Destroy()
1992 13 Thurallor-7095
    if (self.sequenceEditor) then
1993 Thurallor-7095
        self.sequenceEditor:Close();
1994 Thurallor-7095
    end
1995 8 Thurallor-7095
    -- Unregister as event generator
1996 177 Thurallor-7095
    self.manager:SetEventGenerators(false, self);
1997 8 Thurallor-7095
    Node.Destroy(self);
1998 16 Thurallor-7095
    self.manager:SetIncludees(self.objectID, nil);
1999 2 Thurallor-7095
end
2000 Thurallor-7095
 
2001 Thurallor-7095
function Bar:GetVisibleLeft()
2002 13 Thurallor-7095
    local left = self:GetSlotsScreenCoords();
2003 2 Thurallor-7095
    return left;
2004 Thurallor-7095
end
2005 Thurallor-7095
 
2006 Thurallor-7095
function Bar:SetVisibleLeft(left)
2007 Thurallor-7095
    self:OffsetPosition(left - self:GetVisibleLeft(), 0);
2008 Thurallor-7095
end
2009 Thurallor-7095
 
2010 Thurallor-7095
function Bar:GetVisibleTop()
2011 13 Thurallor-7095
    local _, top = self:GetSlotsScreenCoords();
2012 2 Thurallor-7095
    return top;
2013 Thurallor-7095
end
2014 Thurallor-7095
 
2015 Thurallor-7095
function Bar:SetVisibleTop(top)
2016 Thurallor-7095
    self:OffsetPosition(0, top - self:GetVisibleTop());
2017 Thurallor-7095
end
2018 Thurallor-7095
 
2019 Thurallor-7095
function Bar:GetVisibleWidth()
2020 13 Thurallor-7095
    local _, _, width = self:GetSlotsScreenCoords();
2021 2 Thurallor-7095
    return width;
2022 Thurallor-7095
end
2023 Thurallor-7095
 
2024 Thurallor-7095
function Bar:GetVisibleHeight()
2025 13 Thurallor-7095
    local _, _, _, height = self:GetSlotsScreenCoords();
2026 2 Thurallor-7095
    return height;
2027 Thurallor-7095
end
2028 Thurallor-7095
 
2029 Thurallor-7095
function Bar:GetSlotCoords(slot)
2030 Thurallor-7095
    local slotSize = self.settings.slotSize + self.settings.slotSpacing;
2031 Thurallor-7095
    local offset = self.cursorMargin + (slot - 1) * slotSize;
2032 Thurallor-7095
    local left, top;
2033 Thurallor-7095
    if (self.settings.orientation == "Up") then
2034 Thurallor-7095
        left = self.cursorMargin;
2035 13 Thurallor-7095
        top = self.slotContainer:GetHeight() - slotSize - offset;
2036 2 Thurallor-7095
    elseif (self.settings.orientation == "Down") then
2037 Thurallor-7095
        left = self.cursorMargin;
2038 Thurallor-7095
        top = offset;
2039 Thurallor-7095
    elseif (self.settings.orientation == "Left") then
2040 13 Thurallor-7095
        left = self.slotContainer:GetWidth() - slotSize - offset;
2041 2 Thurallor-7095
        top = self.cursorMargin;
2042 Thurallor-7095
    else -- "Right"
2043 Thurallor-7095
        left = offset;
2044 Thurallor-7095
        top = self.cursorMargin;
2045 Thurallor-7095
    end
2046 Thurallor-7095
    return left, top
2047 Thurallor-7095
end
2048 Thurallor-7095
 
2049 Thurallor-7095
function Bar:Find()
2050 Thurallor-7095
    self:MoveOntoScreen();
2051 32 Thurallor-7095
    Turbine.UI.Window.Activate(self);
2052 2 Thurallor-7095
    self:Flash();
2053 Thurallor-7095
end
2054 Thurallor-7095
 
2055 Thurallor-7095
function Bar:MoveOntoScreen()
2056 Thurallor-7095
    local screenWidth, screenHeight = Turbine.UI.Display:GetWidth(), Turbine.UI.Display:GetHeight();
2057 13 Thurallor-7095
    local left, top = self:PointToScreen(self.caption:GetLeft(), self.caption:GetTop());
2058 2 Thurallor-7095
    local right, bottom = left + self.caption:GetWidth(), top + self.caption:GetHeight();
2059 Thurallor-7095
    local deltaX, deltaY = 0, 0;
2060 Thurallor-7095
    if (left < 0) then
2061 Thurallor-7095
        deltaX = -left;
2062 Thurallor-7095
    elseif (right > screenWidth) then
2063 Thurallor-7095
        deltaX = screenWidth - right;
2064 Thurallor-7095
    end
2065 Thurallor-7095
    if (top < 0) then
2066 Thurallor-7095
        deltaY = -top;
2067 Thurallor-7095
    elseif (bottom > screenHeight) then
2068 Thurallor-7095
        deltaY = screenHeight - bottom;
2069 Thurallor-7095
    end
2070 Thurallor-7095
    self:OffsetPosition(deltaX, deltaY);
2071 Thurallor-7095
    self:SnapToGrid();
2072 Thurallor-7095
end
2073 Thurallor-7095
 
2074 Thurallor-7095
function Bar:Flash()
2075 13 Thurallor-7095
    self:Activate();
2076 2 Thurallor-7095
    self.caption.startTime = Turbine.Engine.GetGameTime();
2077 Thurallor-7095
    self.caption.label:SetVisible(true);
2078 13 Thurallor-7095
    if (not self.marquee) then
2079 Thurallor-7095
        self.marquee = Thurallor.UI.Marquee();
2080 Thurallor-7095
        self.marquee:SetParent(self);
2081 Thurallor-7095
        self.marquee:SetSize(self:GetSize());
2082 Thurallor-7095
    end
2083 2 Thurallor-7095
    self.caption.Update = function(caption, args)
2084 Thurallor-7095
        local timeDelta = Turbine.Engine.GetGameTime() - caption.startTime;
2085 Thurallor-7095
        if (timeDelta > 3) then
2086 Thurallor-7095
            caption.label:SetForeColor(self.color);
2087 112 Thurallor-7095
            caption.label:SetVisible((not self.settings.caption.clickThru) and (self.settings.caption.visible ~= "Never"));
2088 2 Thurallor-7095
            caption:SetWantsUpdates(false);
2089 13 Thurallor-7095
            self.marquee:SetParent(nil);
2090 Thurallor-7095
            self.marquee = nil;
2091 2 Thurallor-7095
        else
2092 Thurallor-7095
            local progress = (math.sin(timeDelta * 15) + 1) / 2; --math.modf(timeDelta / 0.3);
2093 Thurallor-7095
            caption.label:SetForeColor(Turbine.UI.Color(progress, 1, 1, 0));
2094 Thurallor-7095
        end
2095 Thurallor-7095
    end
2096 Thurallor-7095
    self.caption:SetWantsUpdates(true);
2097 177 Thurallor-7095
end
2098 Thurallor-7095
 
2099 Thurallor-7095
function Bar:RenameUserEvent(oldName, newName)
2100 Thurallor-7095
 
2101 Thurallor-7095
    -- Update event behaviors
2102 Thurallor-7095
    Node.RenameUserEvent(self, oldName, newName);
2103 Thurallor-7095
 
2104 Thurallor-7095
    -- Update "Generate User Event" slots
2105 Thurallor-7095
    if (self.events[oldName]) then
2106 Thurallor-7095
 
2107 Thurallor-7095
        for s, info in ipairs(self.settings.sequenceItemInfo) do
2108 Thurallor-7095
            if ((info.type == "GenerateEvent") and (info.eventName == oldName)) then
2109 Thurallor-7095
                info.eventName = newName;
2110 Thurallor-7095
            end
2111 Thurallor-7095
        end
2112 Thurallor-7095
    end
2113 Thurallor-7095
 
2114 Thurallor-7095
    -- Update sequence editor, if such a slot is currently being edited
2115 Thurallor-7095
    if (self.sequenceEditor) then
2116 Thurallor-7095
        self.sequenceEditor:Redraw();
2117 Thurallor-7095
    end
2118 Thurallor-7095
 
2119 Thurallor-7095
    -- Redraw
2120 Thurallor-7095
    self:GetQuickSlots();
2121 Thurallor-7095
    self:FindHiddenSlots();
2122 Thurallor-7095
    self:Reset();
2123 Thurallor-7095
end

All times are GMT -5. The time now is 03:50 PM.


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