lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [SequenceBars/] [SequenceEditor.lua] - Blame information for rev 147

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

Line No. Rev Author Line
1 2 Thurallor-7095
SequenceEditor = class(Turbine.UI.Lotro.Window);
2 Thurallor-7095
 
3 7 Thurallor-7095
-- Class variable keeping track of all SequenceEditor instances:
4 Thurallor-7095
SequenceEditor.instances = {};
5 Thurallor-7095
 
6 2 Thurallor-7095
function SequenceEditor:Constructor(bar, settings)
7 Thurallor-7095
    Turbine.UI.Lotro.Window.Constructor(self);
8 7 Thurallor-7095
    SequenceEditor.instances[self] = true;
9 2 Thurallor-7095
 
10 Thurallor-7095
    self.bar = bar;
11 Thurallor-7095
    self.manager = self.bar.manager;
12 Thurallor-7095
    self.settings = settings;
13 20 Thurallor-7095
    self.globals = self.manager.settings;
14 2 Thurallor-7095
 
15 Thurallor-7095
    self:SetText(bar:GetName());
16 13 Thurallor-7095
    self:SetZOrder(2);
17 2 Thurallor-7095
    self:SetVisible(true);
18 Thurallor-7095
 
19 33 Thurallor-7095
    local minWidth = L:GetText("/SequenceEditor/MinWidth");
20 2 Thurallor-7095
    if (not self.settings.sequenceEditor) then
21 Thurallor-7095
        self.settings.sequenceEditor = {};
22 7 Thurallor-7095
        self.settings.sequenceEditor.defaultIcon = resources.BlankIcons[3];
23 2 Thurallor-7095
    end
24 Thurallor-7095
    if (self.settings.sequenceEditor.position) then
25 Thurallor-7095
        self:SetPosition(unpack(self.settings.sequenceEditor.position));
26 Thurallor-7095
    else
27 Thurallor-7095
        self:SetPosition(self.bar:GetPosition());
28 Thurallor-7095
    end
29 Thurallor-7095
    if (self.settings.sequenceEditor.size) then
30 Thurallor-7095
        self:SetSize(unpack(self.settings.sequenceEditor.size));
31 Thurallor-7095
    else
32 33 Thurallor-7095
        self:SetSize(minWidth, 187);
33 2 Thurallor-7095
    end
34 13 Thurallor-7095
 
35 16 Thurallor-7095
    self.relatedSlots = {};
36 Thurallor-7095
 
37 13 Thurallor-7095
    -- Enforce minimum size
38 33 Thurallor-7095
    self:SetMinimumWidth(minWidth);
39 Thurallor-7095
    if (self:GetWidth() < minWidth) then
40 Thurallor-7095
        self:SetWidth(minWidth);
41 Thurallor-7095
    end
42 13 Thurallor-7095
    self:SetMinimumHeight(142);
43 Thurallor-7095
    self:SetResizable(true);
44 Thurallor-7095
 
45 2 Thurallor-7095
    self:Redraw();
46 18 Thurallor-7095
    AddCallback(self, "SizeChanged", function()
47 47 Thurallor-7095
        self.skipUpdates = 2;
48 Thurallor-7095
        self:SetWantsUpdates(true); --redraw during update cycle
49 18 Thurallor-7095
    end);
50 20 Thurallor-7095
 
51 Thurallor-7095
    self:SelectSlot(nil);
52 2 Thurallor-7095
end
53 Thurallor-7095
 
54 16 Thurallor-7095
function SequenceEditor:UpdateBar()
55 Thurallor-7095
    self.bar:ShortcutChanged();
56 Thurallor-7095
    self.manager:NotifyIncluders(self.bar:GetID());
57 Thurallor-7095
end
58 Thurallor-7095
 
59 7 Thurallor-7095
function SequenceEditor:Activated()
60 Thurallor-7095
    -- Find the maximum Z order among all other Sequence Editors.
61 Thurallor-7095
    local maxZ = self:GetZOrder() - 1;
62 Thurallor-7095
    for editor in keys(SequenceEditor.instances) do
63 Thurallor-7095
        if (editor ~= self) then
64 Thurallor-7095
            local z = editor:GetZOrder();
65 Thurallor-7095
            if (z > maxZ) then
66 Thurallor-7095
                maxZ = z;
67 Thurallor-7095
            end
68 Thurallor-7095
        end
69 Thurallor-7095
    end
70 Thurallor-7095
 
71 Thurallor-7095
    if (maxZ == 2147483647) then
72 Thurallor-7095
        -- Move all other SequenceEditors back to make room at the front.
73 Thurallor-7095
        for editor in keys(SequenceEditor.instances) do
74 Thurallor-7095
            editor:SetZOrder(editor:GetZOrder() - 1);
75 Thurallor-7095
        end
76 Thurallor-7095
        maxZ = maxZ - 1;
77 Thurallor-7095
    end
78 Thurallor-7095
 
79 Thurallor-7095
    -- Move the newly-activated Sequence Editor to the front of the stack.
80 Thurallor-7095
    self:SetZOrder(maxZ + 1);
81 Thurallor-7095
end
82 Thurallor-7095
 
83 2 Thurallor-7095
function SequenceEditor:SetText(barName)
84 Thurallor-7095
    local title = L:GetText("/SequenceEditor/Title");
85 Thurallor-7095
    title = string.gsub(title, "<name>", barName);
86 Thurallor-7095
    Turbine.UI.Lotro.Window.SetText(self, title);
87 Thurallor-7095
end
88 Thurallor-7095
 
89 Thurallor-7095
function SequenceEditor:SaveSettings()
90 Thurallor-7095
    self.bar:SaveSettings();
91 Thurallor-7095
end
92 Thurallor-7095
 
93 Thurallor-7095
function SequenceEditor:Redraw()
94 46 Thurallor-7095
    if (self.noRedraw) then
95 Thurallor-7095
        return;
96 Thurallor-7095
    end
97 2 Thurallor-7095
    local width, height = self:GetSize();
98 Thurallor-7095
    local xMargin = 16;
99 Thurallor-7095
    local topMargin = 35;
100 Thurallor-7095
    local bottomMargin = 42;
101 47 Thurallor-7095
    local minSlotTabCardWidth = L:GetNumber("/SequenceEditor/SlotTabCardWidth");
102 Thurallor-7095
 
103 2 Thurallor-7095
    if (not self.slotTabCard) then
104 Thurallor-7095
        self.slotTabCard = Thurallor.UI.TabCard();
105 Thurallor-7095
        self.slotTabCard:SetParent(self);
106 35 Thurallor-7095
        self.slotTabCard:SetTabWidth(L:GetNumber("/SequenceEditor/SlotTabWidth"));
107 2 Thurallor-7095
        self.slotTabCard:SetTabText(L:GetText("/SequenceEditor/SlotTab"));
108 20 Thurallor-7095
 
109 Thurallor-7095
        -- When mouse reenters the area, redisplay the current slot in case options have changed.
110 Thurallor-7095
        self.slotTabCard.MouseEnter = function(ctl)
111 Thurallor-7095
            if (not ctl.mouseInside) then
112 Thurallor-7095
                ctl.mouseInside = true;
113 Thurallor-7095
                self:DisplaySlot(self.selectedSlot);
114 Thurallor-7095
            end
115 Thurallor-7095
        end
116 Thurallor-7095
        self.MouseEnter = function()
117 Thurallor-7095
            if (self.slotTabCard.mouseInside) then
118 Thurallor-7095
                local left, top = self.slotTabCard:GetMousePosition();
119 Thurallor-7095
                local width, height = self.slotTabCard:GetSize();
120 Thurallor-7095
                if ((left < 0) or (left >= width) or (top < 0) or (top >= height)) then
121 Thurallor-7095
                    self.slotTabCard.mouseInside = false;
122 Thurallor-7095
                end
123 Thurallor-7095
            end
124 Thurallor-7095
        end
125 47 Thurallor-7095
 
126 Thurallor-7095
        -- When slot properties card size changes, redisplay the current slot
127 Thurallor-7095
        self.slotTabCard.SizeChanged = function()
128 Thurallor-7095
            self:DisplaySlot(self.selectedSlot);
129 Thurallor-7095
        end
130 2 Thurallor-7095
    end
131 Thurallor-7095
 
132 Thurallor-7095
    if (not self.sequenceTabCard) then
133 Thurallor-7095
        self.sequenceTabCard = Thurallor.UI.TabCard();
134 Thurallor-7095
        self.sequenceTabCard:SetTabWidth(120);
135 Thurallor-7095
        self.sequenceTabCard:SetTabText(L:GetText("/SequenceEditor/SequenceTab"));
136 13 Thurallor-7095
        self.slotPanel = Turbine.UI.Control();
137 Thurallor-7095
        self.sequenceTabCard:SetInteriorControl(self.slotPanel);
138 Thurallor-7095
        self.sequenceTabCard:SetInteriorAlignment(Turbine.UI.ContentAlignment.TopLeft);
139 47 Thurallor-7095
 
140 Thurallor-7095
        -- When sequence card size changes, update the slot grid layout
141 Thurallor-7095
        self.sequenceTabCard.SizeChanged = function()
142 Thurallor-7095
            self:DeleteEmptyTrailingSlots();
143 Thurallor-7095
            local slotPanelWidth = self.sequenceTabCard:GetWidth() - 6;
144 Thurallor-7095
            self.slotSize = self.settings.slotSize + self.settings.slotSpacing;
145 Thurallor-7095
            self.slotsWide = math.floor((slotPanelWidth - 3) / self.slotSize);
