EventTableControl = class(Thurallor.UI.TableControl);
local barPrefix = L:GetText("/DirectoryWindow/EventTable/Bar");
local groupPrefix = L:GetText("/DirectoryWindow/EventTable/Group");
local hotkeyPrefix = L:GetText("/DirectoryWindow/EventTable/Hotkey");
local chatTriggerPrefix = L:GetText("/DirectoryWindow/EventTable/ChatTrigger");
function EventTableControl:Constructor(manager)
Thurallor.UI.TableControl.Constructor(self);
self.manager = manager;
self.settings = manager.settings.eventDirectory or {};
manager.settings.eventDirectory = self.settings;
self.cells = {};
self.constructing = true;
self.via = L:GetText("/DirectoryWindow/EventTable/via");
-- Disable sorting of all columns except event name
local textSort = self.style.column.SortMethod;
self.style.column.SortMethod = nil;
self.style.heading.FontStyle = Turbine.UI.FontStyle.Outline;
self.style.heading.OutlineColor = Turbine.UI.Color.Black;
self.style.cell.FontStyle = Turbine.UI.FontStyle.Outline;
self.style.cell.OutlineColor = Turbine.UI.Color.Black;
--self.style.marquee.AntsEnabled = false;
-- Disable cell locking/unlocking
self.options.columnLockingEnabled = false;
local prevContext = L:SetContext("/DirectoryWindow/EventTable");
self:AddColumn("eventName", L:GetText("EventName"), 1, textSort);
self:AddColumn("generators", L:GetText("TriggeredBy"), 1, nil);
self:AddColumn("watchers", L:GetText("WatchedBy"), 1, nil);
self:AddColumn("script", L:GetText("LuaScript"), 1, nil);
L:SetContext(prevContext);
if (self.settings.presentation) then
self:SetPresentation(self.settings.presentation);
end
self:FillTable();
self:ReSort(true);
self.constructing = false;
end
function EventTableControl:PresentationChanged(args)
if (not self.constructing) then
self.settings.presentation = self:GetPresentation();
--self:SaveSettings(false);
end
end
function EventTableControl:AddMouseOverHighlight(control, foreColor)
control.foreColor = foreColor;
control:SetForeColor(control.foreColor);
control.MouseEnter = function(ctl)
ctl:SetForeColor(Turbine.UI.Color.White);
ctl:SetBackColor(Turbine.UI.Color(1, 0, 0.282, 0.498));
end
control.MouseMove = control.MouseEnter;
control.MouseLeave = function(ctl)
ctl:SetForeColor(ctl.foreColor);
ctl:SetBackColor(nil);
end
end
function EventTableControl:AddTextItem(cell, top, color, font, text)
local control = Thurallor.UI.ComplexLabel();
control:SetParent(cell);
control:SetPosition(1, top);
control:SetFont(font);
control:SetForeColor(color);
control:SetInteriorAlignment(Turbine.UI.ContentAlignment.TopLeft);
local label = control:SetText(" " .. text .. " ");
self:AddMouseOverHighlight(label, color);
control:SetForeColor(Turbine.UI.Color.Silver);
control:SetFont(Turbine.UI.Lotro.Font.Verdana14);
control:SetZOrder(1);
control:SetSize(cell:GetWidth()- 2, 15);
AddCallback(cell, "SizeChanged", function()
control:SetWidth(cell:GetWidth() - 2);
end);
return control, label;
end
function EventTableControl:AddNodeMouseBehaviors(label, node)
label.node = node;
self:AddMouseOverHighlight(label, node:GetColor());
label.MouseClick = function(ctl, args)
-- When row is selected, left- or right-click displays the settings menu.
ctl.node:ShowSettingsMenu(true);
end
end
function EventTableControl:AddNodeLink(cell, top, node, includes)
local text = node:GetName();
local control, label = self:AddTextItem(cell, top, node:GetColor(), Turbine.UI.Lotro.Font.TrajanPro15, text);
self:AddNodeMouseBehaviors(label, node);
if (includes and next(includes)) then
control:SetForeColor(Turbine.UI.Color.Silver);
control:SetFont(Turbine.UI.Lotro.Font.Verdana14);
control:AddText(self.via);
text = text .. " (" .. self.via;
for bar, _ in pairs(includes) do
control:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
control:SetForeColor(bar:GetColor());
local barName = bar:GetName();
local label = control:AddText(" " .. barName .. " ");
text = text .. " " .. barName .. ",";
self:AddNodeMouseBehaviors(label, bar);
end
control:SetForeColor(Turbine.UI.Color.Silver);
control:SetFont(Turbine.UI.Lotro.Font.Verdana14);
text = text:gsub(",$", ")");
end
return top + 15, text;
end
function EventTableControl:AddChatTriggerLink(cell, top, channel, pattern, text)
text = chatTriggerPrefix .. text;
local control, label = self:AddTextItem(cell, top, Turbine.UI.Color.Silver, Turbine.UI.Lotro.Font.Verdana14, text);
label.channel, label.pattern = channel, pattern;
self:AddMouseOverHighlight(label, Turbine.UI.Color.Silver);
AddCallback(label, "MouseClick", function()
DoCallbacks(self, "ChatTriggerClicked", { ChatType = channel; Pattern = pattern });
end);
return top + 14, text;
end
function EventTableControl:AddHotkeyLink(cell, top, text)
text = hotkeyPrefix .. text;
local control, label = self:AddTextItem(cell, top, Turbine.UI.Color.Silver, Turbine.UI.Lotro.Font.Verdana14, text);
self:AddMouseOverHighlight(label, Turbine.UI.Color.Silver);
AddCallback(label, "MouseClick", function()
DoCallbacks(self, "HotkeyClicked");
end);
return top + 14, text;
end
function EventTableControl:MakeEmptyCell(cell)
cell:GetControls():Clear();
cell:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
cell:SetFont(Turbine.UI.Lotro.Font.Verdana14);
cell:SetForeColor(Turbine.UI.Color.Silver);
cell:SetMultiline(false);
cell:SetText("â");
cell.GetText = function() return ""; end -- suppress this line in row tooltip
end
function EventTableControl:MakeNodeListCell(cell, nodeList, includes, hotkeyList, chatTriggerList)
if (not nodeList and not hotkeyList and not chatTriggerList) then
return self:MakeEmptyCell(cell);
end
cell:SetText(nil);
cell:GetControls():Clear();
-- Display node list
local top, text = 5;
local tooltipText = {};
if (nodeList) then
table.sort(nodeList, function(a, b)
return a:GetName() < b:GetName();
end);
for n, node in ipairs(nodeList) do
top, text = self:AddNodeLink(cell, top, node, includes[node]);
local prefix = barPrefix;
if (node:CanHaveChildren()) then
prefix = groupPrefix;
end
table.insert(tooltipText, prefix .. text);
end
end
-- Display hotkey list
if (hotkeyList) then
table.sort(hotkeyList);
for n, text in ipairs(hotkeyList) do
top, text = self:AddHotkeyLink(cell, top, text);
table.insert(tooltipText, text);
end
end
-- Display chat trigger list
if (chatTriggerList) then
for _, info in ipairs(chatTriggerList) do
local channel, pattern, description = unpack(info);
top, text = self:AddChatTriggerLink(cell, top, channel, pattern, description);
table.insert(tooltipText, description);
end
end
cell.text = table.concat(tooltipText, "\n");
cell.GetText = function(ctl)
return ctl.text;
end
cell.SetWidth = function(ctl, width)
Turbine.UI.Lotro.TextBox.SetWidth(ctl, width);
DoCallbacks(ctl, "SizeChanged");
end
cell:SetHeight(top + 5);
end
function EventTableControl:FillTable()
local eventNames = self.manager:GetEventNames();
for _, eventName in ipairs(eventNames) do
self:AppendRow(eventName);
end
end
function EventTableControl:AppendRow(eventName)
local manager = self.manager;
manager.settings.userEvents[eventName] = manager.settings.userEvents[eventName] or {};
local settings = manager.settings.userEvents[eventName];
local rowContainer, cells, rowNum = self:AddRow(eventName, true);
self.cells[eventName] = cells;
-- Add behaviors to event name cell
cells.eventName.eventName = eventName;
cells.eventName:SetReadOnly(false);
cells.eventName.Evaluate = function(cell, newName)
local newName = cell:GetText();
newName = newName:gsub("^[%s]+", "");
newName = newName:gsub("[%s]+$", "");
local eventExists = self:GetRow(newName);
if ((newName == "") or (eventExists and newName ~= cell.eventName)) then
cell:SetBackColor(Turbine.UI.Color.Red);
else
cell:SetBackColor(Turbine.UI.Color.Black);
return newName;
end
end
AddCallback(cells.eventName, "FocusGained", function(cell)
cell:SetForeColor(Turbine.UI.Color.White);
cell:Evaluate();
end);
AddCallback(cells.eventName, "TextChanged", function(cell)
cell:Evaluate();
end);
AddCallback(cells.eventName, "FocusLost", function(cell)
local newName = cell:Evaluate();
if (newName and (newName ~= cell.eventName)) then
self:RenameEvent(cell.eventName, newName);
else
cell:SetText(cell.eventName);
end
cell:SetForeColor(Turbine.UI.Color.Silver);
cell:SetBackColor(Turbine.UI.Color(1, 0, 0.19, 0.33));
end);
-- Add behaviors to Lua script cell
cells.script.eventName = eventName;
cells.script:SetMultiline(true);
cells.script.UpdateHeight = function(cell)
local _, lines = cell:GetText():gsub("\n", "");
cell:SetHeight(10 + (lines + 1) * 12);
end
cells.script.Evaluate = function(cell, script)
local success = loadstring(script);
if (success) then
cell:SetBackColor(Turbine.UI.Color.Black);
else
cell:SetBackColor(Turbine.UI.Color.Red);
end
end
AddCallback(cells.script, "MouseEnter", function(cell)
-- Weird bug: Cell contents aren't drawn properly if I set this flag at initialization.
-- Also doesn't work in the "FocusGained" handler; apparently that's too late.
cell:SetReadOnly(false);
end);
AddCallback(cells.script, "FocusGained", function(cell)
cell:SetForeColor(Turbine.UI.Color.White);
local settings = manager.settings.userEvents[cell.eventName];
if (settings.luaScript) then
cell:Evaluate(settings.luaScript);
else
cell:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
cell:SetFont(Turbine.UI.Lotro.Font.LucidaConsole12);
cell:SetText("");
cell.GetText = nil;
end
end);
AddCallback(cells.script, "TextChanged", function(cell)
local text = cell:GetText();
cell:Evaluate(text);
text = text:gsub("^[%s\n]+", "");
text = text:gsub("[%s\n]+$", "");
if (text == "") then
text = nil;
end
manager:SetEventScript(cell.eventName, text);
end);
AddCallback(cells.script, "FocusLost", function(cell)
cell:SetForeColor(Turbine.UI.Color.Silver);
cell:SetBackColor(Turbine.UI.Color(1, 0, 0.19, 0.33));
self:UpdateCellContents(cell.eventName);
end);
-- Add right-click behavior to show bar/group context menu if row isn't selected
AddCallback(rowContainer, "ContextMenu", function(ctl, args)
-- Find which bar/group was right-clicked on, if any
for _, cell in pairs(rowContainer.cells) do
local controls = cell:GetControls();
for c = 1, controls:GetCount() do
local control = controls:Get(c);
if (control.node) then
local left, top = control:PointToScreen(0, 0);
local width, height = control:GetSize();
local right, bottom = left + width, top + height;
local mouseX, mouseY = Turbine.UI.Display.GetMousePosition();
if ((mouseX >= left) and (mouseX < right) and (mouseY >= top) and (mouseY < bottom)) then
return control.node:ShowSettingsMenu(true);
end
end
end
end
end);
AddCallback(rowContainer, "MouseClick", function(ctl, args)
DoCallbacks(ctl, "ContextMenu", args);
end);
self:UpdateCellContents(eventName);
end
-- Updates the "Generated by" and "Watched by" cells and readjusts the row height
function EventTableControl:UpdateCellContents(eventName)
local cells = self.cells[eventName];
-- Display event name
cells.eventName:SetText(eventName);
cells.eventName:SetHeight(24);
-- Create list of generators
local barList, includes = self.manager:GetEventGenerators(eventName);
local hotkeyList = self.manager:GetEventHotkeys(eventName);
local chatTriggerList = self.manager:GetEventChatTriggers(eventName);
self:MakeNodeListCell(cells.generators, barList, includes, hotkeyList, chatTriggerList);
-- Create list of watchers
local nodeList = self.manager:GetEventListeners(eventName);
self:MakeNodeListCell(cells.watchers, nodeList, {});
-- Display lua script
local settings = self.manager.settings.userEvents[eventName];
if (settings.luaScript) then
cells.script:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
cells.script:SetFont(Turbine.UI.Lotro.Font.LucidaConsole12);
cells.script:SetText(settings.luaScript);
else
self:MakeEmptyCell(cells.script);
end
cells.script:UpdateHeight();
self:EqualizeCellHeights(eventName);
end
function EventTableControl:EqualizeCellHeights(eventName)
local cells = self.cells[eventName];
-- Find maximum cell height
local maxCellHeight = 0;
for colName, cell in pairs(cells) do
maxCellHeight = math.max(maxCellHeight, cell:GetHeight());
end
-- Make all cells the same height.
for colName, cell in pairs(cells) do
cell:SetHeight(maxCellHeight);
end
-- Adjust height of rowContainer
local rowNum = self.rows:IndexOfItem(self:GetRow(eventName));
self:SetRowVisible(rowNum, true);
end
function EventTableControl:CreateEvent(eventName)
self.manager:CreateUserEvent(eventName);
self:AppendRow(eventName);
self:ReSort();
self:SelectRow(eventName);
self:EnsureVisible(eventName);
end
function EventTableControl:RenameEvent(oldName, newName)
self.manager:RenameUserEvent(oldName, newName);
end
function EventTableControl:DeleteEvent(eventName)
self.manager:DeleteUserEvent(eventName);
self:DeleteRow(eventName);
end