NodeLabel = class(Turbine.UI.Label);
function NodeLabel:Constructor(node, object)
Turbine.UI.Label.Constructor(self);
self.node = node;
self.object = object;
self:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
self:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
self:SetFontStyle(Turbine.UI.FontStyle.Outline);
self:SetOutlineColor(Turbine.UI.Color.Black);
self:SetMultiline(false);
self:SetHeight(20);
self:UpdateText();
self.skipSizeChanged = 1;
end
function NodeLabel:UpdateText()
self:SetForeColor(self.object:GetColor());
self:SetText(self.object:GetName());
end
ShowHideButton = class(Turbine.UI.Lotro.Button);
function ShowHideButton:Constructor(node, object)
Turbine.UI.Lotro.Button.Constructor(self);
self.node = node;
self.object = object;
self:SetFont(Turbine.UI.Lotro.Font.TrajanPro13);
self:SetWidth(ShowHideButton.buttonWidth);
object.HiddenChanged = function()
self:UpdateText();
end
self:UpdateText();
end
function ShowHideButton:UpdateText()
local hidden = self.object.settings.hidden;
self:SetFont(Turbine.UI.Lotro.Font.TrajanPro13); -- reapply font for Cyrillic
if (hidden) then
self:SetText(ShowHideButton.showText);
else
self:SetText(ShowHideButton.hideText);
end
self:SetVisible(not self.object:IsParentHidden());
end
function ShowHideButton:Click()
self.object:SetHidden(not self.object:IsHidden());
end
OptionsPanel = class(Turbine.UI.Control);
function OptionsPanel:Constructor(manager)
Turbine.UI.Control.Constructor(self);
self.manager = manager;
self.skipSizeChanged = 0;
self.skipUpdate = 0;
self.tabs = Thurallor.UI.TabCardStack();
self.tabs:SetParent(self);
self.tab1 = Thurallor.UI.TabCard();
self.tab1:SetTabLeft(0);
self.tab1.inside = Turbine.UI.Control();
self.tab1:SetInteriorControl(self.tab1.inside);
self.tab1:SetInteriorAlignment(Turbine.UI.ContentAlignment.TopLeft);
local left, top = 10, 10;
self.tab1.language = Turbine.UI.Label();
self.tab1.language:SetParent(self.tab1.inside);
self.tab1.language:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
self.tab1.language:SetPosition(left, top);
self.tab1.language:SetSize(100, 16);
top = top + 16;
local languages = { "English", "German", "French", "Russian" };
local peers = {};
self.tab1.languageButtons = {};
for l = 1, #languages do
language = languages[l];
local radioButton = Thurallor.UI.RadioButton(self.tab1.inside);
radioButton.language = languages[l];
radioButton:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
radioButton:SetSize(300, 16);
radioButton:SetPosition(left, top);
radioButton.Clicked = function(sender)
self.manager:SetLanguage(Turbine.Language[sender.language]);
-- self:Localize();
-- self:RefreshDirectory();
end
self.tab1.languageButtons[radioButton.language] = radioButton;
table.insert(peers, radioButton);
top = top + 16;
end
Thurallor.UI.RadioButton.LinkPeers(peers);
top = top + 16;
self.tab1.snapToGrid = Turbine.UI.Lotro.CheckBox();
self.tab1.snapToGrid:SetParent(self.tab1.inside);
self.tab1.snapToGrid:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
self.tab1.snapToGrid:SetPosition(left, top);
self.tab1.snapToGrid:SetSize(200, 16);
self.tab1.snapToGrid.CheckedChanged = function(sender)
self.manager:SetSnapToGrid(sender:IsChecked());
end
top = top + 32;
self.tab1.uiScaleLabel = Turbine.UI.Label();
self.tab1.uiScaleLabel:SetParent(self.tab1.inside);
self.tab1.uiScaleLabel:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
self.tab1.uiScaleLabel:SetPosition(left, top);
self.tab1.uiScaleLabel:SetSize(200, 16);
top = top + 16;
self.tab1.uiScale = Turbine.UI.Lotro.ScrollBar();
self.tab1.uiScale:SetParent(self.tab1.inside);
self.tab1.uiScale:SetPosition(left, top);
self.tab1.uiScale:SetSize(200, 10);
self.tab1.uiScale:SetMinimum(13);
self.tab1.uiScale:SetMaximum(96);
self.tab1.uiScale:SetSmallChange(1);
self.tab1.uiScale:SetLargeChange(10);
self.tab1.uiScale.ValueChanged = function(sb)
local scale = sb:GetValue();
self.manager:SetUIScale(scale);
self.tab1.uiScaleLabel:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/UiScale") .. ": " .. string.format("%d", scale * 100 / 32) .. "%");
end
top = top + 26;
self.tab1.uiOpacityLabel = Turbine.UI.Label();
self.tab1.uiOpacityLabel:SetParent(self.tab1.inside);
self.tab1.uiOpacityLabel:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
self.tab1.uiOpacityLabel:SetPosition(left, top);
self.tab1.uiOpacityLabel:SetSize(200, 16);
top = top + 16;
self.tab1.uiOpacity = Turbine.UI.Lotro.ScrollBar();
self.tab1.uiOpacity:SetParent(self.tab1.inside);
self.tab1.uiOpacity:SetPosition(left, top);
self.tab1.uiOpacity:SetSize(200, 10);
self.tab1.uiOpacity:SetMinimum(0);
self.tab1.uiOpacity:SetMaximum(100);
self.tab1.uiOpacity:SetSmallChange(1);
self.tab1.uiOpacity:SetLargeChange(10);
self.tab1.uiOpacity.ValueChanged = function(sb)
local opacity = sb:GetValue();
self.manager:SetUIOpacity(opacity / 100);
self.tab1.uiOpacityLabel:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/UiOpacity") .. ": " .. opacity .. "%");
end
top = top + 16;
local width, height = 300, top + 10;
self.tab1.inside:SetSize(width, height);
self:RefreshGlobalSettings();
self.tab2 = Thurallor.UI.TabCard();
self.tab2.inside = Turbine.UI.Control();
self.tab2.inside:SetSize(width, height);
self.tab2:SetInteriorControl(self.tab2.inside);
self.tab2:SetInteriorAlignment(Turbine.UI.ContentAlignment.TopCenter);
self.tabs:SetSize(width + 20, height + 40);
self:SetSize(width + 20, height + 40);
self.tabs:AddTabCard(self.tab1);
self.tabs:AddTabCard(self.tab2);
self.instructions = Turbine.UI.Label();
self.instructions:SetParent(self.tab2.inside);
self.instructions:SetMultiline(true);
self.instructions.height = 32;
self.instructions:SetHeight(self.instructions.height);
self.instructions:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
self.instructions:SetForeColor(Turbine.UI.Color.PaleGoldenrod);
self:Localize();
-- For drag-and-drop operations
self.carrierWindow = Turbine.UI.Window();
self.carrierWindow:SetZOrder(2147483647);
self.carrierWindow:SetOpacity(0.75);
self.carrierWindow:SetMouseVisible(false);
plugin.GetOptionsPanel = function()
return self;
end
end
function OptionsPanel:ShowRefreshButton()
local prevContext = L:SetContext("/PluginManager/OptionsTab/");
if (not self.refreshButton) then
self.refreshButton = Turbine.UI.Lotro.Button();
self.refreshButton:SetSize(L:GetNumber("ShowHideButtonWidth"), 20);
self.refreshButton.Click = function()
self:RefreshDirectory();
end
end
self.refreshButton:SetText(L:GetText("Show"));
self.refreshButton:SetFont(Turbine.UI.Lotro.Font.TrajanPro13); -- reapply font for Cyrillic
self.tab2:SetInteriorControl(self.refreshButton);
L:SetContext(prevContext);
end
function OptionsPanel:ShowGlobalSettings()
Turbine.PluginManager.ShowOptions(Plugins.SequenceBars);
self.tabs:BringToFront(self.tab1);
self:RefreshGlobalSettings();
end
function OptionsPanel:ShowDirectory()
Turbine.PluginManager.ShowOptions(Plugins.SequenceBars);
self.tabs:BringToFront(self.tab2);
self:RefreshDirectory();
end
function OptionsPanel:Localize()
-- Reapply fonts for Cyrillic support
self.tab1.tabText:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
self.tab2.tabText:SetFont(Turbine.UI.Lotro.Font.TrajanPro15);
for object in values({
self.tab1.language,
self.tab1.languageButtons["English"],
self.tab1.languageButtons["French"],
self.tab1.languageButtons["German"],
self.tab1.languageButtons["Russian"],
self.tab1.snapToGrid,
self.instructions,
self.tab1.uiScaleLabel,
self.tab1.uiOpacityLabel
}) do
object:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
end
local tab1Width = L:GetNumber("/PluginManager/OptionsTab/GlobalSettingsTabWidth");
self.tab1:SetTabWidth(tab1Width);
self.tab1:SetTabText(L:GetText("/PluginManager/OptionsTab/GlobalSettings"));
self.tab1.language:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/Language"));
for language in keys(self.tab1.languageButtons) do
self.tab1.languageButtons[language]:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/LanguageMenu/" .. language));
end
self.tab1.snapToGrid:SetText(L:GetText("/PluginManager/OptionsTab/GlobalSettingsTab/SnapToGrid"));
self.tab1.uiScale:ValueChanged();
self.tab1.uiOpacity:ValueChanged();
self.tab2:SetTabLeft(tab1Width);
self.tab2:SetTabWidth(L:GetNumber("/PluginManager/OptionsTab/DirectoryTabWidth"));
self.tab2:SetTabText(L:GetText("/PluginManager/OptionsTab/Directory"));
self.instructions:SetText(L:GetText("/PluginManager/OptionsTab/Instructions"));
ShowHideButton.buttonWidth = L:GetNumber("/PluginManager/OptionsTab/ShowHideButtonWidth");
ShowHideButton.showText = L:GetText("/PluginManager/OptionsTab/Show");
ShowHideButton.hideText = L:GetText("/PluginManager/OptionsTab/Hide");
end
function OptionsPanel:RefreshGlobalSettings()
for language in keys(self.tab1.languageButtons) do
self.tab1.languageButtons[language]:SetChecked(self.manager.settings.language == Turbine.Language[language]);
end
self.tab1.snapToGrid:SetChecked(self.manager.settings.snapToGrid);
self.tab1.uiScale:SetValue(self.manager.settings.uiScale);
self.tab1.uiOpacity:SetValue(self.manager.settings.uiOpacity * 100);
end
function OptionsPanel:RefreshDirectory()
if (not self:IsDisplayed() or (not self.tab2:IsInFront())) then
return self:ShowRefreshButton();
end
self.tab2:SetInteriorControl(self.tab2.inside);
self:Localize();
if (self.tree) then
self.tree:SetPosition(10,10);
self.tree:SetParent(nil);
end
self.tree = self:AddTreeNode(nil, self.manager);
self.tree:SetParent(self.tab2.inside);
self.tree:SetTop(self.instructions.height);
self.tree.SizeChanged = function()
local newHeight = self.instructions.height + self.tree:GetHeight();
newHeight = math.max(newHeight, self.tab1.inside:GetHeight());
self.tab2.inside:SetHeight(newHeight);
self:SetHeight(newHeight + 40);
end
self.tree.SizeChanged();
self.width = 0;
self:SizeChanged();
end
function OptionsPanel:SetHeight(height)
Turbine.UI.Control.SetHeight(self, height);
self.tabs:SetHeight(height);
end
function OptionsPanel:SizeChanged()
if (self.skipSizeChanged > 0) then
self.skipSizeChanged = self.skipSizeChanged - 1;
return;
end
local width = self:GetWidth();
if (self.width ~= width) then
self.width = width;
self.tabs:SetWidth(self.width);
self.tab2.inside:SetWidth(self.width - 20);
if (self.tree) then
self.instructions:SetWidth(self.width - 20);
self.tree:SetWidth(self.width - 20);
end
end
end
function OptionsPanel:AddTreeNode(parentNode, object)
local newNode = Thurallor.UI.TreeControl();
newNode.object = object;
-- Add a text box for the name of the group or bar.
newNode.label = NodeLabel(newNode, object);
newNode:AddColumn(newNode.label, 1);
-- Add the "Show" or "Hide" button.
newNode.showHideButton = ShowHideButton(newNode, object);
newNode:AddColumn(newNode.showHideButton, 0);
if (parentNode) then
parentNode:AddChild(newNode);
end
-- Add subnodes, if any, alphabetized
local childIDs = {};
if (object:CanHaveChildren()) then
childIDs = object:GetChildIDs();
table.sort(childIDs, function (a, b) return object:GetChild(a):GetName() < object:GetChild(b):GetName(); end);
for c = 1, #childIDs, 1 do
local childID = childIDs[c];
local child = object:GetChild(childID);
self:AddTreeNode(newNode, child);
end
end
newNode:SetExpanded(true);
-- Add mouse behaviors
newNode.label.MouseClick = function(sender, args)
-- Right-click displays the settings menu.
if (args.Button == Turbine.UI.MouseButton.Right) then
sender.node.object:ShowSettingsMenu(true);
end
end
newNode.label.MouseDoubleClick = function(sender, args)
-- Left-double-click opens the caption editor.
if (args.Button == Turbine.UI.MouseButton.Left) then
sender.node.object:EditCaption(newNode.label);
end
end
newNode.label.MouseDown = function(sender, args)
if ((args.Button == Turbine.UI.MouseButton.Left) and (sender ~= self.tree.label)) then
sender.mouseDown = true;
sender.originalLeft, sender.originalTop = sender.node:GetParent():PointToScreen(sender.node:GetPosition());
sender.originalMouseX, sender.originalMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
end
end
newNode.label.MouseMove = function(sender)
if (sender.mouseDown) then
-- Detach from tree
if (not sender.detached) then
sender.originalParentNode = sender.node:GetParentTreeControl();
sender.originalChildNumber = sender.originalParentNode:RemoveChild(sender.node);
self.carrierWindow:SetVisible(true);
self.carrierWindow:SetSize(sender.node:GetSize());
sender.node:SetParent(self.carrierWindow);
sender.node:SetPosition(0, 0);
self.carrierWindow:SetPosition(sender.originalLeft, sender.originalTop);
sender.node:SetColumnWidth(3, 0);
sender.detached = true;
end
local newMouseX, newMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
local deltaX, deltaY = newMouseX - sender.originalMouseX, newMouseY - sender.originalMouseY;
local left = sender.originalLeft + deltaX;
local top = sender.originalTop + deltaY;
self.carrierWindow:SetPosition(left, top);
if (sender.previousHighlight) then
sender.previousHighlight:SetBackColor(nil);
sender.previousHighlight = nil;
end
-- Figure out if we're over another textBox
local hoveringOverNode, target = self.tree:IsMouseInside();
if (hoveringOverNode) then
local source = sender.node;
if (
(target.object:CanHaveChildren()) and
(target ~= source) and
(not source.object:Contains(target.object)) and
(source.object.parent ~= target.object)
) then
sender.targetObject = target.object;
--Puts("target object is " .. object.settings.type .. " " .. Serialize(object.settings.caption.text));
target.label:SetBackColor(Turbine.UI.Color(1, 0.25, 0.25, 0.75));
sender.previousHighlight = target.label;
return;
end
end
sender.targetObject = nil;
end
end
newNode.label.MouseUp = function(sender, args)
if (args.Button == Turbine.UI.MouseButton.Left) then
sender.mouseDown = false;
if (sender.detached) then
local newMouseX, newMouseY = Turbine.UI.Display.GetMouseX(), Turbine.UI.Display.GetMouseY();
local deltaX, deltaY = newMouseX - sender.originalMouseX, newMouseY - sender.originalMouseY;
-- Do the object transfer
sender.node:SetParent(nil);
if (sender.targetObject) then
local sourceObject = sender.node.object;
if (sourceObject.settings.type == "bar") then
self.manager:TransferBar(sourceObject.objectID, sourceObject.parent, sender.targetObject);
else
self.manager:TransferGroup(sourceObject.objectID, sourceObject.parent, sender.targetObject);
end
else
-- Reattach to tree
self.carrierWindow:SetVisible(false);
sender.node:SetColumnWidth(3, ShowHideButton.buttonWidth);
sender.originalParentNode:InsertChild(sender.node, sender.originalChildNumber);
sender.detached = false;
end
end
end
end
return newNode;
end