146 Thurallor-7095
            self.slotsHigh = math.max(math.ceil(#self.settings.sequenceItemInfo / self.slotsWide) + 1, 2);
147 Thurallor-7095
            self:ExtendSequenceTo(self.slotsHigh * self.slotsWide);
148 Thurallor-7095
            self.slotPanel:SetSize(self.slotsWide * self.slotSize + 3, self.slotsHigh * self.slotSize + 3);
149 Thurallor-7095
            self.slotPanel:SetBackColor(self.bar.color);
150 Thurallor-7095
 
151 Thurallor-7095
            -- Draw some quickslots
152 Thurallor-7095
            if (not self.sequenceItems) then
153 Thurallor-7095
                self.sequenceItems = {};
154 Thurallor-7095
            end
155 Thurallor-7095
            local s = 1;
156 Thurallor-7095
            for y = 1, self.slotsHigh, 1 do
157 Thurallor-7095
                for x = 1, self.slotsWide, 1 do
158 Thurallor-7095
                    self:RebuildSlot(s, x, y);
159 Thurallor-7095
                    s = s + 1;
160 Thurallor-7095
                end
161 Thurallor-7095
            end
162 Thurallor-7095
        end
163 Thurallor-7095
 
164 2 Thurallor-7095
    end
165 Thurallor-7095
 
166 47 Thurallor-7095
    if (not self.splitControl) then
167 Thurallor-7095
        self.splitControl = Thurallor.UI.SplitControl(Turbine.UI.Orientation.Horizontal, self.sequenceTabCard, self.slotTabCard);
168 Thurallor-7095
        self.splitControl:SetParent(self);
169 Thurallor-7095
        self.splitControl:SetPosition(xMargin, topMargin);
170 Thurallor-7095
        self.splitControl:SetSashSize(5);
171 Thurallor-7095
        self.splitControl:SetSpacing(3);
172 Thurallor-7095
        if (self.settings.sequenceEditor.sashPosition == nil) then
173 Thurallor-7095
            self.splitControl:SetSashPosition(1);
174 Thurallor-7095
            self.settings.sequenceEditor.sashPosition = self.splitControl:GetSashPosition();
175 Thurallor-7095
        else
176 Thurallor-7095
            self.splitControl:SetSashPosition(self.settings.sequenceEditor.sashPosition);
177 2 Thurallor-7095
        end
178 48 Thurallor-7095
        AddCallback(self.splitControl, "SashPositionChanged", function()
179 47 Thurallor-7095
            self.settings.sequenceEditor.sashPosition = self.splitControl:GetSashPosition();
180 Thurallor-7095
            self:SaveSettings();
181 48 Thurallor-7095
        end);
182 2 Thurallor-7095
    end
183 47 Thurallor-7095
    local splitControlWidth = width - (2 * xMargin);
184 Thurallor-7095
    self.splitControl:SetSize(splitControlWidth, height - (topMargin + bottomMargin));
185 Thurallor-7095
    self.sequenceTabCard:SizeChanged();
186 Thurallor-7095
 
187 Thurallor-7095
    -- Enforce minimum width for slot properties card
188 Thurallor-7095
    self.splitControl:SetMaximumSashPosition((splitControlWidth - minSlotTabCardWidth - 5.5) / splitControlWidth);
189 Thurallor-7095
    -- Enforce minimum width for sequence card
190 Thurallor-7095
    self.splitControl:SetMinimumSashPosition(124 / splitControlWidth);
191 Thurallor-7095
 
192 2 Thurallor-7095
    if (not self.instructions) then
193 Thurallor-7095
        self.instructions = Turbine.UI.Label();
194 Thurallor-7095
        self.instructions:SetParent(self);
195 Thurallor-7095
        self.instructions:SetMouseVisible(false);
196 Thurallor-7095
        self.instructions:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
197 Thurallor-7095
        self.instructions:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
198 Thurallor-7095
        self.instructions:SetMultiline(true);
199 Thurallor-7095
        self.instructions:SetForeColor(Turbine.UI.Color.PaleGoldenrod);
200 Thurallor-7095
        self.instructions:SetText(L:GetText("/SequenceEditor/Instructions"));
201 Thurallor-7095
    end
202 Thurallor-7095
    self.instructions:SetSize(self:GetWidth() - 2 * xMargin, 30);
203 Thurallor-7095
    self.instructions:SetPosition(xMargin, self:GetHeight() - 40);
204 13 Thurallor-7095
 
205 Thurallor-7095
    if (self.selectedSlot) then
206 Thurallor-7095
        self:SelectSlot(self.selectedSlot);
207 2 Thurallor-7095
    end
208 Thurallor-7095
end
209 Thurallor-7095
 
210 15 Thurallor-7095
function SequenceEditor:SetMinimumHeight(height)
211 Thurallor-7095
    Turbine.UI.Window.SetMinimumHeight(self, height);
212 Thurallor-7095
    if (self:GetHeight() < height) then
213 Thurallor-7095
        self:SetHeight(height);
214 47 Thurallor-7095
        self.skipUpdates = 0;
215 Thurallor-7095
        self:SetWantsUpdates(true);
216 15 Thurallor-7095
    end
217 Thurallor-7095
end
218 Thurallor-7095
 
219 47 Thurallor-7095
function SequenceEditor:Update()
220 Thurallor-7095
    if (self.skipUpdates > 0) then
221 Thurallor-7095
        self.skipUpdates = self.skipUpdates - 1;
222 Thurallor-7095
    else
223 Thurallor-7095
        self:Redraw();
224 Thurallor-7095
        self.settings.sequenceEditor.size = {self:GetSize()};
225 Thurallor-7095
        self:SaveSettings();
226 Thurallor-7095
        self:SetWantsUpdates(false);
227 Thurallor-7095
    end
228 2 Thurallor-7095
end
229 Thurallor-7095
 
230 Thurallor-7095
function SequenceEditor:PositionChanged()
231 Thurallor-7095
    self.settings.sequenceEditor.position = {self:GetPosition()};
232 Thurallor-7095
    self:SaveSettings();
233 Thurallor-7095
end
234 Thurallor-7095
 
235 Thurallor-7095
function SequenceEditor:DisplaySlot(s)
236 20 Thurallor-7095
    if (self.ItemMovedCallback) then
237 Thurallor-7095
        RemoveCallback(Thurallor.Utils.Watcher, "ItemMoved", self.ItemMovedCallback);
238 Thurallor-7095
        self.ItemMovedCallback = nil;
239 Thurallor-7095
    end
240 Thurallor-7095
 
241 2 Thurallor-7095
    self.slotTabCard:SetInteriorControl(nil);
242 Thurallor-7095
    self.slotTabCard:SetTabText(L:GetText("/SequenceEditor/SlotTab"));
243 7 Thurallor-7095
    if ((s == nil) or (s > #self.settings.sequenceItemInfo)) then
244 Thurallor-7095
        self.slotTabCard:SetVisible(false);
245 2 Thurallor-7095
        return;
246 7 Thurallor-7095
    else
247 Thurallor-7095
        self.slotTabCard:SetVisible(true);
248 2 Thurallor-7095
    end
249 Thurallor-7095
    self:ExtendSequenceTo(s);
250 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
251 47 Thurallor-7095
    local slotTabCardWidth = self.slotTabCard:GetWidth();
252 2 Thurallor-7095
 
253 Thurallor-7095
    -- Update slot tab caption and create properties container
254 Thurallor-7095
    self.slotTabCard:SetTabText(L:GetText("/SequenceEditor/SlotTab") .. " " .. tostring(s));
255 Thurallor-7095
    self.slotProperties = Turbine.UI.Control();
256 Thurallor-7095
    self.slotTabCard:SetInteriorControl(self.slotProperties);
257 47 Thurallor-7095
    self.slotProperties:SetWidth(slotTabCardWidth - 17);
258 13 Thurallor-7095
 
259 7 Thurallor-7095
    local function UpdateIcon()
260 35 Thurallor-7095
        local center = math.floor((slotTabCardWidth - 20) / 2);
261 34 Thurallor-7095
        self.selectedIcon = self:BuildSlot(s, self.slotProperties, self.selectedIcon, center - 16, 10);
262 13 Thurallor-7095
        self.selectedIcon.numLabel:SetText(nil);     -- don't display slot number overlay
263 Thurallor-7095
        self.selectedIcon.numLabel.MouseClick = nil; -- disable right-click menu
264 Thurallor-7095
        self.selectedIcon.numLabel.MouseDown = nil;  -- disable dragging
265 15 Thurallor-7095
        self.selectedIcon:SetActionEnabled(true);
266 Thurallor-7095
        self.selectedIcon:SetAllowDrop(true);
267 7 Thurallor-7095
        self:RebuildSlot(s, nil, nil, true);
268 Thurallor-7095
    end
269 Thurallor-7095
    UpdateIcon();
270 2 Thurallor-7095
 
271 Thurallor-7095
    -- Create a function for adding a centered line of text to the properties control
272 Thurallor-7095
    local AddLabel = function(top, text, color)
273 Thurallor-7095
        local label = Turbine.UI.Label();
274 Thurallor-7095
        label:SetParent(self.slotProperties);
275 Thurallor-7095
        label:SetPosition(0, top);
276 35 Thurallor-7095
        label:SetSize(slotTabCardWidth - 20, 16);
277 2 Thurallor-7095
        top = top + 16;
278 Thurallor-7095
        label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
279 Thurallor-7095
        label:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
280 Thurallor-7095
        label:SetForeColor(color);
281 Thurallor-7095
        label:SetMarkupEnabled(true);
282 Thurallor-7095
        label:SetText(text);
283 Thurallor-7095
        return top, label;
284 Thurallor-7095
    end
285 20 Thurallor-7095
 
286 Thurallor-7095
    -- Create a function for adding a centered button to the properties control
287 47 Thurallor-7095
    local AddButton = function(top, width, text, font)
288 20 Thurallor-7095
        local button = Turbine.UI.Lotro.Button();
289 Thurallor-7095
        button:SetParent(self.slotProperties);
290 Thurallor-7095
        local left = math.floor((self.slotProperties:GetWidth() - width) / 2);
291 Thurallor-7095
        button:SetPosition(left, top + 2);
292 Thurallor-7095
        button:SetWidth(width);
293 47 Thurallor-7095
        if (font == nil) then
294 Thurallor-7095
            font = Turbine.UI.Lotro.Font.TrajanPro14;
295 Thurallor-7095
        end
296 Thurallor-7095
        button:SetFont(font);
297 20 Thurallor-7095
        button:SetText(text);
298 Thurallor-7095
        top = top + 2 + button:GetHeight();
299 Thurallor-7095
        return top, button;
300 Thurallor-7095
    end
301 Thurallor-7095
 
302 2 Thurallor-7095
    -- Create a function for adding a centered text box to the properties control
303 47 Thurallor-7095
    local AddTextBox = function(top, text, color, resizable, textBoxSize)
304 2 Thurallor-7095
        local textBox = Turbine.UI.Lotro.TextBox();
305 Thurallor-7095
        textBox:SetParent(self.slotProperties);
306 Thurallor-7095
        textBox:SetPosition(0, top);
307 35 Thurallor-7095
        textBox:SetSize(slotTabCardWidth - 20, 20);
308 47 Thurallor-7095
        if (textBoxSize) then
309 Thurallor-7095
            textBox:SetHeight(textBoxSize[2]);
310 Thurallor-7095
        end
311 Thurallor-7095
        top = top + textBox:GetHeight();
312 2 Thurallor-7095
        textBox:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
313 7 Thurallor-7095
        textBox:SetMultiline(false);
314 2 Thurallor-7095
        textBox:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
315 Thurallor-7095
        textBox:SetForeColor(color);
316 Thurallor-7095
        textBox:SetText(text);
317 47 Thurallor-7095
        if (resizable) then
318 Thurallor-7095
            textBox.resizer = Thurallor.UI.Resizer(textBox);
319 Thurallor-7095
            textBox.resizer:SetMinimumHeight(20);
320 Thurallor-7095
            textBox.resizer:SetMinimumWidth(slotTabCardWidth - 20);
321 Thurallor-7095
            textBox.resizer:SetMaximumWidth(slotTabCardWidth - 20);
322 Thurallor-7095
        end
323 2 Thurallor-7095
        return top, textBox;
324 Thurallor-7095
    end
325 6 Thurallor-7095
 
326 20 Thurallor-7095
    -- Create a function for adding a left-justified checkbox to the properties control
327 6 Thurallor-7095
    local AddCheckBox = function(top, text, color, checked)
328 Thurallor-7095
        local checkBox = Turbine.UI.Lotro.CheckBox();
329 Thurallor-7095
        checkBox:SetParent(self.slotProperties);
330 Thurallor-7095
        checkBox:SetPosition(0, top);
331 35 Thurallor-7095
        checkBox:SetSize(slotTabCardWidth - 20, 20);
332 6 Thurallor-7095
        top = top + 20;
333 Thurallor-7095
        checkBox:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
334 Thurallor-7095
        checkBox:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
335 Thurallor-7095
        checkBox:SetForeColor(color);
336 Thurallor-7095
        checkBox:SetText(text);
337 Thurallor-7095
        if (checked) then
338 Thurallor-7095
            checkBox:SetChecked(true);
339 Thurallor-7095
        end
340 Thurallor-7095
        return top, checkBox;
341 Thurallor-7095
    end
342 2 Thurallor-7095
 
343 6 Thurallor-7095
    -- Create a function for adding a left-justified radio button to the properties control
344 Thurallor-7095
    local AddRadioButton = function(top, text, color, checked)
345 Thurallor-7095
        local button = Thurallor.UI.RadioButton(self.slotProperties, text, checked);
346 Thurallor-7095
        button:SetPosition(0, top);
347 35 Thurallor-7095
        button:SetSize(slotTabCardWidth - 20, 16);
348 6 Thurallor-7095
        top = top + 16;
349 Thurallor-7095
        button:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
350 Thurallor-7095
        button:SetForeColor(color);
351 Thurallor-7095
        return top, button;
352 Thurallor-7095
    end
353 Thurallor-7095
 
354 Thurallor-7095
    -- Create a function for adding a drop-down listbox to the properties control
355 16 Thurallor-7095
    local AddDropDown = function(top, items, default)
356 128 Thurallor-7095
        local dropDown = Thurallor.UI.DropDown(items, default or items[1]);
357 6 Thurallor-7095
        dropDown:SetParent(self.slotProperties);
358 Thurallor-7095
        dropDown:SetPosition(0, top);
359 35 Thurallor-7095
        dropDown:SetWidth(slotTabCardWidth - 20);
360 6 Thurallor-7095
        top = top + dropDown:GetHeight();
361 Thurallor-7095
        return top, dropDown;
362 Thurallor-7095
    end
363 7 Thurallor-7095
 
364 16 Thurallor-7095
    -- Create a function for adding a pull-down hierarchical menu to the properties control
365 Thurallor-7095
    local AddPullDown = function(top, items, default)
366 Thurallor-7095
        local pullDown = Thurallor.UI.PullDownMenu(items, default);
367 Thurallor-7095
        pullDown:SetParent(self.slotProperties);
368 Thurallor-7095
        pullDown:SetPosition(0, top);
369 35 Thurallor-7095
        pullDown:SetWidth(slotTabCardWidth - 20);
370 16 Thurallor-7095
        top = top + pullDown:GetHeight();
371 Thurallor-7095
        return top, pullDown;
372 Thurallor-7095
    end
373 Thurallor-7095
 
374 7 Thurallor-7095
    -- Create a function for adding a horizontal scrollbar to the properties control
375 Thurallor-7095
    local AddSlider = function(top, minimum, maximum, value)
376 Thurallor-7095
        local scrollBar = Turbine.UI.Lotro.ScrollBar();
377 Thurallor-7095
        scrollBar:SetParent(self.slotProperties);
378 Thurallor-7095
        scrollBar:SetPosition(0, top);
379 35 Thurallor-7095
        scrollBar:SetSize(slotTabCardWidth - 20, 10);
380 7 Thurallor-7095
        scrollBar:SetMinimum(minimum);
381 Thurallor-7095
        scrollBar:SetMaximum(maximum);
382 Thurallor-7095
        scrollBar:SetSmallChange(1);
383 Thurallor-7095
        scrollBar:SetValue(value);
384 Thurallor-7095
        top = top + 10;
385 Thurallor-7095
        return top, scrollBar;
386 Thurallor-7095
    end
387 34 Thurallor-7095
 
388 Thurallor-7095
    -- Create a function for adding an expand/collapse section header to the properties control
389 Thurallor-7095
    local AddSection = function(top, text, color, expanded)
390 Thurallor-7095
        local button = Turbine.UI.Control();
391 Thurallor-7095
        button:SetParent(self.slotProperties);
392 Thurallor-7095
        button:SetPosition(0, top);
393 Thurallor-7095
        button:SetSize(16, 16);
394 Thurallor-7095
        button:SetBlendMode(Turbine.UI.BlendMode.Overlay);
395 Thurallor-7095
        local label = Turbine.UI.Label();
396 Thurallor-7095
        label:SetParent(self.slotProperties);
397 Thurallor-7095
        label:SetPosition(18, top);
398 35 Thurallor-7095
        label:SetSize(slotTabCardWidth - 20 - 18, 16);
399 34 Thurallor-7095
        top = top + 16;
400 Thurallor-7095
        label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
401 Thurallor-7095
        label:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
402 Thurallor-7095
        label:SetForeColor(color);
403 Thurallor-7095
        label:SetMarkupEnabled(true);
404 Thurallor-7095
        label:SetText(text);
405 Thurallor-7095
        function button.MouseClick()
406 Thurallor-7095
            if (button.expanded) then
407 Thurallor-7095
                button:SetBackground(resources.Icon.Expand);
408 Thurallor-7095
                button.expanded = false;
409 Thurallor-7095
                DoCallbacks(button, "ExpandedChanged", false);
410 Thurallor-7095
            else
411 Thurallor-7095
                button:SetBackground(resources.Icon.Collapse);
412 Thurallor-7095
                button.expanded = true;
413 Thurallor-7095
                DoCallbacks(button, "ExpandedChanged", true);
414 Thurallor-7095
            end
415 Thurallor-7095
        end
416 Thurallor-7095
        label.MouseClick = button.MouseClick;
417 Thurallor-7095
        button.expanded = not expanded;
418 Thurallor-7095
        button:MouseClick();
419 Thurallor-7095
        return top, button;
420 Thurallor-7095
    end
421 6 Thurallor-7095
 
422 2 Thurallor-7095
    -- Draw the caption
423 Thurallor-7095
    local top = 54;
424 Thurallor-7095
    if (info.class == "Turbine.UI.Lotro.Quickslot") then
425 Thurallor-7095
        top = AddLabel(top, L:GetText("/SequenceEditor/StandardQuickslot"), Turbine.UI.Color.PaleGoldenrod);
426 135 Thurallor-7095
    elseif ((info.class == "Turbine.UI.Control") or (info.class == "Turbine.UI.Lotro.EntityControl")) then
427 2 Thurallor-7095
        top = AddLabel(top, L:GetText("/SequenceEditor/SpecialSlot") .. ":", Turbine.UI.Color.PaleGoldenrod);
428 32 Thurallor-7095
        local label;
429 Thurallor-7095
        top, label = AddLabel(top, info.toolTip, Turbine.UI.Color.PaleGoldenrod);
430 Thurallor-7095
        -- Some German strings need line wrapping here.
431 Thurallor-7095
        label:SetHeight(32);
432 Thurallor-7095
        label:SetTextAlignment(Turbine.UI.ContentAlignment.TopCenter);
433 2 Thurallor-7095
    end
434 Thurallor-7095
 
435 Thurallor-7095
    -- Draw the arguments
436 Thurallor-7095
    if (info.class == "Turbine.UI.Lotro.Quickslot") then
437 Thurallor-7095
        top = top + 16; -- skip a line
438 Thurallor-7095
        for key, value in pairs(Turbine.UI.Lotro.ShortcutType) do
439 Thurallor-7095
            if (info.type == value) then
440 Thurallor-7095
                top = AddLabel(top, L:GetText("/SequenceEditor/ShortcutType") .. ": " .. L:GetText("/SequenceEditor/ShortcutTypes/" .. key), Turbine.UI.Color.Goldenrod);
441 Thurallor-7095
                break;
442 Thurallor-7095
            end
443 Thurallor-7095
        end
444 7 Thurallor-7095
 
445 Thurallor-7095
        if (info.type == Turbine.UI.Lotro.ShortcutType.Alias) then
446 Thurallor-7095
            -- Allow the user to specify the command
447 Thurallor-7095
            top = top + 16; -- skip a line
448 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/ChatCommand") .. ":", Turbine.UI.Color.Goldenrod);
449 Thurallor-7095
            local textBox;
450 Thurallor-7095
            top, textBox = AddTextBox(top, info.Data, Turbine.UI.Color.White);
451 Thurallor-7095
            textBox.TextChanged = function(sender, args)
452 Thurallor-7095
                local text = sender:GetText();
453 Thurallor-7095
                -- Remove carriage returns
454 Thurallor-7095
                local stripped = string.gsub(text, "\n", "");
455 Thurallor-7095
                if (stripped ~= text) then
456 Thurallor-7095
                    sender:SetText(stripped);
457 Thurallor-7095
                    text = stripped;
458 Thurallor-7095
                end
459 Thurallor-7095
                info.Data = text;
460 16 Thurallor-7095
                self:UpdateBar();
461 7 Thurallor-7095
            end
462 20 Thurallor-7095
        elseif (info.type == Turbine.UI.Lotro.ShortcutType.Item) then
463 Thurallor-7095
            local shortcut = Turbine.UI.Lotro.Shortcut(info.type, info.Data);
464 Thurallor-7095
            local item = shortcut:GetItem();
465 128 Thurallor-7095
            if (pcall(item.GetMaxStackSize, item)) then
466 Thurallor-7095
                if (item:GetMaxStackSize() == 1) then -- equippable
467 Thurallor-7095
 
468 Thurallor-7095
                    -- Allow the user to specify immediate advance, or wait-for-equip
469 Thurallor-7095
                    top = top + 16; -- skip a line
470 Thurallor-7095
                    top = AddLabel(top, L:GetText("/SequenceEditor/AdvanceToNextSlot") .. ":", Turbine.UI.Color.Goldenrod);
471 Thurallor-7095
                    local button1, button2;
472 Thurallor-7095
                    top, button1 = AddRadioButton(top, L:GetText("/SequenceEditor/WithLeftClick"), Turbine.UI.Color.DarkGoldenrod, (not info.advanceEvent));
473 Thurallor-7095
                    top, button2 = AddRadioButton(top, L:GetText("/SequenceEditor/WhenItemEquipped"), Turbine.UI.Color.DarkGoldenrod, info.advanceEvent);
474 Thurallor-7095
                    Thurallor.UI.RadioButton.LinkPeers({button1, button2});
475 Thurallor-7095
 
476 Thurallor-7095
                    button1.Clicked = function()
477 Thurallor-7095
                        info.advanceEvent = nil;
478 Thurallor-7095
                        self:UpdateBar();
479 Thurallor-7095
                    end
480 Thurallor-7095
                    button2.Clicked = function()
481 Thurallor-7095
                        info.advanceEvent = "ItemEquipped";
482 Thurallor-7095
                        self:UpdateBar();
483 Thurallor-7095
                    end
484 20 Thurallor-7095
                end
485 128 Thurallor-7095
            -- else "invalid entity" -- probably an item that no longer exists in your inventory
486 20 Thurallor-7095
            end
487 143 Thurallor-7095
        elseif (info.type == Turbine.UI.Lotro.ShortcutType.Skill) then
488 Thurallor-7095
            local skillName = self.selectedIcon:GetSkillName();
489 Thurallor-7095
 
490 Thurallor-7095
            if (skillName) then
491 Thurallor-7095
                -- Allow the user to specify immediate advance, or wait-for-execute
492 Thurallor-7095
                top = top + 16; -- skip a line
493 Thurallor-7095
                top = AddLabel(top, L:GetText("/SequenceEditor/AdvanceToNextSlot") .. ":", Turbine.UI.Color.Goldenrod);
494 Thurallor-7095
                local button1, button2;
495 Thurallor-7095
                top, button1 = AddRadioButton(top, L:GetText("/SequenceEditor/WithLeftClick"), Turbine.UI.Color.DarkGoldenrod, (not info.advanceEvent));
496 Thurallor-7095
                top, button2 = AddRadioButton(top, L:GetText("/SequenceEditor/WhenSkillExecuted"), Turbine.UI.Color.DarkGoldenrod, info.advanceEvent);
497 Thurallor-7095
                Thurallor.UI.RadioButton.LinkPeers({button1, button2});
498 Thurallor-7095
 
499 Thurallor-7095
                button1.Clicked = function()
500 Thurallor-7095
                    info.advanceEvent = nil;
501 Thurallor-7095
                    self:UpdateBar();
502 Thurallor-7095
                end
503 Thurallor-7095
                button2.Clicked = function()
504 Thurallor-7095
                    info.advanceEvent = "SkillExecuted";
505 Thurallor-7095
                    self:UpdateBar();
506 Thurallor-7095
                end
507 Thurallor-7095
            -- else this skill isn't in moebius92's SkillData database
508 Thurallor-7095
            end
509 7 Thurallor-7095
        end
510 Thurallor-7095
 
511 135 Thurallor-7095
    elseif (info.class == "Turbine.UI.Lotro.EntityControl") then
512 Thurallor-7095
        if (info.type == "SelectTarget") then
513 Thurallor-7095
 
514 Thurallor-7095
            local getTargetFuncs = {
515 Thurallor-7095
                -- args are: watcher, localPlayer, info.raidMemberName
516 Thurallor-7095
                ["Self"] =                  "local _, player = ...; return player;";
517 136 Thurallor-7095
                ["CurrentTarget"] =         "local watcher = ...; return watcher:GetPlayerTarget();";
518 Thurallor-7095
                ["CurrentTargetsTarget"] =  "local watcher = ...; return watcher:GetTargetsTarget();";
519 135 Thurallor-7095
                ["Pet"] =                   "local _, player = ...; return player:GetPet();";
520 Thurallor-7095
                ["RaidLeader"] =            "local watcher = ...; return watcher.GetParty():GetLeader();";
521 Thurallor-7095
                ["RaidMemberByName"] =      "local watcher, _, name = ...; return watcher.GetPartyMemberByName(name, true);";
522 Thurallor-7095
                ["NextRaidMember"] =        "local watcher = ...; return watcher.GetNextPartyMember();";
523 Thurallor-7095
                ["FirstAssistee"] =         "local watcher = ...; return watcher.GetPartyAssistTarget(1);";
524 Thurallor-7095
                ["SecondAssistee"] =        "local watcher = ...; return watcher.GetPartyAssistTarget(2);";
525 Thurallor-7095
                ["ThirdAssistee"] =         "local watcher = ...; return watcher.GetPartyAssistTarget(3);";
526 Thurallor-7095
                ["FourthAssistee"] =        "local watcher = ...; return watcher.GetPartyAssistTarget(4);";
527 Thurallor-7095
                ["NextAssistee"] =          "local watcher = ...; return watcher.GetNextAssistTarget();";
528 Thurallor-7095
                ["FirstAssisteesTarget"] =  "local watcher = ...; local target = watcher.GetPartyAssistTarget(1); return (target and target:GetTarget());";
529 Thurallor-7095
                ["SecondAssisteesTarget"] = "local watcher = ...; local target = watcher.GetPartyAssistTarget(2); return (target and target:GetTarget());";
530 Thurallor-7095
                ["ThirdAssisteesTarget"] =  "local watcher = ...; local target = watcher.GetPartyAssistTarget(3); return (target and target:GetTarget());";
531 Thurallor-7095
                ["FourthAssisteesTarget"] = "local watcher = ...; local target = watcher.GetPartyAssistTarget(4); return (target and target:GetTarget());";
532 Thurallor-7095
                ["NextAssisteesTarget"] =   "local watcher = ...; local target = watcher.GetNextAssistTarget(); return (target and target:GetTarget());";
533 Thurallor-7095
            };
534 Thurallor-7095
 
535 Thurallor-7095
            -- Allow the user to choose the target category
536 Thurallor-7095
            top = top + 16; -- skip a line
537 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/Target") .. ":", Turbine.UI.Color.Goldenrod);
538 Thurallor-7095
 
539 Thurallor-7095
            local currentItem = info.target;
540 Thurallor-7095
            info.getTargetFunc = getTargetFuncs[currentItem];
541 Thurallor-7095
            local prevContext;
542 Thurallor-7095
            prevContext = L:SetContext("/SequenceEditor/TargetMenu");
543 Thurallor-7095
            local targs, localTargs = L:GetItems(), {};
544 Thurallor-7095
            for targ in values(targs) do
545 Thurallor-7095
                table.insert(localTargs, L:GetText(targ));
546 Thurallor-7095
            end
547 Thurallor-7095
            table.sort(localTargs);
548 Thurallor-7095
            local dropDown;
549 Thurallor-7095
            top, dropDown = AddDropDown(top, localTargs, L:GetText(currentItem));
550 Thurallor-7095
            dropDown:SetAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
551 Thurallor-7095
            dropDown:SetExpandedWidth(math.max(220, slotTabCardWidth - 20));
552 Thurallor-7095
            dropDown.ItemChanged = function(sender, args)
553 Thurallor-7095
                for targ in values(targs) do
554 Thurallor-7095
                    if (L:GetText(targ) == args.Text) then
555 Thurallor-7095
                        info.target = targ;
556 Thurallor-7095
                        self:DisplaySlot(self.selectedSlot);
557 Thurallor-7095
                        self:UpdateBar();
558 Thurallor-7095
                        break;
559 Thurallor-7095
                    end
560 Thurallor-7095
                end
561 Thurallor-7095
            end
562 Thurallor-7095
 
563 Thurallor-7095
            -- If "Raid Member" is chosen, allow the user to select raid member by name
564 Thurallor-7095
            if (info.target == "RaidMemberByName") then
565 Thurallor-7095
                if ((info.raidMemberName == nil) or (info.raidMemberName == "")) then
566 Thurallor-7095
                    info.raidMemberName = self.manager.player:GetName();
567 Thurallor-7095
                end
568 Thurallor-7095
                local textBox;
569 Thurallor-7095
                top, textBox = AddTextBox(top, info.raidMemberName, Turbine.UI.Color.White);
570 Thurallor-7095
                textBox.TextChanged = function(sender, args)
571 Thurallor-7095
                    local text = sender:GetText();
572 Thurallor-7095
                    -- Remove carriage returns
573 Thurallor-7095
                    local stripped = string.gsub(text, "\n", "");
574 Thurallor-7095
                    if (stripped ~= text) then
575 Thurallor-7095
                        sender:SetText(stripped);
576 Thurallor-7095
                        text = stripped;
577 Thurallor-7095
                    end
578 Thurallor-7095
                    info.raidMemberName = text;
579 Thurallor-7095
                    self:UpdateBar();
580 Thurallor-7095
                end
581 Thurallor-7095
            end
582 Thurallor-7095
 
583 Thurallor-7095
            -- Evaluate the target selection and display the name of the targeted entity
584 Thurallor-7095
            top, label = AddLabel(top, "", Turbine.UI.Color.Goldenrod);
585 Thurallor-7095
            label.Update = function()
586 Thurallor-7095
                local entity = loadstring(info.getTargetFunc)(self.manager.watcher, self.manager.player, info.raidMemberName);
587 Thurallor-7095
                if (entity) then
588 Thurallor-7095
                    label:SetText("(" .. entity:GetName() .. ")");
589 Thurallor-7095
                    label:SetForeColor(Turbine.UI.Color.Lime);
590 Thurallor-7095
                else
591 Thurallor-7095
                    label:SetText(L:GetText("/SequenceEditor/NoTarget"));
592 Thurallor-7095
                    label:SetForeColor(Turbine.UI.Color.Red);
593 Thurallor-7095
                end
594 Thurallor-7095
            end
595 Thurallor-7095
            label:SetWantsUpdates(true);
596 Thurallor-7095
        end
597 Thurallor-7095
 
598 2 Thurallor-7095
    elseif (info.class == "Turbine.UI.Control") then
599 34 Thurallor-7095
        if (info.type == "Delay") then
600 Thurallor-7095
 
601 Thurallor-7095
            -- Allow the user to specify the delay period
602 Thurallor-7095
            top = top + 16; -- skip a line
603 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/DelayPeriod") .. ":", Turbine.UI.Color.Goldenrod);
604 Thurallor-7095
            local textBox;
605 Thurallor-7095
            _, textBox = AddTextBox(top, info.delay, Turbine.UI.Color.White);
606 Thurallor-7095
            textBox:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleRight);
607 35 Thurallor-7095
            local center = math.floor((slotTabCardWidth - 20) / 2);
608 34 Thurallor-7095
            textBox:SetWidth(50);
609 Thurallor-7095
            textBox:SetLeft(center - 2 - 50);
610 Thurallor-7095
            top, label = AddLabel(top + 2, L:GetText("/SequenceEditor/Seconds"), Turbine.UI.Color.DarkGoldenrod);
611 Thurallor-7095
            label:SetLeft(center + 2);
612 Thurallor-7095
            label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
613 Thurallor-7095
            textBox.TextChanged = function(sender, args)
614 Thurallor-7095
                info.delay = tonumber(sender:GetText());
615 147 Thurallor-7095
                info.action = "local item, s = ...; item.bar:StartSlotCooldown(s, " .. tostring(info.delay):gsub(",", ".") .. ");";
616 34 Thurallor-7095
                self:UpdateBar();
617 Thurallor-7095
            end
618 Thurallor-7095
        elseif (info.type == "GenerateEvent") then
619 6 Thurallor-7095
 
620 Thurallor-7095
            -- Allow the user to specify the event name
621 Thurallor-7095
            top = top + 16; -- skip a line
622 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/EventName") .. ":", Turbine.UI.Color.Goldenrod);
623 2 Thurallor-7095
            local textBox;
624 Thurallor-7095
            top, textBox = AddTextBox(top, info.eventName, Turbine.UI.Color.White);
625 Thurallor-7095
            textBox.TextChanged = function(sender, args)
626 5 Thurallor-7095
                local text = sender:GetText();
627 Thurallor-7095
                -- Remove carriage returns
628 Thurallor-7095
                local stripped = string.gsub(text, "\n", "");
629 Thurallor-7095
                if (stripped ~= text) then
630 Thurallor-7095
                    sender:SetText(stripped);
631 Thurallor-7095
                    text = stripped;
632 Thurallor-7095
                end
633 Thurallor-7095
                info.eventName = text;
634 16 Thurallor-7095
                self:UpdateBar();
635 2 Thurallor-7095
            end
636 6 Thurallor-7095
        elseif (info.type == "SetUnequipDestination") then
637 Thurallor-7095
 
638 20 Thurallor-7095
            -- Temporary method to allow users to discover bag slot numbers.
639 Thurallor-7095
            self.ItemMovedCallback = function(sender, args)
640 Thurallor-7095
                local str = L:GetText("/ItemMoved");
641 Thurallor-7095
                str = string.gsub(str, "<source>", tostring(args.OldIndex));
642 Thurallor-7095
                str = string.gsub(str, "<destination>", tostring(args.NewIndex));
643 Thurallor-7095
                Puts(str);
644 Thurallor-7095
            end
645 Thurallor-7095
            AddCallback(Thurallor.Utils.Watcher, "ItemMoved", self.ItemMovedCallback);
646 Thurallor-7095
 
647 6 Thurallor-7095
            -- Allow the user to specify the desired bag slot
648 Thurallor-7095
            top = top + 16; -- skip a line
649 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/PreferredBagSlot") .. ":", Turbine.UI.Color.Goldenrod);
650 Thurallor-7095
 
651 114 Thurallor-7095
            top, textBox = AddTextBox(top, tostring(info.bagSlot), Turbine.UI.Color.White);
652 Thurallor-7095
            textBox:SetFont(Turbine.UI.Lotro.Font.Verdana14);
653 Thurallor-7095
            textBox.TextChanged = function(sender, args)
654 Thurallor-7095
                local series = Thurallor.Utils.Series(sender:GetText())
655 Thurallor-7095
                info.bagSlot = series:tostring();
656 16 Thurallor-7095
                self:UpdateBar();
657 6 Thurallor-7095
            end
658 Thurallor-7095
        elseif (string.match(info.type, "^Remove ")) then
659 Thurallor-7095
 
660 Thurallor-7095
            -- Allow the user to edit choose the item to be unequipped
661 Thurallor-7095
            top = top + 16; -- skip a line
662 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/EquipmentType") .. ":", Turbine.UI.Color.Goldenrod);
663 Thurallor-7095
 
664 Thurallor-7095
            local currentItem = string.sub(info.type, 8);
665 Thurallor-7095
            local prevContext = L:SetContext("/SequenceEditor/EquipmentSlots");
666 Thurallor-7095
            local eqSlots, localEqSlots = L:GetItems(), {};
667 Thurallor-7095
            for slot in values(eqSlots) do
668 Thurallor-7095
                table.insert(localEqSlots, L:GetText(slot));
669 Thurallor-7095
            end
670 Thurallor-7095
            table.sort(localEqSlots);
671 Thurallor-7095
            local dropDown;
672 16 Thurallor-7095
            top, dropDown = AddDropDown(top, localEqSlots, L:GetText(currentItem));
673 122 Thurallor-7095
            dropDown:SetExpandedWidth(math.max(220, slotTabCardWidth - 20));
674 6 Thurallor-7095
            dropDown.ItemChanged = function(sender, args)
675 Thurallor-7095
                for slot in values(eqSlots) do
676 Thurallor-7095
                    if (L:GetText(slot) == args.Text) then
677 122 Thurallor-7095
                        self:DeleteSlot(s);
678 6 Thurallor-7095
                        self:CreateRemovalSlot(s, slot, info.bagSlot);
679 Thurallor-7095
                        break;
680 Thurallor-7095
                    end
681 Thurallor-7095
                end
682 Thurallor-7095
            end
683 16 Thurallor-7095
        elseif (info.type == "If") then
684 Thurallor-7095
 
685 Thurallor-7095
            -- Allow the user to specify the conditional expression
686 Thurallor-7095
            top = top + 16; -- skip a line
687 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/Condition") .. ":", Turbine.UI.Color.Goldenrod);
688 Thurallor-7095
 
689 Thurallor-7095
            local prevContext = L:SetContext("/SequenceEditor/ConditionTypes");
690 Thurallor-7095
            local condInfo = {
691 20 Thurallor-7095
                ["Always"] =                      { expr = "return true;" };
692 Thurallor-7095
                ["Never"] =                       { expr = "return false;" };
693 43 Thurallor-7095
                ["SkillReady"] =                  {  arg = "skillName";
694 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.SkillReady(<skillName>));" };
695 Thurallor-7095
                ["SkillNotReady"] =               {  arg = "skillName";
696 Thurallor-7095
                                                    expr = "return (not Thurallor.Utils.Watcher.SkillReady(<skillName>));" };
697 48 Thurallor-7095
                ["SkillUsable"] =                 {  arg = "skillName";
698 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.SkillUsable(<skillName>));" };
699 Thurallor-7095
                ["SkillNotUsable"] =              {  arg = "skillName";
700 Thurallor-7095
                                                    expr = "return (not Thurallor.Utils.Watcher.SkillUsable(<skillName>));" };
701 41 Thurallor-7095
                ["SkillTrained"] =                {  arg = "skillName";
702 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.SkillTrained(<skillName>));" };
703 Thurallor-7095
                ["SkillNotTrained"] =             {  arg = "skillName";
704 Thurallor-7095
                                                    expr = "return (not Thurallor.Utils.Watcher.SkillTrained(<skillName>));" };
705 20 Thurallor-7095
                ["PlayerEffectDisease"] =         { expr = "return Thurallor.Utils.Watcher.PlayerHasEffectCategory(Turbine.Gameplay.EffectCategory.Disease);" };
706 Thurallor-7095
                ["PlayerEffectFear"] =            { expr = "return Thurallor.Utils.Watcher.PlayerHasEffectCategory(Turbine.Gameplay.EffectCategory.Fear);" };
707 Thurallor-7095
                ["PlayerEffectPoison"] =          { expr = "return Thurallor.Utils.Watcher.PlayerHasEffectCategory(Turbine.Gameplay.EffectCategory.Poison);" };
708 Thurallor-7095
                ["PlayerEffectWound"] =           { expr = "return Thurallor.Utils.Watcher.PlayerHasEffectCategory(Turbine.Gameplay.EffectCategory.Wound);" };
709 Thurallor-7095
                ["PlayerEffectOther"] =           {  arg = "effect";
710 Thurallor-7095
                                                    expr = "return Thurallor.Utils.Watcher.PlayerHasEffect(<effect>);" };
711 Thurallor-7095
                ["NotPlayerEffectOther"] =        {  arg = "effect";
712 Thurallor-7095
                                                    expr = "return (not Thurallor.Utils.Watcher.PlayerHasEffect(<effect>));" };
713 23 Thurallor-7095
-- Target effects tracking is so buggy as to be useless.  Hoping Turbine addresses this bug soon.
714 Thurallor-7095
--                ["TargetEffectDisease"] =         { expr = "return Thurallor.Utils.Watcher.TargetHasEffectCategory(Turbine.Gameplay.EffectCategory.Disease);" };
715 Thurallor-7095
--                ["TargetEffectFear"] =            { expr = "return Thurallor.Utils.Watcher.TargetHasEffectCategory(Turbine.Gameplay.EffectCategory.Fear);" };
716 Thurallor-7095
--                ["TargetEffectPoison"] =          { expr = "return Thurallor.Utils.Watcher.TargetHasEffectCategory(Turbine.Gameplay.EffectCategory.Poison);" };
717 Thurallor-7095
--                ["TargetEffectWound"] =           { expr = "return Thurallor.Utils.Watcher.TargetHasEffectCategory(Turbine.Gameplay.EffectCategory.Wound);" };
718 Thurallor-7095
--                ["TargetEffectOther"] =           {  arg = "effect";
719 Thurallor-7095
--                                                    expr = "return Thurallor.Utils.Watcher.TargetHasEffect(<effect>);" };
720 Thurallor-7095
--                ["NotTargetEffectOther"] =        {  arg = "effect";
721 Thurallor-7095
--                                                    expr = "return (not Thurallor.Utils.Watcher.TargetHasEffect(<effect>));" };
722 111 Thurallor-7095
                ["PlayerInCombat"] =              { expr = "local _, player = ...; return player:IsInCombat();" };
723 Thurallor-7095
                ["PlayerOutOfCombat"] =           { expr = "local _, player = ...; return not player:IsInCombat();" };
724 20 Thurallor-7095
                ["PlayerMorale < x"] =            {  arg = "x";
725 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetMorale() < <x>)" };
726 Thurallor-7095
                ["PlayerMorale < x%"] =           {  arg = "x";
727 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetMorale() < player:GetBaseMaxMorale() * <x> / 100)" };
728 Thurallor-7095
                ["PlayerMorale > x"] =            {  arg = "x";
729 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetMorale() > <x>)" };
730 Thurallor-7095
                ["PlayerMorale > x%"] =           {  arg = "x";
731 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetMorale() > player:GetBaseMaxMorale() * <x> / 100)" };
732 140 Thurallor-7095
                ["TargetIsFellow"] =              { expr = "local _, player = ...; return Thurallor.Utils.Watcher.TargetIsPartyMember();" };
733 Thurallor-7095
                ["TargetNotFellow"] =             { expr = "local _, player = ...; return not Thurallor.Utils.Watcher.TargetIsPartyMember();" };
734 20 Thurallor-7095
                ["TargetMorale < x"] =            {  arg = "x";
735 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetMorale and (target:GetMorale() < <x>))" };
736 20 Thurallor-7095
                ["TargetMorale < x%"] =           {  arg = "x";
737 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetMorale and (target:GetMorale() < target:GetBaseMaxMorale() * <x> / 100))" };
738 20 Thurallor-7095
                ["TargetMorale > x"] =            {  arg = "x";
739 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetMorale and (target:GetMorale() > <x>))" };
740 20 Thurallor-7095
                ["TargetMorale > x%"] =           {  arg = "x";
741 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetMorale and (target:GetMorale() > target:GetBaseMaxMorale() * <x> / 100))" };
742 20 Thurallor-7095
                ["PlayerPower < x"] =             {  arg = "x";
743 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetPower() < <x>)" };
744 Thurallor-7095
                ["PlayerPower < x%"] =            {  arg = "x";
745 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetPower() < player:GetBaseMaxPower() * <x> / 100)" };
746 Thurallor-7095
                ["PlayerPower > x"] =             {  arg = "x";
747 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetPower() > <x>)" };
748 Thurallor-7095
                ["PlayerPower > x%"] =            {  arg = "x";
749 Thurallor-7095
                                                    expr = "local _, player = ...; return (player:GetPower() > player:GetBaseMaxPower() * <x> / 100)" };
750 Thurallor-7095
                ["TargetPower < x"] =             {  arg = "x";
751 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetPower and (target:GetPower() < <x>))" };
752 20 Thurallor-7095
                ["TargetPower < x%"] =            {  arg = "x";
753 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetPower and (target:GetPower() < target:GetBaseMaxPower() * <x> / 100))" };
754 20 Thurallor-7095
                ["TargetPower > x"] =             {  arg = "x";
755 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetPower and (target:GetPower() > <x>))" };
756 20 Thurallor-7095
                ["TargetPower > x%"] =            {  arg = "x";
757 117 Thurallor-7095
                                                    expr = "local _, player = ...; local target = player:GetTarget(); return (target and target.GetPower and (target:GetPower() > target:GetBaseMaxPower() * <x> / 100))" };
758 111 Thurallor-7095
                ["ChampionPlayerFervor < x"] =    {  arg = "x";
759 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetFervor and (attribs:GetFervor() < <x>);" };
760 Thurallor-7095
                ["ChampionPlayerFervor > x"] =    {  arg = "x";
761 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetFervor and (attribs:GetFervor() > <x>);" };
762 20 Thurallor-7095
                ["BeorningPlayerWrath < x%"] =    {  arg = "x";
763 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetWrath and (attribs:GetWrath() < <x>);" };
764 Thurallor-7095
                ["BeorningPlayerWrath > x%"] =    {  arg = "x";
765 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetWrath and (attribs:GetWrath() > <x>);" };
766 Thurallor-7095
                ["BeorningInBearForm"] =          { expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.IsInBearForm and attribs:IsInBearForm();" };
767 Thurallor-7095
                ["BeorningNotInBearForm"] =       { expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.IsInBearForm and (not attribs:IsInBearForm());" };
768 40 Thurallor-7095
                ["HunterFocus < x"] =             {  arg = "x";
769 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetFocus and (attribs:GetFocus() < <x>);" };
770 Thurallor-7095
                ["HunterFocus > x"] =             {  arg = "x";
771 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetFocus and (attribs:GetFocus() > <x>);" };
772 124 Thurallor-7095
                ["RunekeeperAttunement < x"] =    {  arg = "x";
773 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetAttunement and (attribs:GetAttunement() < <x>);" };
774 Thurallor-7095
                ["RunekeeperAttunement > x"] =    {  arg = "x";
775 Thurallor-7095
                                                    expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.GetAttunement and (attribs:GetAttunement() > <x>);" };
776 Thurallor-7095
                ["RunekeeperCharged"] =           { expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.IsCharged and attribs:IsCharged();" };
777 Thurallor-7095
                ["RunekeeperNotCharged"] =        { expr = "local _, player = ...; local attribs = player:GetClassAttributes(); return attribs.IsCharged and (not attribs:IsCharged());" };
778 20 Thurallor-7095
                ["ItemEquipped"] =                {  arg = { "eqItemName", "eqSlot" };
779 Thurallor-7095
                                                    expr = "return IsEquipped(<eqItemName>, <eqSlot>);" };
780 Thurallor-7095
                ["ItemNotEquipped"] =             {  arg = { "eqItemName", "eqSlot" };
781 Thurallor-7095
                                                    expr = "return (not IsEquipped(<eqItemName>, <eqSlot>));" };
782 30 Thurallor-7095
                ["ItemQuantity > x"] =            {  arg = { "stackItemName", "x" };
783 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.GetItemQuantity(<stackItemName>) > <x>);" };
784 Thurallor-7095
                ["ItemQuantity < x"] =            {  arg = { "stackItemName", "x" };
785 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.GetItemQuantity(<stackItemName>) < <x>);" };
786 111 Thurallor-7095
                ["StanceSelected"] =              {  arg = "stance";
787 119 Thurallor-7095
                                                    expr = "return (Thurallor.Utils.Watcher.GetStance() == <stance>);" };
788 20 Thurallor-7095
                ["LuaScript"] =                   {  arg = "script";
789 Thurallor-7095
                                                    expr = "<script>" };
790 16 Thurallor-7095
            };
791 Thurallor-7095
            local condNames = {};
792 Thurallor-7095
            for k in keys(condInfo) do
793 Thurallor-7095
                table.insert(condNames, L:GetText(k));
794 Thurallor-7095
            end
795 Thurallor-7095
            table.sort(condNames);
796 Thurallor-7095
 
797 20 Thurallor-7095
            local function SwitchArgs(arg)
798 16 Thurallor-7095
                if (not info.condArgs) then
799 Thurallor-7095
                    info.condArgs = {};
800 Thurallor-7095
                end
801 Thurallor-7095
                if (not arg) then
802 Thurallor-7095
                    info.condArgs = nil;
803 Thurallor-7095
                elseif ((arg == "x") and not info.condArgs.x) then
804 Thurallor-7095
                    info.condArgs = { x = 0 };
805 41 Thurallor-7095
                elseif ((arg == "skillName") and not info.condArgs.skillName) then
806 Thurallor-7095
                    info.condArgs = { skillName = "nil" };
807 16 Thurallor-7095
                elseif ((arg == "skill") and not info.condArgs.skill) then
808 Thurallor-7095
                    info.condArgs = { skill = 0 };
809 20 Thurallor-7095
                elseif ((arg == "effect") and not info.condArgs.effect) then
810 22 Thurallor-7095
                    info.condArgs = { effect = "nil" };
811 111 Thurallor-7095
                elseif ((arg == "stance") and not info.condArgs.stance) then
812 Thurallor-7095
                    info.condArgs = { stance = 0 };
813 16 Thurallor-7095
                elseif ((arg == "script") and not info.condArgs.script) then
814 Thurallor-7095
                    if (info.condExpr) then
815 Thurallor-7095
                        local script = info.condExpr;
816 Thurallor-7095
                        if (info.condArgs) then
817 Thurallor-7095
                            for name, value in pairs(info.condArgs) do
818 Thurallor-7095
                                script = string.gsub(script, "<" .. name .. ">", tostring(value));
819 Thurallor-7095
                            end
820 Thurallor-7095
                        end
821 Thurallor-7095
                        info.condArgs = { script = script };
822 Thurallor-7095
                    else
823 Thurallor-7095
                        info.condArgs = { script = "return true;" };
824 Thurallor-7095
                    end
825 20 Thurallor-7095
                elseif (type(arg) == "table") then
826 Thurallor-7095
                    -- Multiple args
827 Thurallor-7095
                    local prevArgs = info.condArgs;
828 Thurallor-7095
                    info.condArgs = {};
829 Thurallor-7095
                    for argName in values(arg) do
830 Thurallor-7095
                        if (prevArgs[argName]) then
831 Thurallor-7095
                            info.condArgs[argName] = prevArgs[argName];
832 16 Thurallor-7095
                        end
833 20 Thurallor-7095
                        if ((argName == "eqItemName") and not info.condArgs.eqItemName) then
834 Thurallor-7095
                            info.condArgs.eqItemName = "nil";
835 30 Thurallor-7095
                        elseif ((argName == "stackItemName") and not info.condArgs.stackItemName) then
836 Thurallor-7095
                            info.condArgs.stackItemName = "nil";
837 20 Thurallor-7095
                        elseif ((argName == "eqSlot") and not info.condArgs.eqSlot) then
838 Thurallor-7095
                            info.condArgs.eqSlot = "nil";
839 30 Thurallor-7095
                        elseif ((argName == "x") and not info.condArgs.x) then
840 Thurallor-7095
                            info.condArgs.x  = 0;
841 16 Thurallor-7095
                        end
842 Thurallor-7095
                    end
843 Thurallor-7095
                end
844 20 Thurallor-7095
                info.condExpr = condInfo[info.condName].expr;
845 16 Thurallor-7095
            end
846 Thurallor-7095
 
847 Thurallor-7095
            local dropDown;
848 Thurallor-7095
            top, dropDown = AddDropDown(top, condNames, L:GetText(info.condName));
849 47 Thurallor-7095
            dropDown:SetExpandedWidth(math.max(300, slotTabCardWidth - 20));
850 16 Thurallor-7095
            dropDown:SetAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
851 Thurallor-7095
            dropDown.ItemChanged = function(sender, args)
852 Thurallor-7095
                local prevContext = L:SetContext("/SequenceEditor/ConditionTypes");
853 Thurallor-7095
                info.condName = L:GetItem(args.Text);
854 Thurallor-7095
                L:SetContext(prevContext);
855 Thurallor-7095
                local arg = condInfo[info.condName].arg;
856 20 Thurallor-7095
                SwitchArgs(arg);
857 16 Thurallor-7095
                self:UpdateBar();
858 20 Thurallor-7095
                self:DisplaySlot(self.selectedSlot);
859 16 Thurallor-7095
            end
860 Thurallor-7095
 
861 20 Thurallor-7095
            SwitchArgs(condInfo[info.condName].arg);
862 Thurallor-7095
            L:SetContext(prevContext);
863 16 Thurallor-7095
 
864 20 Thurallor-7095
            -- Display additional arguments depending on the current condition type
865 Thurallor-7095
            if (info.condArgs) then
866 30 Thurallor-7095
                if (info.condArgs.stackItemName) then
867 Thurallor-7095
                    local function GetStackableItems()
868 Thurallor-7095
                        local hash = {};
869 Thurallor-7095
                        local backpack = self.manager.player:GetBackpack();
870 Thurallor-7095
                        for i = 1, backpack:GetSize(), 1 do
871 Thurallor-7095
                            local item = backpack:GetItem(i);
872 Thurallor-7095
                            if (item and (item:GetMaxStackSize() > 1)) then
873 Thurallor-7095
                                hash[item:GetName()] = true;
874 Thurallor-7095
                            end
875 Thurallor-7095
                        end
876 Thurallor-7095
                        local items = {};
877 Thurallor-7095
                        for key in sorted_keys(hash) do
878 Thurallor-7095
                            table.insert(items, key);
879 Thurallor-7095
                        end
880 Thurallor-7095
                        return items;
881 Thurallor-7095
                    end
882 Thurallor-7095
                    local stackItemNames = GetStackableItems();
883 Thurallor-7095
                    local dropDown;
884 Thurallor-7095
                    top, dropDown = AddDropDown(top + 2, stackItemNames);
885 47 Thurallor-7095
                    dropDown:SetExpandedWidth(math.max(400, slotTabCardWidth - 20));
886 30 Thurallor-7095
                    dropDown.ItemChanged = function(sender, args)
887 Thurallor-7095
                        info.condArgs.stackItemName = "\"" .. args.Text .. "\"";
888 Thurallor-7095
                        self:UpdateBar();
889 Thurallor-7095
                    end
890 Thurallor-7095
                    dropDown:SetParent(self.slotProperties);
891 41 Thurallor-7095
                    local name = info.condArgs.stackItemName;
892 Thurallor-7095
                    if (name == "nil") then
893 Thurallor-7095
                        name = stackItemNames[1];
894 Thurallor-7095
                        if (name) then
895 Thurallor-7095
                            dropDown:ItemChanged({Text = name});
896 Thurallor-7095
                        end
897 Thurallor-7095
                    else
898 Thurallor-7095
                        dropDown:SetText(string.sub(name, 2, -2));
899 30 Thurallor-7095
                    end
900 Thurallor-7095
                end
901 20 Thurallor-7095
                if (info.condArgs.x) then
902 Thurallor-7095
                    local _, xLabel = AddLabel(top + 3, "", Turbine.UI.Color.DarkGoldenrod);
903 Thurallor-7095
                    xLabel:SetWidth(30);
904 Thurallor-7095
                    xLabel:SetFont(Turbine.UI.Lotro.Font.Verdana16);
905 Thurallor-7095
                    xLabel:SetText("x =");
906 Thurallor-7095
 
907 Thurallor-7095
                    local xField;
908 Thurallor-7095
                    top, xField = AddTextBox(top + 2, "", Turbine.UI.Color.White);
909 Thurallor-7095
                    xField:SetLeft(30);
910 35 Thurallor-7095
                    xField:SetWidth(slotTabCardWidth - 50);
911 20 Thurallor-7095
                    xField.TextChanged = function(sender)
912 Thurallor-7095
                        info.condArgs.x = tonumber(sender:GetText());
913 23 Thurallor-7095
                        if (not info.condArgs.x) then
914 Thurallor-7095
                            info.condArgs.x = 0;
915 Thurallor-7095
                        end
916 20 Thurallor-7095
                        self:UpdateBar();
917 Thurallor-7095
                    end
918 Thurallor-7095
                    xField:SetText(info.condArgs.x);
919 Thurallor-7095
                    xLabel:SetParent(self.slotProperties);
920 Thurallor-7095
                    xField:SetText(tostring(info.condArgs.x));
921 Thurallor-7095
                    xField:SetParent(self.slotProperties);
922 Thurallor-7095
                end
923 41 Thurallor-7095
                if (info.condArgs.skillName) then
924 43 Thurallor-7095
                    local trainedSkills = Thurallor.Utils.Watcher.GetTrainedSkillsInfo();
925 Thurallor-7095
                    local skills = Thurallor.Utils.Watcher.GetSkillsInfo(true);
926 Thurallor-7095
                    local displayNames = {};
927 Thurallor-7095
                    local untrained = L:GetText("/SequenceEditor/Untrained");
928 Thurallor-7095
                    for n = 1, #skills.names, 1 do
929 Thurallor-7095
                        local name = skills.names[n];
930 Thurallor-7095
                        if (not trainedSkills.byName[name]) then
931 Thurallor-7095
                            name = name .. " (" .. untrained .. ")";
932 Thurallor-7095
                        end
933 Thurallor-7095
                        table.insert(displayNames, name);
934 Thurallor-7095
                    end
935 20 Thurallor-7095
                    local dropDown;
936 43 Thurallor-7095
                    top, dropDown = AddDropDown(top + 2, displayNames);
937 47 Thurallor-7095
                    dropDown:SetExpandedWidth(math.max(300, slotTabCardWidth - 20));
938 20 Thurallor-7095
                    dropDown.ItemChanged = function(sender, args)
939 43 Thurallor-7095
                        local text = string.gsub(args.Text, " %(" .. L:GetText("/SequenceEditor/Untrained") .. "%)$", "");
940 Thurallor-7095
                        dropDown:SetText(text);
941 Thurallor-7095
                        info.condArgs.skillName = "\"" .. text .. "\"";
942 41 Thurallor-7095
                        self:UpdateBar();
943 Thurallor-7095
                    end
944 Thurallor-7095
                    dropDown:SetParent(self.slotProperties);
945 Thurallor-7095
                    local skillName = info.condArgs.skillName;
946 Thurallor-7095
                    if (skillName == "nil") then
947 43 Thurallor-7095
                        skillName = skills.names[1]; -- first one always will be a trained skill
948 41 Thurallor-7095
                        dropDown:ItemChanged({Text = skillName});
949 Thurallor-7095
                    else
950 Thurallor-7095
                        skillName = string.gsub(skillName, "\"", "")
951 Thurallor-7095
                        dropDown:SetText(skillName);
952 Thurallor-7095
                    end
953 Thurallor-7095
                end
954 20 Thurallor-7095
                if (info.condArgs.effect) then
955 Thurallor-7095
                    local effectNames = Thurallor.Utils.Watcher.GetKnownEffectNames();
956 Thurallor-7095
                    if (#effectNames >= 1) then
957 Thurallor-7095
                        table.insert(effectNames, 1, L:GetText("/SequenceEditor/ConditionTypes/OtherEffect"));
958 Thurallor-7095
                        local dropDown;
959 Thurallor-7095
                        top, dropDown = AddDropDown(top + 2, effectNames);
960 47 Thurallor-7095
                        dropDown:SetExpandedWidth(math.max(300, slotTabCardWidth - 20));
961 23 Thurallor-7095
                        function dropDown.ItemChanged(ctl, args)
962 22 Thurallor-7095
                            local effectNames = Thurallor.Utils.Watcher.GetKnownEffectNames();
963 Thurallor-7095
                            local other = L:GetText("/SequenceEditor/ConditionTypes/OtherEffect");
964 Thurallor-7095
                            table.insert(effectNames, 1, other);
965 20 Thurallor-7095
                            if (args.Text == other) then
966 Thurallor-7095
                                local ok = L:GetText("/ExportWindow/OK");
967 Thurallor-7095
                                local window = Alert(other,
968 Thurallor-7095
                                    L:GetText("/SequenceEditor/ConditionTypes/OtherEffectHelp"),
969 Thurallor-7095
                                    ok);
970 Thurallor-7095
                                CenterWindow(window);
971 Thurallor-7095
                                window.label:SetFont(Turbine.UI.Lotro.Font.Verdana14);
972 Thurallor-7095
                                window.label:SetText(window.label:GetText());
973 Thurallor-7095
                                window.buttons[ok].Click = function()
974 Thurallor-7095
                                    window:Close();
975 Thurallor-7095
                                end
976 Thurallor-7095
                                dropDown:SetText(string.gsub(info.condArgs.effect, "\"", ""));
977 22 Thurallor-7095
                            elseif (not args.Text) then
978 Thurallor-7095
                                return;
979 20 Thurallor-7095
                            else
980 Thurallor-7095
                                info.condArgs.effect = "\"" .. args.Text .. "\"";
981 Thurallor-7095
                                self:UpdateBar();
982 Thurallor-7095
                            end
983 Thurallor-7095
                        end
984 Thurallor-7095
                        dropDown:SetParent(self.slotProperties);
985 Thurallor-7095
                        local effect = info.condArgs.effect;
986 22 Thurallor-7095
                        if (effect == "nil") then
987 20 Thurallor-7095
                            effect = effectNames[2];
988 41 Thurallor-7095
                            dropDown:SetText(effect);
989 Thurallor-7095
                            dropDown:ItemChanged({Text = effect});
990 22 Thurallor-7095
                        else
991 Thurallor-7095
                            effect = string.gsub(effect, "\"", "")
992 41 Thurallor-7095
                            dropDown:SetText(effect);
993 20 Thurallor-7095
                        end
994 Thurallor-7095
                    end
995 Thurallor-7095
                end
996 111 Thurallor-7095
                if (info.condArgs.stance) then
997 Thurallor-7095
                    local stanceNames = L:GetSortedTexts("/SequenceEditor/Stance");
998 Thurallor-7095
                    local dropDown;
999 Thurallor-7095
                    top, dropDown = AddDropDown(top + 2, stanceNames);
1000 Thurallor-7095
                    dropDown:SetExpandedWidth(math.max(500, slotTabCardWidth - 20));
1001 Thurallor-7095
                    function dropDown.ItemChanged(ctl, args)
1002 Thurallor-7095
                        local prevContext = L:SetContext("/SequenceEditor/Stance");
1003 Thurallor-7095
                        local stance = L:GetItem(args.Text);
1004 Thurallor-7095
                        info.condArgs.stance = tonumber(stance);
1005 Thurallor-7095
                        self:UpdateBar();
1006 Thurallor-7095
                    end
1007 Thurallor-7095
                    dropDown:SetParent(self.slotProperties);
1008 Thurallor-7095
                    local stance = info.condArgs.stance;
1009 Thurallor-7095
                    dropDown:SetText(L:GetText("/SequenceEditor/Stance/" .. tostring(stance)));
1010 Thurallor-7095
                end
1011 20 Thurallor-7095
                if (info.condArgs.script) then
1012 47 Thurallor-7095
                    top, self.scriptBox = AddTextBox(top + 2, info.condArgs.script, Turbine.UI.Color.White, true, self.settings.sequenceEditor.scriptBoxSize);
1013 Thurallor-7095
                    self.scriptBox:SetZOrder(1);
1014 Thurallor-7095
                    self.scriptBox:SetMultiline(true);
1015 Thurallor-7095
                    self.scriptBox:SetTextAlignment(Turbine.UI.ContentAlignment.TopLeft);
1016 Thurallor-7095
                    self.scriptBox:SetFont(Turbine.UI.Lotro.Font.Verdana12);
1017 48 Thurallor-7095
                    self.scriptBox.prevText = info.condArgs.script;
1018 20 Thurallor-7095
                    self.scriptBox:SetWantsUpdates(true);
1019 47 Thurallor-7095
                    function self.scriptBox.Resized()
1020 Thurallor-7095
                        self.settings.sequenceEditor.scriptBoxSize = {self.scriptBox:GetSize()};
1021 Thurallor-7095
                        self:SaveSettings();
1022 Thurallor-7095
                        self:DisplaySlot(self.selectedSlot);
1023 Thurallor-7095
                    end
1024 20 Thurallor-7095
                    self.scriptBox.Update = function(sender)
1025 Thurallor-7095
                        local script = sender:GetText();
1026 Thurallor-7095
                        if (script ~= sender.prevText) then
1027 Thurallor-7095
                            local success, errorMsg = loadstring(script, "Slot " .. tostring(s));
1028 Thurallor-7095
                            if (success) then
1029 Thurallor-7095
                                self.scriptBox:SetBackColor(Turbine.UI.Color.Black);
1030 Thurallor-7095
                                info.condArgs.script = script;
1031 Thurallor-7095
                                self:UpdateBar();
1032 Thurallor-7095
                            else
1033 Thurallor-7095
                                self.scriptBox:SetBackColor(Turbine.UI.Color.Red);
1034 Thurallor-7095
                            end
1035 Thurallor-7095
                        end
1036 Thurallor-7095
                        sender.prevText = script;
1037 Thurallor-7095
                    end
1038 Thurallor-7095
                end
1039 Thurallor-7095
                if (info.condArgs.eqItemName) then
1040 Thurallor-7095
                    local function GetEquippableItems()
1041 Thurallor-7095
                        local hash = { [L:GetText("/SequenceEditor/AnyEqItem")] = true };
1042 Thurallor-7095
                        for container in values({ self.manager.player:GetBackpack(), self.manager.player:GetEquipment() }) do
1043 Thurallor-7095
                            for i = 1, container:GetSize(), 1 do
1044 Thurallor-7095
                                local item = container:GetItem(i);
1045 30 Thurallor-7095
                                if (item and (item:GetMaxStackSize() == 1)) then
1046 Thurallor-7095
                                    hash[item:GetName()] = true;
1047 20 Thurallor-7095
                                end
1048 Thurallor-7095
                            end
1049 Thurallor-7095
                        end
1050 Thurallor-7095
                        local items = {};
1051 Thurallor-7095
                        for key in sorted_keys(hash) do
1052 Thurallor-7095
                            table.insert(items, key);
1053 Thurallor-7095
                        end
1054 Thurallor-7095
                        return items;
1055 Thurallor-7095
                    end
1056 Thurallor-7095
                    local eqItemNames = GetEquippableItems();
1057 Thurallor-7095
                    local anyItem = L:GetText("/SequenceEditor/AnyEqItem");
1058 Thurallor-7095
                    local dropDown;
1059 Thurallor-7095
                    top, dropDown = AddDropDown(top + 2, eqItemNames);
1060 47 Thurallor-7095
                    dropDown:SetExpandedWidth(math.max(400, slotTabCardWidth - 20));
1061 20 Thurallor-7095
                    dropDown.ItemChanged = function(sender, args)
1062 Thurallor-7095
                        local anyItem = L:GetText("/SequenceEditor/AnyEqItem");
1063 Thurallor-7095
                        if (args.Text == anyItem) then
1064 Thurallor-7095
                            info.condArgs.eqItemName = "nil";
1065 Thurallor-7095
                        else
1066 Thurallor-7095
                            info.condArgs.eqItemName = "\"" .. args.Text .. "\"";
1067 Thurallor-7095
                        end
1068 Thurallor-7095
                        self:UpdateBar();
1069 Thurallor-7095
                    end
1070 Thurallor-7095
                    dropDown:SetParent(self.slotProperties);
1071 Thurallor-7095
                    if (info.condArgs.eqItemName == "nil") then
1072 Thurallor-7095
                        dropDown:SetText(anyItem);
1073 Thurallor-7095
                    else
1074 Thurallor-7095
                        local name = string.sub(info.condArgs.eqItemName, 2, -2);
1075 Thurallor-7095
                        dropDown:SetText(name);
1076 Thurallor-7095
                    end
1077 Thurallor-7095
                end
1078 Thurallor-7095
                if (info.condArgs.eqSlot) then
1079 Thurallor-7095
                    local prevContext = L:SetContext("/SequenceEditor/EquipmentSlots");
1080 Thurallor-7095
                    local eqSlotNames, localEqSlotNames, eqSlotValues = L:GetItems(), {}, {};
1081 Thurallor-7095
                    for slot in values(eqSlotNames) do
1082 Thurallor-7095
                        local text = L:GetText(slot);
1083 Thurallor-7095
                        table.insert(localEqSlotNames, text);
1084 Thurallor-7095
                        eqSlotValues[text] = tostring(Turbine.Gameplay.Equipment[slot]);
1085 Thurallor-7095
                    end
1086 Thurallor-7095
                    local anySlot = L:GetText("/SequenceEditor/AnyEqSlot");
1087 Thurallor-7095
                    eqSlotValues[anySlot] = "nil";
1088 Thurallor-7095
                    table.insert(localEqSlotNames, anySlot);
1089 Thurallor-7095
                    table.sort(localEqSlotNames);
1090 Thurallor-7095
                    local dropDown;
1091 Thurallor-7095
                    top, dropDown = AddDropDown(top + 2, localEqSlotNames);
1092 Thurallor-7095
                    dropDown.ItemChanged = function(sender, args)
1093 Thurallor-7095
                        info.condArgs.eqSlot = eqSlotValues[args.Text];
1094 Thurallor-7095
                        self:UpdateBar();
1095 Thurallor-7095
                    end
1096 Thurallor-7095
                    dropDown:SetParent(self.slotProperties);
1097 Thurallor-7095
                    if (info.condArgs.eqSlot == "nil") then
1098 Thurallor-7095
                        dropDown:SetText(anySlot);
1099 Thurallor-7095
                    else
1100 Thurallor-7095
                        local slotName = Search(Turbine.Gameplay.Equipment, tonumber(info.condArgs.eqSlot));
1101 Thurallor-7095
                        dropDown:SetText(L:GetText(slotName));
1102 Thurallor-7095
                    end
1103 Thurallor-7095
                    L:SetContext(prevContext);
1104 Thurallor-7095
                end
1105 Thurallor-7095
            end
1106 47 Thurallor-7095
 
1107 Thurallor-7095
            -- Evaluate the condition and display the current value
1108 Thurallor-7095
            local function GetValueStr()
1109 Thurallor-7095
                local sequence = self.bar.sequence;
1110 Thurallor-7095
                local slot = sequence:GetSlot(sequence:GetNewIndex(s));
1111 49 Thurallor-7095
                if (slot and slot.condFunc) then
1112 146 Thurallor-7095
                    local text;
1113 Thurallor-7095
                    local success, value = pcall(slot.condFunc, slot, self.manager.player);
1114 Thurallor-7095
                    if (success) then
1115 Thurallor-7095
                        if (value) then
1116 Thurallor-7095
                            text = L:GetText("/SequenceEditor/True");
1117 Thurallor-7095
                        else
1118 Thurallor-7095
                            text = L:GetText("/SequenceEditor/False");
1119 Thurallor-7095
                        end
1120 Thurallor-7095
                    else
1121 Thurallor-7095
                        text = "Error: " .. value;
1122 49 Thurallor-7095
                    end
1123 Thurallor-7095
                    return "(" .. text .. ")";
1124 47 Thurallor-7095
                end
1125 Thurallor-7095
            end
1126 Thurallor-7095
            if (info.condArgs and info.condArgs.script) then
1127 146 Thurallor-7095
                top, self.playButton = AddButton(top, 40, "â–º", Turbine.UI.Lotro.Font.Arial12);
1128 47 Thurallor-7095
                top, label = AddLabel(top, "", Turbine.UI.Color.Goldenrod);
1129 146 Thurallor-7095
                AddCallback(self.playButton, "Click", function()
1130 47 Thurallor-7095
                    label:SetText(GetValueStr());
1131 Thurallor-7095
                end);
1132 146 Thurallor-7095
                AddCallback(self.playButton, "MouseLeave", function()
1133 47 Thurallor-7095
                    label:SetText("");
1134 Thurallor-7095
                end);
1135 Thurallor-7095
            else
1136 Thurallor-7095
                top, label = AddLabel(top, "", Turbine.UI.Color.Goldenrod);
1137 Thurallor-7095
                label.Update = function()
1138 Thurallor-7095
                    label:SetText(GetValueStr());
1139 Thurallor-7095
                end
1140 Thurallor-7095
                label:SetWantsUpdates(true);
1141 Thurallor-7095
            end
1142 146 Thurallor-7095
 
1143 Thurallor-7095
        elseif (info.type == "LuaScript") then
1144 Thurallor-7095
 
1145 Thurallor-7095
            -- Display script editor box
1146 Thurallor-7095
            top, self.scriptBox = AddTextBox(top + 2, info.action, Turbine.UI.Color.White, true, self.settings.sequenceEditor.scriptBoxSize);
1147 Thurallor-7095
            self.scriptBox:SetZOrder(1);
1148 Thurallor-7095
            self.scriptBox:SetMultiline(true);
1149 Thurallor-7095
            self.scriptBox:SetTextAlignment(Turbine.UI.ContentAlignment.TopLeft);
1150 Thurallor-7095
            self.scriptBox:SetFont(Turbine.UI.Lotro.Font.Verdana12);
1151 Thurallor-7095
            self.scriptBox.prevText = info.action;
1152 Thurallor-7095
            self.scriptBox:SetWantsUpdates(true);
1153 Thurallor-7095
            function self.scriptBox.Resized()
1154 Thurallor-7095
                self.settings.sequenceEditor.scriptBoxSize = {self.scriptBox:GetSize()};
1155 Thurallor-7095
                self:SaveSettings();
1156 Thurallor-7095
                self:DisplaySlot(self.selectedSlot);
1157 Thurallor-7095
            end
1158 Thurallor-7095
            self.scriptBox.Update = function(sender)
1159 Thurallor-7095
                local script = sender:GetText();
1160 Thurallor-7095
                if (script ~= sender.prevText) then
1161 Thurallor-7095
                    local success, errorMsg = loadstring(script, "Slot " .. tostring(s));
1162 Thurallor-7095
                    if (success) then
1163 Thurallor-7095
                        self.scriptBox:SetBackColor(Turbine.UI.Color.Black);
1164 Thurallor-7095
                        self.playButton:SetEnabled(true);
1165 Thurallor-7095
                        info.action = script;
1166 Thurallor-7095
                        self:UpdateBar();
1167 Thurallor-7095
                    else
1168 Thurallor-7095
                        self.scriptBox:SetBackColor(Turbine.UI.Color.Red);
1169 Thurallor-7095
                        self.playButton:SetEnabled(false);
1170 Thurallor-7095
                    end
1171 Thurallor-7095
                end
1172 Thurallor-7095
                sender.prevText = script;
1173 Thurallor-7095
            end
1174 Thurallor-7095
 
1175 Thurallor-7095
            -- Create a button for executing the script
1176 Thurallor-7095
            top, self.playButton = AddButton(top, 40, "â–º", Turbine.UI.Lotro.Font.Arial12);
1177 Thurallor-7095
            top, label = AddLabel(top, "", Turbine.UI.Color.Goldenrod);
1178 Thurallor-7095
            AddCallback(self.playButton, "Click", function()
1179 Thurallor-7095
                local script = self.scriptBox:GetText();
1180 Thurallor-7095
                local success, result = pcall(loadstring(script, "Slot " .. tostring(s)));
1181 Thurallor-7095
                if (success) then
1182 Thurallor-7095
                    if (type(result) == "string") then
1183 Thurallor-7095
                        result = "\"" .. result .. "\"";
1184 Thurallor-7095
                    else
1185 Thurallor-7095
                        result = tostring(result); -- or "nil";
1186 Thurallor-7095
                    end
1187 Thurallor-7095
                    label:SetText("returned: " .. result);
1188 Thurallor-7095
                else
1189 Thurallor-7095
                    label:SetText("error: " .. result);
1190 Thurallor-7095
                end
1191 Thurallor-7095
            end);
1192 Thurallor-7095
            AddCallback(self.playButton, "MouseLeave", function()
1193 Thurallor-7095
                label:SetText("");
1194 Thurallor-7095
            end);
1195 Thurallor-7095
 
1196 16 Thurallor-7095
        elseif (info.type == "Include") then
1197 Thurallor-7095
            top = top + 16; -- skip a line
1198 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/OtherSequence") .. ":", Turbine.UI.Color.Goldenrod);
1199 Thurallor-7095
            local function GetObjectTree()
1200 Thurallor-7095
                -- Get a list of all bar IDs.
1201 Thurallor-7095
                local objectIDs = self.manager:FindAllDescendentIDs(nil, true, false);
1202 Thurallor-7095
 
1203 Thurallor-7095
                -- Including self doesn't make sense, so prevent that.
1204 Thurallor-7095
                local foundSelf;
1205 Thurallor-7095
                for o = 1, #objectIDs, 1 do
1206 Thurallor-7095
                    local object = self.manager:GetObject(objectIDs[o]);
1207 Thurallor-7095
                    if (object == self.bar) then
1208 Thurallor-7095
                        foundSelf = o;
1209 Thurallor-7095
                    end
1210 Thurallor-7095
                end
1211 Thurallor-7095
                if (foundSelf) then
1212 Thurallor-7095
                    table.remove(objectIDs, foundSelf);
1213 Thurallor-7095
                end
1214 Thurallor-7095
 
1215 Thurallor-7095
                -- Add nonempty groups.
1216 17 Thurallor-7095
                local groupIDs = {};
1217 Thurallor-7095
                for o = 1, #objectIDs, 1 do
1218 Thurallor-7095
                    local objectID = objectIDs[o];
1219 Thurallor-7095
                    local object = self.manager:GetObject(objectID);
1220 Thurallor-7095
                    while (object.parent) do
1221 Thurallor-7095
                        object = object.parent;
1222 Thurallor-7095
                        objectID = object:GetID();
1223 Thurallor-7095
                        if (objectID) then
1224 Thurallor-7095
                            groupIDs[objectID] = 1;
1225 16 Thurallor-7095
                        end
1226 Thurallor-7095
                    end
1227 17 Thurallor-7095
                end
1228 Thurallor-7095
                for groupID in keys(groupIDs) do
1229 Thurallor-7095
                    table.insert(objectIDs, groupID);
1230 Thurallor-7095
                end
1231 16 Thurallor-7095
 
1232 Thurallor-7095
                -- Create item list for PullDownMenu.
1233 Thurallor-7095
                local items = {};
1234 Thurallor-7095
                for o = 1, #objectIDs, 1 do
1235 Thurallor-7095
                    local objectID = objectIDs[o];
1236 Thurallor-7095
                    local object = self.manager:GetObject(objectID);
1237 Thurallor-7095
                    local parentID = nil;
1238 Thurallor-7095
                    if (object.parent) then
1239 Thurallor-7095
                        parentID = object.parent:GetID();
1240 Thurallor-7095
                    end
1241 Thurallor-7095
                    table.insert(items, { objectID, object:GetName(), parentID });
1242 Thurallor-7095
                end
1243 Thurallor-7095
                return items;
1244 Thurallor-7095
            end
1245 Thurallor-7095
            local pullDown;
1246 Thurallor-7095
            top, pullDown = AddPullDown(top, GetObjectTree(), info.include);
1247 Thurallor-7095
            pullDown.SelectionChanged = function(sender, id)
1248 Thurallor-7095
                info.include = id;
1249 Thurallor-7095
                self:UpdateBar();
1250 20 Thurallor-7095
                self:SelectSlot(s);
1251 16 Thurallor-7095
            end
1252 20 Thurallor-7095
            AddCallback(pullDown, "MouseClick", function(sender, args)
1253 Thurallor-7095
                -- Right-click displays the bar menu.
1254 Thurallor-7095
                if (args.Button == Turbine.UI.MouseButton.Right) then
1255 Thurallor-7095
                    if (info.include) then
1256 Thurallor-7095
                        local bar = self.manager.objects[info.include];
1257 Thurallor-7095
                        if (bar) then
1258 Thurallor-7095
                            bar:ShowSettingsMenu();
1259 Thurallor-7095
                        end
1260 Thurallor-7095
                    end
1261 Thurallor-7095
                end
1262 Thurallor-7095
            end);
1263 6 Thurallor-7095
 
1264 20 Thurallor-7095
            -- Add the "unlink" button if a sequence is selected.
1265 Thurallor-7095
            if (info.include) then
1266 Thurallor-7095
                local button;
1267 Thurallor-7095
                local text, width = L:GetText("/SequenceEditor/Unlink"), L:GetNumber("/SequenceEditor/UnlinkButtonWidth");
1268 Thurallor-7095
                top, button = AddButton(top, width, text);
1269 Thurallor-7095
                AddCallback(button, "Click", function()
1270 Thurallor-7095
                    self:UnlinkIncludedSequence(s);
1271 Thurallor-7095
                end);
1272 Thurallor-7095
            end
1273 Thurallor-7095
        end
1274 Thurallor-7095
 
1275 16 Thurallor-7095
        -- Allow the user to specify whether activation is click-based or automatic.
1276 Thurallor-7095
        if (info.type ~= "Include") then
1277 6 Thurallor-7095
            top = top + 16; -- skip a line
1278 Thurallor-7095
            top = AddLabel(top, L:GetText("/SequenceEditor/Activation") .. ":", Turbine.UI.Color.Goldenrod);
1279 Thurallor-7095
            local button1, button2;
1280 Thurallor-7095
            top, button1 = AddRadioButton(top, L:GetText("/SequenceEditor/WithLeftClick"), Turbine.UI.Color.DarkGoldenrod, (not info.automatic));
1281 Thurallor-7095
            top, button2 = AddRadioButton(top, L:GetText("/SequenceEditor/Automatic"), Turbine.UI.Color.DarkGoldenrod, info.automatic);
1282 Thurallor-7095
            Thurallor.UI.RadioButton.LinkPeers({button1, button2});
1283 Thurallor-7095
            button1.Clicked = function()
1284 Thurallor-7095
                info.automatic = nil;
1285 16 Thurallor-7095
                self:UpdateBar();
1286 6 Thurallor-7095
            end
1287 Thurallor-7095
            button2.Clicked = function()
1288 Thurallor-7095
                info.automatic = true;
1289 16 Thurallor-7095
                self:UpdateBar();
1290 6 Thurallor-7095
            end
1291 2 Thurallor-7095
        end
1292 Thurallor-7095
    end
1293 Thurallor-7095
 
1294 136 Thurallor-7095
    -- Allow the user to specify that advancement should not occur until there is a target
1295 Thurallor-7095
    if ((info.type == Turbine.UI.Lotro.ShortcutType.Skill) or (info.type == "SelectTarget")) then
1296 Thurallor-7095
        top = top + 16; -- skip a line
1297 Thurallor-7095
        local checkbox;
1298 Thurallor-7095
        top, checkbox = AddCheckBox(top, L:GetText("/SequenceEditor/RequireTarget"), Turbine.UI.Color.Goldenrod, info.requireTarget);
1299 Thurallor-7095
 
1300 Thurallor-7095
        checkbox.CheckedChanged = function(chkbx)
1301 Thurallor-7095
            if (chkbx:IsChecked()) then
1302 Thurallor-7095
                info.requireTarget = true;
1303 Thurallor-7095
            else
1304 Thurallor-7095
                info.requireTarget = nil;
1305 Thurallor-7095
            end
1306 Thurallor-7095
            self:UpdateBar();
1307 Thurallor-7095
        end
1308 Thurallor-7095
    end
1309 Thurallor-7095
 
1310 34 Thurallor-7095
    -- Allow the user to modify slot appearance (text, icon)
1311 15 Thurallor-7095
    top = top + 16; -- skip a line
1312 34 Thurallor-7095
    local button;
1313 Thurallor-7095
    top, button = AddSection(top, L:GetText("/SequenceEditor/Appearance"), Turbine.UI.Color.Goldenrod, self.appearanceExpanded);
1314 Thurallor-7095
    function button.ExpandedChanged(sender, expanded)
1315 Thurallor-7095
        self.appearanceExpanded = expanded;
1316 Thurallor-7095
        self:DisplaySlot(self.selectedSlot);
1317 Thurallor-7095
    end
1318 Thurallor-7095
 
1319 Thurallor-7095
    if (self.appearanceExpanded) then
1320 Thurallor-7095
 
1321 Thurallor-7095
        -- Allow the user to optionally overlay some text
1322 Thurallor-7095
        top = top + 16; -- skip a line
1323 Thurallor-7095
        top = AddLabel(top, L:GetText("/SequenceEditor/TextOverlay") .. ":", Turbine.UI.Color.Goldenrod);
1324 Thurallor-7095
        local textBox;
1325 Thurallor-7095
        top, textBox = AddTextBox(top, info.textOverlay, Turbine.UI.Color.White);
1326 Thurallor-7095
        textBox:SetFont(Turbine.UI.Lotro.Font.Verdana12);
1327 Thurallor-7095
        textBox.TextChanged = function(sender, args)
1328 Thurallor-7095
            local text = sender:GetText();
1329 Thurallor-7095
            if (text == "") then
1330 Thurallor-7095
                text = nil;
1331 Thurallor-7095
            end
1332 Thurallor-7095
            info.textOverlay = text;
1333 Thurallor-7095
            UpdateIcon();
1334 Thurallor-7095
            self:UpdateBar();
1335 7 Thurallor-7095
        end
1336 34 Thurallor-7095
 
1337 Thurallor-7095
        -- Allow the user to optionally change the icon
1338 Thurallor-7095
        top = top + 16; -- skip a line
1339 Thurallor-7095
        top = AddLabel(top, L:GetText("/SequenceEditor/ChangeIcon") .. ":", Turbine.UI.Color.Goldenrod);
1340 Thurallor-7095
        local button1, button2, slider2, button3, slider3, button4, textbox;
1341 Thurallor-7095
        top, button1 = AddRadioButton(top, L:GetText("/SequenceEditor/DefaultIcon"), Turbine.UI.Color.DarkGoldenrod);
1342 Thurallor-7095
        top, button2 = AddRadioButton(top, L:GetText("/SequenceEditor/BlankIcon"), Turbine.UI.Color.DarkGoldenrod);
1343 Thurallor-7095
        top, slider2 = AddSlider(top, 1, #resources.BlankIcons, 1);
1344 Thurallor-7095
        slider2:SetLeft(12);
1345 Thurallor-7095
        slider2:SetWidth(slider2:GetWidth() - 12);
1346 Thurallor-7095
        top, button3 = AddRadioButton(top, L:GetText("/SequenceEditor/SkillIcon"), Turbine.UI.Color.DarkGoldenrod);
1347 Thurallor-7095
        local skillsInfo = Thurallor.Utils.Watcher.GetSkillsInfo();
1348 Thurallor-7095
        local gambitsInfo = Thurallor.Utils.Watcher.GetGambitsInfo();
1349 Thurallor-7095
        self.skillIcons = {};
1350 Thurallor-7095
        for id in sorted_keys(skillsInfo.byIcon) do
1351 Thurallor-7095
            table.insert(self.skillIcons, id);
1352 Thurallor-7095
        end
1353 Thurallor-7095
        for id in sorted_keys(gambitsInfo.byIcon) do
1354 Thurallor-7095
            table.insert(self.skillIcons, id);
1355 Thurallor-7095
        end
1356 Thurallor-7095
        top, slider3 = AddSlider(top, 1, #self.skillIcons, 1);
1357 Thurallor-7095
        slider3:SetLeft(12);
1358 Thurallor-7095
        slider3:SetWidth(slider3:GetWidth() - 12);
1359 Thurallor-7095
        top, button4 = AddRadioButton(top, L:GetText("/SequenceEditor/SpecificIconID"), Turbine.UI.Color.DarkGoldenrod);
1360 Thurallor-7095
        top, textBox = AddTextBox(top, "", Turbine.UI.Color.White);
1361 47 Thurallor-7095
        textBox:SetFont(Turbine.UI.Lotro.Font.Verdana12);
1362 34 Thurallor-7095
        textBox:SetLeft(12);
1363 Thurallor-7095
        textBox:SetWidth(textBox:GetWidth() - 12);
1364 Thurallor-7095
        if (info.altIcon == nil) then
1365 Thurallor-7095
            button1:SetChecked(true);
1366 Thurallor-7095
        else
1367 Thurallor-7095
            local blankIcon = Search(resources.BlankIcons, info.altIcon);
1368 Thurallor-7095
            if (blankIcon) then
1369 Thurallor-7095
                button2:SetChecked(true);
1370 Thurallor-7095
                slider2:SetValue(blankIcon);
1371 Thurallor-7095
            else
1372 Thurallor-7095
                local skillIcon = Search(self.skillIcons, info.altIcon);
1373 Thurallor-7095
                if (skillIcon) then
1374 Thurallor-7095
                    button3:SetChecked(true);
1375 Thurallor-7095
                    slider3:SetValue(skillIcon);
1376 Thurallor-7095
                else
1377 Thurallor-7095
                    button4:SetChecked(true);
1378 Thurallor-7095
                end
1379 Thurallor-7095
            end
1380 Thurallor-7095
        end
1381 Thurallor-7095
        local function UpdateIconID()
1382 Thurallor-7095
            local id = info.altIcon;
1383 Thurallor-7095
            if (id == nil) then
1384 Thurallor-7095
                id = info.background;
1385 Thurallor-7095
            end
1386 Thurallor-7095
            if (type(id) == "number") then
1387 Thurallor-7095
                textBox:SetText(string.format("0x%8.8X", id));
1388 Thurallor-7095
            elseif (type(id) == "string") then
1389 Thurallor-7095
                textBox:SetText(id);
1390 Thurallor-7095
            else
1391 Thurallor-7095
                -- Get icon ID from quickslot
1392 Thurallor-7095
 
1393 Thurallor-7095
            end
1394 Thurallor-7095
        end
1395 Thurallor-7095
        UpdateIconID();
1396 Thurallor-7095
        Thurallor.UI.RadioButton.LinkPeers({button1, button2, button3, button4});
1397 Thurallor-7095
        function button1.Clicked()
1398 Thurallor-7095
            info.altIcon = nil;
1399 Thurallor-7095
            UpdateIcon();
1400 Thurallor-7095
            UpdateIconID();
1401 Thurallor-7095
            self:UpdateBar();
1402 Thurallor-7095
        end
1403 Thurallor-7095
        function button2.Clicked()
1404 Thurallor-7095
            slider2:ValueChanged();
1405 Thurallor-7095
        end
1406 Thurallor-7095
        function button3.Clicked()
1407 Thurallor-7095
            slider3:ValueChanged();
1408 Thurallor-7095
        end
1409 Thurallor-7095
        function button4.Clicked()
1410 Thurallor-7095
            textBox:TextChanged();
1411 Thurallor-7095
        end
1412 Thurallor-7095
        slider2.ValueChanged = function(sender)
1413 Thurallor-7095
            if (not button2:IsChecked()) then
1414 Thurallor-7095
                button2:MouseClick();
1415 Thurallor-7095
                return;
1416 Thurallor-7095
            end
1417 Thurallor-7095
            info.altIcon = resources.BlankIcons[sender:GetValue()];
1418 Thurallor-7095
            UpdateIcon();
1419 Thurallor-7095
            UpdateIconID();
1420 Thurallor-7095
            self:UpdateBar();
1421 Thurallor-7095
            self.settings.sequenceEditor.defaultIcon = info.altIcon;
1422 Thurallor-7095
        end
1423 Thurallor-7095
        slider3.ValueChanged = function(sender)
1424 Thurallor-7095
            if (not button3:IsChecked()) then
1425 Thurallor-7095
                button3:MouseClick();
1426 Thurallor-7095
                return;
1427 Thurallor-7095
            end
1428 Thurallor-7095
            info.altIcon = self.skillIcons[sender:GetValue()];
1429 Thurallor-7095
            UpdateIcon();
1430 Thurallor-7095
            UpdateIconID();
1431 Thurallor-7095
            self:UpdateBar();
1432 Thurallor-7095
            self.settings.sequenceEditor.defaultIcon = info.altIcon;
1433 Thurallor-7095
        end
1434 Thurallor-7095
        function textBox.FocusGained()
1435 Thurallor-7095
            button4:MouseClick();
1436 Thurallor-7095
        end
1437 Thurallor-7095
        textBox.TextChanged = function(sender)
1438 Thurallor-7095
            if (not button4:IsChecked()) then
1439 Thurallor-7095
                return;
1440 Thurallor-7095
            end
1441 Thurallor-7095
            local id = sender:GetText();
1442 Thurallor-7095
            if (tonumber(id) ~= nil) then
1443 Thurallor-7095
                id = tonumber(id);
1444 Thurallor-7095
            end
1445 Thurallor-7095
            local valid = pcall(GetAssetSize, id);
1446 Thurallor-7095
            if (valid) then
1447 Thurallor-7095
                textBox:SetForeColor(Turbine.UI.Color.White);
1448 Thurallor-7095
                info.altIcon = id;
1449 Thurallor-7095
                UpdateIcon();
1450 Thurallor-7095
                self:UpdateBar();
1451 Thurallor-7095
            else
1452 Thurallor-7095
                textBox:SetForeColor(Turbine.UI.Color.Red);
1453 Thurallor-7095
            end
1454 Thurallor-7095
        end
1455 2 Thurallor-7095
    end
1456 Thurallor-7095
 
1457 Thurallor-7095
    self.slotProperties:SetHeight(top);
1458 15 Thurallor-7095
    self:SetMinimumHeight(top + 110);
1459 2 Thurallor-7095
end
1460 Thurallor-7095
 
1461 13 Thurallor-7095
function SequenceEditor:FindSlotAtPosition(x, y, drawCaret)
1462 7 Thurallor-7095
    local originX, originY = self.slotPanel:GetParent():PointToScreen(self.slotPanel:GetPosition());
1463 13 Thurallor-7095
    local relX, relY = x - originX, y - originY + 3;
1464 Thurallor-7095
    local posX, posY = 1 + math.floor(relX / self.slotSize + 0.5), 1 + math.floor(relY / self.slotSize);
1465 7 Thurallor-7095
    local s = nil;
1466 13 Thurallor-7095
    if ((posX >= 1) and (posX <= self.slotsWide + 1) and (posY >= 1) and (posY <= self.slotsHigh)) then
1467 7 Thurallor-7095
        s = ((posY - 1) * self.slotsWide) + posX;
1468 Thurallor-7095
    end
1469 13 Thurallor-7095
    if ((posX == self.slotsWide + 1) and (posY == self.slotsHigh)) then
1470 Thurallor-7095
        s = nil;
1471 Thurallor-7095
    end
1472 7 Thurallor-7095
 
1473 Thurallor-7095
    -- Update caret position.
1474 Thurallor-7095
    if ((not drawCaret) or (not s)) then
1475 Thurallor-7095
        -- Hide carets in all Sequence Editors
1476 Thurallor-7095
        for editor in keys(SequenceEditor.instances) do
1477 Thurallor-7095
            if (editor.caret) then
1478 Thurallor-7095
                editor.caret:SetParent(nil);
1479 Thurallor-7095
                editor.caret = nil;
1480 Thurallor-7095
            end
1481 Thurallor-7095
        end
1482 Thurallor-7095
    else
1483 Thurallor-7095
        if (not self.caret) then
1484 Thurallor-7095
            self.caret = Turbine.UI.Control();
1485 Thurallor-7095
            self.caret:SetParent(self.slotPanel);
1486 Thurallor-7095
            self.caret:SetBackground(resources.Icon.Caret);
1487 Thurallor-7095
            self.caret:SetBlendMode(Turbine.UI.BlendMode.AlphaBlend);
1488 Thurallor-7095
            self.caret:SetSize(3, 36)
1489 Thurallor-7095
        end
1490 Thurallor-7095
        self.caret:SetPosition((posX - 1) * self.slotSize, (posY - 1) * self.slotSize);
1491 Thurallor-7095
    end
1492 Thurallor-7095
 
1493 Thurallor-7095
    return s;
1494 Thurallor-7095
end
1495 Thurallor-7095
 
1496 13 Thurallor-7095
function SequenceEditor:FindForeignSlotAtPosition(x, y, drawCaret)
1497 7 Thurallor-7095
 
1498 Thurallor-7095
    -- Find the frontmost SequenceEditor under the mouse cursor
1499 Thurallor-7095
    local frontEditor = self;
1500 Thurallor-7095
    local maxZ = -2147483648;
1501 Thurallor-7095
    for editor in keys(SequenceEditor.instances) do
1502 Thurallor-7095
        if (editor ~= self) then
1503 Thurallor-7095
            local left, top = editor:GetPosition();
1504 Thurallor-7095
            local width, height = editor:GetSize();
1505 13 Thurallor-7095
            if ((x >= left) and (x <= left + width) and (y >= top) and (y <= top + height)) then
1506 7 Thurallor-7095
                if (editor:GetZOrder() >= maxZ) then
1507 Thurallor-7095
                    frontEditor = editor;
1508 Thurallor-7095
                    maxZ = editor:GetZOrder();
1509 Thurallor-7095
                end
1510 Thurallor-7095
            end
1511 Thurallor-7095
        end
1512 Thurallor-7095
    end
1513 Thurallor-7095
 
1514 13 Thurallor-7095
    return frontEditor, frontEditor:FindSlotAtPosition(x, y, drawCaret);
1515 7 Thurallor-7095
end
1516 Thurallor-7095
 
1517 13 Thurallor-7095
function SequenceEditor:BuildSlot(slot, parent, object, left, top)
1518 Thurallor-7095
--Puts("BuildSlot(" .. tostring(slot) .. ", " .. tostring(parent) .. ", " .. tostring(object) .. ", " .. tostring(left) .. ", " .. tostring(top));
1519 2 Thurallor-7095
 
1520 Thurallor-7095
    -- Get slot info, or initialize to default
1521 13 Thurallor-7095
    local info = self.settings.sequenceItemInfo[slot];
1522 Thurallor-7095
    if (object) then
1523 Thurallor-7095
        -- Reuse the existing object
1524 Thurallor-7095
        object:SetParent(parent);
1525 Thurallor-7095
        object:SetInfo(info);
1526 Thurallor-7095
        object:SetPosition(left, top);
1527 Thurallor-7095
        object:SetNumLabel(slot);
1528 Thurallor-7095
        return object;
1529 2 Thurallor-7095
    end
1530 Thurallor-7095
 
1531 13 Thurallor-7095
    -- Need to create a new object
1532 Thurallor-7095
    object = Slot(info);
1533 Thurallor-7095
    object:SetPosition(left, top);
1534 Thurallor-7095
    object:SetNumLabel(slot);
1535 2 Thurallor-7095
    object:SetParent(parent);
1536 13 Thurallor-7095
    object:SetActionEnabled(false);
1537 Thurallor-7095
    object:SetAllowDrop(true);
1538 Thurallor-7095
    object:SetDraggable(true);
1539 2 Thurallor-7095
 
1540 7 Thurallor-7095
    -- Desired mouse behaviors:
1541 Thurallor-7095
    --   Left-click selects the slot and shows its properties in the "Slot" tab.
1542 Thurallor-7095
    --   Right-click displays the settings menu.
1543 Thurallor-7095
    --   Left-button-drag initiates a drag-and-drop (move) operation.
1544 2 Thurallor-7095
 
1545 13 Thurallor-7095
    object.ShortcutChanged = function(sender, shortcutType, shortcutData)
1546 Thurallor-7095
        local s = sender:GetNumLabel();
1547 2 Thurallor-7095
        self:ExtendSequenceTo(s);
1548 13 Thurallor-7095
        local info = sender:GetInfo();
1549 Thurallor-7095
        self.settings.sequenceItemInfo[s] = info;
1550 Thurallor-7095
 
1551 Thurallor-7095
        if (shortcutType == Turbine.UI.Lotro.ShortcutType.Alias) then
1552 7 Thurallor-7095
            info.textOverlay = string.gsub(info.Data, "^/", "");
1553 Thurallor-7095
            info.textOverlay = string.gsub(info.textOverlay, "%s.*$", "");
1554 Thurallor-7095
            info.background = self.settings.sequenceEditor.defaultIcon;
1555 13 Thurallor-7095
            sender:SetInfo(info);
1556 7 Thurallor-7095
        end
1557 13 Thurallor-7095
 
1558 16 Thurallor-7095
        self:UpdateBar();
1559 122 Thurallor-7095
        self:Redraw();
1560 2 Thurallor-7095
        self:SelectSlot(s);
1561 Thurallor-7095
    end
1562 Thurallor-7095
 
1563 13 Thurallor-7095
    object.MouseClick = function(sender, args)
1564 2 Thurallor-7095
        -- Left-click selects the slot and shows its properties in the "Slot" tab.
1565 Thurallor-7095
        if (args.Button == Turbine.UI.MouseButton.Left) then
1566 13 Thurallor-7095
            self:SelectSlot(sender:GetNumLabel());
1567 2 Thurallor-7095
 
1568 Thurallor-7095
        -- Right-click displays the settings menu.
1569 Thurallor-7095
        elseif (args.Button == Turbine.UI.MouseButton.Right) then
1570 13 Thurallor-7095
            self.clickedItem = sender:GetNumLabel();
1571 2 Thurallor-7095
            self:ShowContextMenu();
1572 Thurallor-7095
        end
1573 Thurallor-7095
    end
1574 Thurallor-7095
 
1575 13 Thurallor-7095
    object.DropPositionValid = function(sender, left, top)
1576 Thurallor-7095
        local s = sender:GetNumLabel();
1577 Thurallor-7095
 
1578 Thurallor-7095
        -- Draw a "caret" showing where the slot will be inserted.
1579 Thurallor-7095
        local editor = self;
1580 Thurallor-7095
        local newSlot = self:FindSlotAtPosition(left, top, true);
1581 Thurallor-7095
        if (not newSlot) then
1582 Thurallor-7095
            editor, newSlot = self:FindForeignSlotAtPosition(left, top, true);
1583 7 Thurallor-7095
        end
1584 13 Thurallor-7095
        if ((editor == self) and ((newSlot == s) or (newSlot == s + 1))) then
1585 Thurallor-7095
            self:FindSlotAtPosition(0, 0, false); -- hide caret if returning to the same position
1586 Thurallor-7095
        end
1587 Thurallor-7095
        return newSlot; -- if newSlot is nil, a red "X" will be shown
1588 7 Thurallor-7095
    end
1589 Thurallor-7095
 
1590 13 Thurallor-7095
    object.DragDropComplete = function(sender, left, top)
1591 Thurallor-7095
        local s = sender:GetNumLabel();
1592 2 Thurallor-7095
 
1593 13 Thurallor-7095
        -- Select destination slot.  Hide the caret.
1594 Thurallor-7095
        local editor = self;
1595 Thurallor-7095
        local newSlot = self:FindSlotAtPosition(left, top, false);
1596 Thurallor-7095
        if (not newSlot) then
1597 Thurallor-7095
            editor, newSlot = self:FindForeignSlotAtPosition(left, top, false);
1598 Thurallor-7095
        end
1599 Thurallor-7095
 
1600 Thurallor-7095
        -- Do the move operation, and redraw.
1601 Thurallor-7095
        if (newSlot and (editor ~= self)) then
1602 Thurallor-7095
            editor:InsertSlot(newSlot, self.settings.sequenceItemInfo[s]);
1603 Thurallor-7095
            self:DeleteSlot(s);
1604 Thurallor-7095
        elseif (newSlot and (newSlot ~= s) and (newSlot ~= s + 1)) then
1605 Thurallor-7095
            self:MoveSlot(s, newSlot);
1606 Thurallor-7095
        else
1607 Thurallor-7095
            self:Redraw();
1608 Thurallor-7095
        end
1609 Thurallor-7095
    end
1610 Thurallor-7095
 
1611 2 Thurallor-7095
    return object;
1612 Thurallor-7095
end
1613 Thurallor-7095
 
1614 7 Thurallor-7095
function SequenceEditor:RebuildSlot(s, x, y, alreadyDisplaying)
1615 2 Thurallor-7095
    local oldObject = self.sequenceItems[s];
1616 Thurallor-7095
 
1617 Thurallor-7095
    -- If x and y aren't specified, then presumably the object has already been positioned previously
1618 Thurallor-7095
    if (x == nil) then
1619 Thurallor-7095
        x = oldObject.x;
1620 Thurallor-7095
        y = oldObject.y;
1621 Thurallor-7095
    end
1622 Thurallor-7095
    local left, top = self:GetSlotPosition(x, y);
1623 Thurallor-7095
 
1624 Thurallor-7095
    local newObject = self:BuildSlot(s, self.slotPanel, oldObject, left, top);
1625 Thurallor-7095
    newObject.x = x;
1626 Thurallor-7095
    newObject.y = y;
1627 Thurallor-7095
    self.sequenceItems[s] = newObject;
1628 Thurallor-7095
 
1629 7 Thurallor-7095
    if (not alreadyDisplaying and (self.selectedSlot == s)) then
1630 2 Thurallor-7095
        self:DisplaySlot(s);
1631 Thurallor-7095
    end
1632 Thurallor-7095
end
1633 Thurallor-7095
 
1634 Thurallor-7095
function SequenceEditor:SelectSlot(s)
1635 13 Thurallor-7095
--Puts("SelectSlot(" .. tostring(s) .. "): self.selectedSlot = " .. tostring(self.selectedSlot));
1636 2 Thurallor-7095
    if (self.selectedSlot) then
1637 13 Thurallor-7095
        local object = self.sequenceItems[self.selectedSlot];
1638 Thurallor-7095
        object:SetSelected(false);
1639 Thurallor-7095
        local info = self.settings.sequenceItemInfo[self.selectedSlot];
1640 Thurallor-7095
        if (info and (info.class == "Turbine.UI.Lotro.Quickslot") and (not info.type)) then
1641 2 Thurallor-7095
            -- Delete empty shortcut
1642 13 Thurallor-7095
            info.class = nil;
1643 2 Thurallor-7095
        end
1644 Thurallor-7095
    end
1645 16 Thurallor-7095
    for o = 1, #self.relatedSlots, 1 do
1646 Thurallor-7095
        local otherSlot, otherObject = unpack(self.relatedSlots[o]);
1647 Thurallor-7095
        otherObject:SetSelected(nil);
1648 Thurallor-7095
        self.relatedSlots[o] = nil;
1649 Thurallor-7095
    end
1650 2 Thurallor-7095
    if (s ~= nil) then
1651 7 Thurallor-7095
        local info = self.settings.sequenceItemInfo[s];
1652 13 Thurallor-7095
        if ((not info) or (not info.class)) then
1653 7 Thurallor-7095
            s = nil;
1654 Thurallor-7095
        else
1655 13 Thurallor-7095
            local object = self.sequenceItems[s];
1656 Thurallor-7095
            object:SetSelected(true);
1657 16 Thurallor-7095
            local sequence = self.bar:GetSequence();
1658 Thurallor-7095
            local barObject = sequence:GetSlot(sequence:GetNewIndex(s));
1659 Thurallor-7095
            if (barObject) then
1660 Thurallor-7095
                for otherSlot, _ in pairs({ifSlot = 1; elseSlot = 1; endIfSlot = 1}) do
1661 Thurallor-7095
                    if (barObject[otherSlot]) then
1662 Thurallor-7095
                        local otherObject = self.sequenceItems[sequence:GetOldIndex(barObject[otherSlot])];
1663 Thurallor-7095
                        otherObject:SetSelected(true, Turbine.UI.Color.Yellow);
1664 Thurallor-7095
                        table.insert(self.relatedSlots, {otherSlot, otherObject});
1665 Thurallor-7095
                    end
1666 Thurallor-7095
                end
1667 Thurallor-7095
            end
1668 7 Thurallor-7095
        end
1669 2 Thurallor-7095
    end
1670 Thurallor-7095
    self.selectedSlot = s;
1671 Thurallor-7095
    self:DisplaySlot(s);
1672 Thurallor-7095
end
1673 Thurallor-7095
 
1674 Thurallor-7095
function SequenceEditor:GetSlotPosition(x, y)
1675 Thurallor-7095
    local left = (x - 1) * (self.settings.slotSize + self.settings.slotSpacing) - self.settings.slotSpacing;
1676 Thurallor-7095
    local top = (y - 1) * (self.settings.slotSize + self.settings.slotSpacing) - self.settings.slotSpacing;
1677 Thurallor-7095
    return left, top;
1678 Thurallor-7095
end
1679 Thurallor-7095
 
1680 Thurallor-7095
function SequenceEditor:Closing()
1681 7 Thurallor-7095
    SequenceEditor.instances[self] = nil;
1682 2 Thurallor-7095
    self:DeleteEmptyTrailingSlots();
1683 16 Thurallor-7095
    self:UpdateBar();
1684 20 Thurallor-7095
    if (self.ItemMovedCallback) then
1685 Thurallor-7095
        RemoveCallback(Thurallor.Utils.Watcher, "ItemMoved", self.ItemMovedCallback);
1686 Thurallor-7095
        self.ItemMovedCallback = nil;
1687 Thurallor-7095
    end
1688 2 Thurallor-7095
end
1689 Thurallor-7095
 
1690 Thurallor-7095
function SequenceEditor:Close()
1691 Thurallor-7095
    Turbine.UI.Lotro.Window.Close(self);
1692 Thurallor-7095
end
1693 Thurallor-7095
 
1694 Thurallor-7095
function SequenceEditor:ShowContextMenu()
1695 Thurallor-7095
    -- Build the settings menu.
1696 18 Thurallor-7095
    self.settingsMenu = Turbine.UI.ContextMenu();
1697 2 Thurallor-7095
    local prevContext = L:SetContext("/SequenceEditor/RightClickMenu");
1698 Thurallor-7095
    self:AddSettingsMenuItem(self.settingsMenu, "Root", false);
1699 Thurallor-7095
    L:SetContext(prevContext);
1700 Thurallor-7095
    self.settingsMenu:ShowMenu();
1701 Thurallor-7095
end
1702 Thurallor-7095
 
1703 Thurallor-7095
function SequenceEditor:AddSettingsMenuItem(parent, itemName)
1704 Thurallor-7095
    local item = Turbine.UI.MenuItem(L:GetText(itemName), true, false);
1705 Thurallor-7095
    parent:GetItems():Add(item);
1706 Thurallor-7095
 
1707 Thurallor-7095
    if (itemName == "Root") then
1708 Thurallor-7095
        parent:GetItems():Clear();
1709 34 Thurallor-7095
        self:AddSettingsMenuItem(parent, "CreateSpecialSlot");
1710 Thurallor-7095
        self:AddSettingsMenuItem(parent, "InsertEmptySlot");
1711 7 Thurallor-7095
        self:AddSettingsMenuItem(parent, "CloneSlot");
1712 2 Thurallor-7095
        self:AddSettingsMenuItem(parent, "DeleteSlot");
1713 7 Thurallor-7095
    elseif (itemName == "CloneSlot") then
1714 121 Thurallor-7095
        item.Click = function()
1715 7 Thurallor-7095
            self:CloneSlot(self.clickedItem);
1716 Thurallor-7095
        end
1717 2 Thurallor-7095
    elseif (itemName == "InsertEmptySlot") then
1718 121 Thurallor-7095
        item.Click = function()
1719 2 Thurallor-7095
            self:InsertEmptySlot(self.clickedItem);
1720 Thurallor-7095
        end
1721 Thurallor-7095
    elseif (itemName == ("DeleteSlot")) then
1722 121 Thurallor-7095
        item.Click = function()
1723 2 Thurallor-7095
            self:DeleteSlot(self.clickedItem);
1724 Thurallor-7095
        end
1725 Thurallor-7095
    elseif (itemName == "CreateSpecialSlot") then
1726 Thurallor-7095
        local prevContext = L:SetContext("SpecialSlotMenu");
1727 34 Thurallor-7095
        local texts = L:GetSortedTexts();
1728 Thurallor-7095
        for i = 1, #texts, 1 do
1729 Thurallor-7095
            self:AddSettingsMenuItem(item, L:GetItem(texts[i]));
1730 Thurallor-7095
        end
1731 2 Thurallor-7095
        L:SetContext(prevContext);
1732 6 Thurallor-7095
    elseif (string.find("StopAnimating|GenerateEvent|SetUnequipDestination", itemName)) then
1733 121 Thurallor-7095
        item.Click = function()
1734 2 Thurallor-7095
            self:CreateCommandSlot(self.clickedItem, itemName, item:GetText());
1735 Thurallor-7095
        end
1736 7 Thurallor-7095
    elseif (itemName == "ChatCommand") then
1737 Thurallor-7095
        local commands = Turbine.Shell.GetCommands();
1738 Thurallor-7095
        local index = math.random(#commands);
1739 121 Thurallor-7095
        item.Click = function()
1740 7 Thurallor-7095
            self:CreateAliasSlot(self.clickedItem, "/" .. commands[index]);
1741 Thurallor-7095
        end
1742 2 Thurallor-7095
    elseif (itemName == "RemoveEquipment") then
1743 121 Thurallor-7095
        item.Click = function()
1744 6 Thurallor-7095
            self:CreateRemovalSlot(self.clickedItem, "Gloves");
1745 2 Thurallor-7095
        end
1746 16 Thurallor-7095
    elseif ((itemName == "IfThen") or (itemName == "IfThenElse")) then
1747 121 Thurallor-7095
        item.Click = function()
1748 16 Thurallor-7095
            self:CreateConditional(self.clickedItem, itemName);
1749 Thurallor-7095
        end
1750 Thurallor-7095
    elseif (itemName == "Include") then
1751 121 Thurallor-7095
        item.Click = function()
1752 16 Thurallor-7095
            self:CreateIncludeSlot(self.clickedItem);
1753 Thurallor-7095
        end
1754 34 Thurallor-7095
    elseif (itemName == "Delay") then
1755 121 Thurallor-7095
        item.Click = function()
1756 34 Thurallor-7095
            self:CreateDelaySlot(self.clickedItem);
1757 Thurallor-7095
        end
1758 135 Thurallor-7095
    elseif (itemName == "SelectTarget") then
1759 Thurallor-7095
        item.Click = function()
1760 Thurallor-7095
            self:CreateSelectTargetSlot(self.clickedItem);
1761 Thurallor-7095
        end
1762 146 Thurallor-7095
    elseif (itemName == "LuaScript") then
1763 Thurallor-7095
        item.Click = function()
1764 Thurallor-7095
            self:CreateLuaScriptSlot(self.clickedItem);
1765 Thurallor-7095
        end
1766 2 Thurallor-7095
    end
1767 Thurallor-7095
end
1768 Thurallor-7095
 
1769 7 Thurallor-7095
function SequenceEditor:CreateAliasSlot(s, command)
1770 34 Thurallor-7095
    self:InsertEmptySlot(s);
1771 7 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1772 Thurallor-7095
    info.class = "Turbine.UI.Lotro.Quickslot";
1773 Thurallor-7095
    info.background = nil;
1774 Thurallor-7095
    info.type = Turbine.UI.Lotro.ShortcutType.Alias;
1775 Thurallor-7095
    info.Data = command;
1776 34 Thurallor-7095
    info.altIcon = self.settings.sequenceEditor.defaultIcon;
1777 16 Thurallor-7095
    if (info.background) then
1778 Thurallor-7095
        info.textOverlay = string.gsub(info.Data, "^/", "");
1779 Thurallor-7095
        info.textOverlay = string.gsub(info.textOverlay, "%s.*$", "");
1780 Thurallor-7095
    end
1781 7 Thurallor-7095
    self:RebuildSlot(s);
1782 16 Thurallor-7095
    self:UpdateBar();
1783 7 Thurallor-7095
    self:Redraw();
1784 Thurallor-7095
    self:SelectSlot(s);
1785 Thurallor-7095
end
1786 Thurallor-7095
 
1787 34 Thurallor-7095
function SequenceEditor:CreateDelaySlot(s)
1788 Thurallor-7095
    self:InsertEmptySlot(s);
1789 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1790 Thurallor-7095
    info.class = "Turbine.UI.Control";
1791 Thurallor-7095
    info.background = resources.Icon.Clock;
1792 Thurallor-7095
    info.altIcon = nil;
1793 Thurallor-7095
    info.type = "Delay";
1794 Thurallor-7095
    info.toolTip = L:GetText("/SequenceEditor/RightClickMenu/SpecialSlotMenu/Delay");
1795 Thurallor-7095
    info.delay = 0.25;
1796 147 Thurallor-7095
    info.action = "local item, s = ...; item.bar:StartSlotCooldown(s, " .. tostring(info.delay):gsub(",", ".") .. ");";
1797 34 Thurallor-7095
    info.advanceEvent = "DelayComplete";
1798 Thurallor-7095
 
1799 Thurallor-7095
    self:RebuildSlot(s);
1800 Thurallor-7095
    self:UpdateBar();
1801 Thurallor-7095
    self:Redraw();
1802 Thurallor-7095
    self:SelectSlot(s);
1803 Thurallor-7095
end
1804 Thurallor-7095
 
1805 135 Thurallor-7095
function SequenceEditor:CreateSelectTargetSlot(s)
1806 Thurallor-7095
    self:InsertEmptySlot(s);
1807 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1808 Thurallor-7095
    info.class = "Turbine.UI.Lotro.EntityControl";
1809 Thurallor-7095
    info.altIcon = nil;
1810 Thurallor-7095
    info.type = "SelectTarget";
1811 Thurallor-7095
    info.toolTip = L:GetText("/SequenceEditor/RightClickMenu/SpecialSlotMenu/SelectTarget");
1812 Thurallor-7095
    info.target = "Self";
1813 Thurallor-7095
    info.getTargetFunc = "local _, player = ...; return player;";
1814 Thurallor-7095
 
1815 Thurallor-7095
    self:RebuildSlot(s);
1816 Thurallor-7095
    self:UpdateBar();
1817 Thurallor-7095
    self:Redraw();
1818 Thurallor-7095
    self:SelectSlot(s);
1819 Thurallor-7095
 
1820 Thurallor-7095
end
1821 Thurallor-7095
 
1822 16 Thurallor-7095
function SequenceEditor:CreateIncludeSlot(s)
1823 34 Thurallor-7095
    self:InsertEmptySlot(s);
1824 16 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1825 Thurallor-7095
    info.class = "Turbine.UI.Control";
1826 Thurallor-7095
    info.background = resources.Icon.Include;
1827 34 Thurallor-7095
    info.altIcon = nil;
1828 16 Thurallor-7095
    info.type = "Include";
1829 Thurallor-7095
    info.toolTip = L:GetText("/SequenceEditor/RightClickMenu/SpecialSlotMenu/Include");
1830 Thurallor-7095
 
1831 Thurallor-7095
    self:RebuildSlot(s);
1832 Thurallor-7095
    self:UpdateBar();
1833 Thurallor-7095
    self:Redraw();
1834 Thurallor-7095
    self:SelectSlot(s);
1835 Thurallor-7095
end
1836 7 Thurallor-7095
 
1837 146 Thurallor-7095
function SequenceEditor:CreateLuaScriptSlot(s)
1838 Thurallor-7095
    self:InsertEmptySlot(s);
1839 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1840 Thurallor-7095
    info.class = "Turbine.UI.Control";
1841 Thurallor-7095
    info.background = resources.Icon.LuaScript;
1842 Thurallor-7095
    info.altIcon = nil;
1843 Thurallor-7095
    info.type = "LuaScript";
1844 Thurallor-7095
    info.toolTip = L:GetText("/SequenceEditor/RightClickMenu/SpecialSlotMenu/LuaScript");
1845 Thurallor-7095
    info.action = "Turbine.Shell.WriteLine(\"Hello, world!\");";
1846 Thurallor-7095
 
1847 Thurallor-7095
    self:RebuildSlot(s);
1848 Thurallor-7095
    self:UpdateBar();
1849 Thurallor-7095
    self:Redraw();
1850 Thurallor-7095
    self:SelectSlot(s);
1851 Thurallor-7095
end
1852 Thurallor-7095
 
1853 20 Thurallor-7095
function SequenceEditor:UnlinkIncludedSequence(s)
1854 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1855 Thurallor-7095
    if (not info.include) then
1856 Thurallor-7095
        return;
1857 Thurallor-7095
    end
1858 Thurallor-7095
    local otherSequenceSettings = self.globals.bars[info.include];
1859 Thurallor-7095
    if (not otherSequenceSettings) then
1860 Thurallor-7095
        return;
1861 Thurallor-7095
    end
1862 Thurallor-7095
    local otherItemInfo = otherSequenceSettings.sequenceItemInfo;
1863 Thurallor-7095
    self:DeleteSlot(s);
1864 Thurallor-7095
    for i = 1, #otherItemInfo, 1 do
1865 Thurallor-7095
        if (otherItemInfo[i].class) then
1866 Thurallor-7095
            table.insert(self.settings.sequenceItemInfo, s + i - 1, {});
1867 Thurallor-7095
            DeepTableCopy(otherItemInfo[i], self.settings.sequenceItemInfo[s + i - 1]);
1868 Thurallor-7095
        end
1869 Thurallor-7095
    end
1870 Thurallor-7095
    self:Redraw();
1871 Thurallor-7095
    self:SelectSlot(s);
1872 Thurallor-7095
end
1873 Thurallor-7095
 
1874 16 Thurallor-7095
function SequenceEditor:CreateConditional(s, condType)
1875 34 Thurallor-7095
    local prevContext = L:SetContext("/SequenceEditor");
1876 16 Thurallor-7095
    local ifSlot = s;
1877 46 Thurallor-7095
    self.noRedraw = true;
1878 20 Thurallor-7095
    self:InsertEmptySlot(s);
1879 16 Thurallor-7095
    if (condType == "IfThenElse") then
1880 20 Thurallor-7095
        self:InsertEmptySlot(s);
1881 16 Thurallor-7095
    end
1882 20 Thurallor-7095
    self:InsertEmptySlot(s);
1883 16 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1884 Thurallor-7095
    info.class = "Turbine.UI.Control";
1885 Thurallor-7095
    info.background = resources.Icon["If"];
1886 34 Thurallor-7095
    info.altIcon = nil;
1887 16 Thurallor-7095
    info.type = "If";
1888 Thurallor-7095
    info.condName = "Always";
1889 Thurallor-7095
    info.condExpr = "return true;";
1890 Thurallor-7095
    info.toolTip = L:GetText("If");
1891 Thurallor-7095
    info.automatic = true;
1892 Thurallor-7095
    if (condType == "IfThenElse") then
1893 Thurallor-7095
        s = s + 1;
1894 Thurallor-7095
        info = self.settings.sequenceItemInfo[s];
1895 Thurallor-7095
        info.class = "Turbine.UI.Control";
1896 Thurallor-7095
        info.background = resources.Icon["Else"];
1897 34 Thurallor-7095
        info.altIcon = nil;
1898 16 Thurallor-7095
        info.type = "Else";
1899 Thurallor-7095
        info.toolTip = L:GetText("Else");
1900 Thurallor-7095
        info.automatic = true;
1901 Thurallor-7095
    end
1902 Thurallor-7095
    s = s + 1;
1903 Thurallor-7095
    info = self.settings.sequenceItemInfo[s];
1904 Thurallor-7095
    info.class = "Turbine.UI.Control";
1905 Thurallor-7095
    info.background = resources.Icon["EndIf"];
1906 34 Thurallor-7095
    info.altIcon = nil;
1907 16 Thurallor-7095
    info.type = "EndIf";
1908 Thurallor-7095
    info.toolTip = L:GetText("EndIf");
1909 Thurallor-7095
    info.automatic = true;
1910 46 Thurallor-7095
    self.noRedraw = false;
1911 16 Thurallor-7095
    self:Redraw();
1912 Thurallor-7095
    self:UpdateBar();
1913 Thurallor-7095
    self:SelectSlot(ifSlot);
1914 Thurallor-7095
    L:SetContext(prevContext);
1915 Thurallor-7095
end
1916 Thurallor-7095
 
1917 2 Thurallor-7095
function SequenceEditor:CreateCommandSlot(s, slotName, toolTip)
1918 34 Thurallor-7095
    self:InsertEmptySlot(s);
1919 2 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1920 Thurallor-7095
    info.class = "Turbine.UI.Control";
1921 Thurallor-7095
    info.background = resources.Icon[slotName];
1922 34 Thurallor-7095
    info.altIcon = nil;
1923 2 Thurallor-7095
    if (slotName == "StopAnimating") then
1924 43 Thurallor-7095
        info.action = "local item = ...; item.bar.animationStopped = true; ";
1925 2 Thurallor-7095
    elseif (slotName == "GenerateEvent") then
1926 32 Thurallor-7095
        info.eventName = L:GetText("/SequenceEditor/NewEvent");
1927 34 Thurallor-7095
        info.action = "local item = ...; item.bar.manager:PropagateEvent(item.info.eventName);";
1928 6 Thurallor-7095
    elseif (slotName == "SetUnequipDestination") then
1929 Thurallor-7095
        info.bagSlot = 1;
1930 34 Thurallor-7095
        info.action = "local item = ...; item.bar.manager:SetUnequipDestination(item.info.bagSlot);";
1931 2 Thurallor-7095
    end
1932 Thurallor-7095
    info.type = slotName;
1933 Thurallor-7095
    info.toolTip = toolTip;
1934 Thurallor-7095
    self:RebuildSlot(s);
1935 16 Thurallor-7095
    self:UpdateBar();
1936 2 Thurallor-7095
    self:Redraw();
1937 Thurallor-7095
    self:SelectSlot(s);
1938 Thurallor-7095
end
1939 Thurallor-7095
 
1940 6 Thurallor-7095
function SequenceEditor:CreateRemovalSlot(s, eqSlotName, bagSlot)
1941 34 Thurallor-7095
    self:InsertEmptySlot(s);
1942 2 Thurallor-7095
    local info = self.settings.sequenceItemInfo[s];
1943 Thurallor-7095
    info.class = "Turbine.UI.Control";
1944 6 Thurallor-7095
    info.background = resources.Icon["Unequip" .. eqSlotName];
1945 34 Thurallor-7095
    info.altIcon = nil;
1946 Thurallor-7095
    info.action = "local item = ...; item.bar.manager:Unequip(Turbine.Gameplay.Equipment." .. eqSlotName .. ");";
1947 6 Thurallor-7095
    info.type = "Remove " .. eqSlotName;
1948 Thurallor-7095
 
1949 Thurallor-7095
    local prevContext = L:SetContext("/SequenceEditor");
1950 Thurallor-7095
    local toolTip = L:GetText("RemoveItem");
1951 Thurallor-7095
    L:SetContext("EquipmentSlots");
1952 Thurallor-7095
    local localEqSlotName = L:GetText(eqSlotName);
1953 Thurallor-7095
    info.toolTip = string.gsub(toolTip, "<item>", localEqSlotName);
1954 Thurallor-7095
    L:SetContext(prevContext);
1955 Thurallor-7095
 
1956 2 Thurallor-7095
    self:RebuildSlot(s);
1957 16 Thurallor-7095
    self:UpdateBar();
1958 2 Thurallor-7095
    self:Redraw();
1959 Thurallor-7095
    self:SelectSlot(s);
1960 Thurallor-7095
end
1961 Thurallor-7095
 
1962 Thurallor-7095
function SequenceEditor:ExtendSequenceTo(s)
1963 Thurallor-7095
    if (s <= #self.settings.sequenceItemInfo) then
1964 Thurallor-7095
        return false;
1965 Thurallor-7095
    end
1966 Thurallor-7095
    while (s > #self.settings.sequenceItemInfo) do
1967 Thurallor-7095
        table.insert(self.settings.sequenceItemInfo, {});
1968 Thurallor-7095
    end
1969 Thurallor-7095
    return true;
1970 Thurallor-7095
end
1971 Thurallor-7095
 
1972 Thurallor-7095
function SequenceEditor:DeleteEmptyTrailingSlots()
1973 Thurallor-7095
    local sequenceItemInfo = self.settings.sequenceItemInfo;
1974 Thurallor-7095
    for s = #sequenceItemInfo, 1, -1 do
1975 Thurallor-7095
        local info = sequenceItemInfo[s];
1976 Thurallor-7095
        if (not info.class) then
1977 Thurallor-7095
            table.remove(sequenceItemInfo, s);
1978 5 Thurallor-7095
            -- Remove empty slot displays
1979 Thurallor-7095
            if (self.sequenceItems) then
1980 Thurallor-7095
                local object = self.sequenceItems[s];
1981 Thurallor-7095
                if (object) then
1982 Thurallor-7095
                    if (object.numLabel) then
1983 Thurallor-7095
                        object.numLabel:SetParent(nil);
1984 Thurallor-7095
                    end
1985 Thurallor-7095
                    object:SetParent(nil);
1986 Thurallor-7095
                    self.sequenceItems[s] = nil;
1987 Thurallor-7095
                end
1988 Thurallor-7095
            end
1989 2 Thurallor-7095
        else
1990 Thurallor-7095
            break;
1991 Thurallor-7095
        end
1992 Thurallor-7095
    end
1993 Thurallor-7095
end
1994 Thurallor-7095
 
1995 7 Thurallor-7095
function SequenceEditor:CloneSlot(s)
1996 Thurallor-7095
    self:InsertEmptySlot(s);
1997 Thurallor-7095
    DeepTableCopy(self.settings.sequenceItemInfo[s + 1], self.settings.sequenceItemInfo[s]);
1998 Thurallor-7095
    self:RebuildSlot(s);
1999 16 Thurallor-7095
    self:UpdateBar();
2000 7 Thurallor-7095
    self:Redraw();
2001 Thurallor-7095
    self:SelectSlot(s);
2002 Thurallor-7095
end
2003 Thurallor-7095
 
2004 Thurallor-7095
function SequenceEditor:MoveSlot(sourceSlot, destSlot)
2005 Thurallor-7095
    self:InsertEmptySlot(destSlot);
2006 Thurallor-7095
    if (sourceSlot >= destSlot) then
2007 Thurallor-7095
        sourceSlot = sourceSlot + 1;
2008 Thurallor-7095
    end
2009 Thurallor-7095
    DeepTableCopy(self.settings.sequenceItemInfo[sourceSlot], self.settings.sequenceItemInfo[destSlot]);
2010 Thurallor-7095
    self:RebuildSlot(destSlot);
2011 Thurallor-7095
    self:DeleteSlot(sourceSlot);
2012 Thurallor-7095
    if (sourceSlot <= destSlot) then
2013 Thurallor-7095
        destSlot = destSlot - 1;
2014 Thurallor-7095
    end
2015 16 Thurallor-7095
    self:UpdateBar();
2016 7 Thurallor-7095
    self:Redraw();
2017 Thurallor-7095
    self:SelectSlot(destSlot);
2018 Thurallor-7095
end
2019 Thurallor-7095
 
2020 Thurallor-7095
function SequenceEditor:InsertSlot(s, info)
2021 2 Thurallor-7095
    if (s > #self.settings.sequenceItemInfo) then
2022 Thurallor-7095
        self:ExtendSequenceTo(s);
2023 Thurallor-7095
    else
2024 Thurallor-7095
        table.insert(self.settings.sequenceItemInfo, s, {});
2025 Thurallor-7095
    end
2026 7 Thurallor-7095
    if (info) then
2027 Thurallor-7095
        DeepTableCopy(info, self.settings.sequenceItemInfo[s]);
2028 Thurallor-7095
    end
2029 2 Thurallor-7095
    self:Redraw();
2030 16 Thurallor-7095
    self:UpdateBar();
2031 2 Thurallor-7095
    self:SelectSlot(s);
2032 Thurallor-7095
end
2033 Thurallor-7095
 
2034 7 Thurallor-7095
function SequenceEditor:InsertEmptySlot(s)
2035 Thurallor-7095
    self:InsertSlot(s, nil);
2036 Thurallor-7095
end
2037 Thurallor-7095
 
2038 2 Thurallor-7095
function SequenceEditor:DeleteSlot(s)
2039 Thurallor-7095
    table.remove(self.settings.sequenceItemInfo, s);
2040 Thurallor-7095
    self:Redraw();
2041 16 Thurallor-7095
    self:UpdateBar();
2042 2 Thurallor-7095
    self:ExtendSequenceTo(s);
2043 Thurallor-7095
    self:SelectSlot(nil);
2044 Thurallor-7095
end

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


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