QuestRepeatedDialog = class(Turbine.UI.Lotro.Window);
QuestRepeatedDialog.instances = {};
local importPath = getfenv(1)._.Name;
local imagePath = string.gsub(string.gsub(importPath, "%.QuestRepeatedDialog$", ""), "%.", "/") .. "/Images/";
function QuestRepeatedDialog.GetInstance(win, quest, settings, charSettings, charID)
if (QuestRepeatedDialog.instances[quest]) then
return QuestRepeatedDialog.instances[quest];
end
return QuestRepeatedDialog(win, quest, settings, charSettings, charID);
end
function QuestRepeatedDialog:Constructor(win, quest, settings, charSettings, charID)
-- Enforce only one such window per quest
if (QuestRepeatedDialog.instances[quest]) then
error("Dialog exists", 3);
end
QuestRepeatedDialog.instances[quest] = self;
Turbine.UI.Lotro.Window.Constructor(self);
local prevContext = L:SetContext("/QuestRepeatedDialog");
self:SetText(L:GetText("Title"));
self:SetVisible(true);
self:SetZOrder(win:GetZOrder() + 1);
self:SetSize(600, 0);
self.window = win;
self.charID = charID or win.charID;
self.charName = win:GetCharNameWithServer(charID);
self.quest = quest;
self.settings = settings;
self.charSettings = charSettings;
self.enabled = settings.enabled or false;
self.currentDesc = settings.desc;
self.currentLoc = settings.location;
self.currentCat = settings.category;
self.currentTab = settings.tab;
if (settings.cooldown) then
self.currentMode = "delay";
elseif (settings.rotation) then
self.currentMode = "rotation";
else -- (settings.resetTimes)
self.currentMode = "resetTimes";
end
self.elapsedMinutes = math.floor(0.5 + (Turbine.Engine.GetGameTime() - settings.lastCompleted) / 60) * 60;
local elapsedHours = math.floor(self.elapsedMinutes / 3600) * 3600;
self.resetTimesCtl = ResetTimesControl(settings.resetTimes, false);
AddCallback(self.resetTimesCtl, "SizeChanged", function()
self:DoLayout();
end);
AddCallback(self.resetTimesCtl, "ValidChanged", function (_, valid)
self.okButton:SetEnabled(valid);
end);
self.delayCtl = DelayControl(true, true, true, false);
self.delayCtl:SetDelay(settings.cooldown or elapsedHours);
self.rotationTimesCtl = RotationTimesControl(settings.rotation);
AddCallback(self.rotationTimesCtl, "SizeChanged", function()
self:DoLayout();
end);
-- Handle ENTER and ESC keys
EnableEnterEscHandling(self);
L:SetContext(prevContext);
self:DoLayout();
if (win.settings.questRepeatedDialog.position) then
self:SetPosition(unpack(win.settings.questRepeatedDialog.position));
SetUniquePosition(self, QuestRepeatedDialog.instances);
else
CenterWindow(self);
end
end
function QuestRepeatedDialog:PositionChanged()
self.window.settings.questRepeatedDialog.position = {self:GetPosition()};
self.window:SaveSettings();
end
function QuestRepeatedDialog:DoLayout()
local settings = self.settings;
local label, textBox, checkBox;
local xmargin = 28;
local width = self:GetWidth() - 2 * xmargin;
local function AddLabel(parent, top, text, height)
local label = Turbine.UI.Label();
label:SetFont(Turbine.UI.Lotro.Font.Verdana14);
label:SetFontStyle(Turbine.UI.FontStyle.Outline);
label:SetOutlineColor(Turbine.UI.Color.Black);
label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
label:SetText(text);
label:SetParent(parent);
label:SetPosition(xmargin, top);
label:SetSize(width, height);
return label, top + height + 10;
end
local function AddCheckBox(parent, top, text, expanded)
local checkBox = Turbine.UI.Lotro.CheckBox();
checkBox:SetFont(Turbine.UI.Lotro.Font.Verdana14);
checkBox:SetFontStyle(Turbine.UI.FontStyle.Outline);
checkBox:SetOutlineColor(Turbine.UI.Color.Black);
checkBox:SetParent(parent);
checkBox:SetPosition(2 * xmargin, top);
checkBox:SetChecked(expanded);
if (expanded) then
text = text .. L:GetText("Colon");
end
checkBox:SetText(" " .. text);
checkBox:AutoSize();
return checkBox, top + 24;
end
local function AddRadioButton(parent, top, text, selected, expanded)
if (expanded) then
text = text .. L:GetText("Colon");
end
local button = Thurallor.UI.RadioButton(parent, text, selected);
button:SetFont(Turbine.UI.Lotro.Font.Verdana14);
button:SetPosition(2 * xmargin, top);
button:SetSize(width, 14);
return button, top + 20;
end
local function AddTextBox(parent, top, value)
local textBox = Turbine.UI.Lotro.TextBox();
textBox:SetParent(parent);
textBox:SetSelectable(true);
textBox:SetMultiline(false);
textBox:SetFont(Turbine.UI.Lotro.Font.Verdana14);
textBox:SetForeColor(Turbine.UI.Color.PaleGoldenrod);
textBox:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
textBox:SetText(value);
textBox:SetPosition(2 * xmargin + L:GetText("ColumnWidth"), top);
textBox:SetSize(width - textBox:GetLeft(), 22);
return textBox, top + 34;
end
function AddDropDown(parent, top, indent, items, selectedItem)
local dropDown = Thurallor.UI.DropDown(items, selectedItem);
dropDown:SetParent(parent);
dropDown:SetFont(Turbine.UI.Lotro.Font.Verdana14);
dropDown:SetPosition(2 * xmargin + indent, top);
dropDown:SetSize(width - dropDown:GetLeft(), 22);
dropDown:SetAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
return dropDown, top + 34;
end
self:GetControls():Clear();
collectgarbage();
local prevContext = L:SetContext("/QuestRepeatedDialog");
local top = 39;
local highlight = Turbine.UI.Control();
highlight:SetBlendMode(Turbine.UI.BlendMode.Overlay);
highlight:SetBackground(imagePath .. "options_panel_divider.tga");
highlight:SetParent(self);
highlight:SetSize(400, 30);
highlight:SetPosition(math.floor(0.5 + (self:GetWidth() - 400)/2), top);
label, top = AddLabel(self, top, self.quest, 30);
label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
label:SetFont(Turbine.UI.Lotro.Font.TrajanPro20);
label:SetForeColor(Turbine.UI.Color.Yellow);
top = top - 10;
label, top = AddLabel(self, top, self.charName, 14);
label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
label:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
label:SetForeColor(Turbine.UI.Color.Silver);
top = top + 10; -- skip some space
local text = L:GetText("Question");
text = string.gsub(text, "<elapsed>", Time.GetDelayStr(self.elapsedMinutes));
label, top = AddLabel(self, top, text, 14 * L:GetText("QuestionLines"));
label:SetTextAlignment(Turbine.UI.ContentAlignment.BottomLeft);
yesButton, top = AddRadioButton(self, top, L:GetText("Yes"), self.enabled);
yesButton.Clicked = function()
self.enabled = true;
self:DoLayout();
end
noButton, top = AddRadioButton(self, top, L:GetText("No"), not self.enabled);
noButton.Clicked = function()
self.enabled = false;
self:DoLayout();
end
Thurallor.UI.RadioButton.LinkPeers({ yesButton, noButton });
if (self.enabled) then
top = top + 10; -- skip some space
label, top = AddLabel(self, top, L:GetText("Customize") .. L:GetText("Colon"), 14);
checkBox, top = AddCheckBox(self, top, L:GetText("/MainWindow/ColumnHeadings/Description"), self.currentDesc);
if (self.currentDesc) then
self.desc = AddTextBox(self, top - 27, self.currentDesc);
self.desc.TextChanged = function(ctl)
self.currentDesc = ctl:GetText();
end
self.desc.FocusLost = function(ctl)
self:DoLayout();
end
end
checkBox.CheckedChanged = function(ctl)
self.currentDesc = (ctl:IsChecked() and (settings.desc or self.quest)) or nil;
self:DoLayout();
end
checkBox, top = AddCheckBox(self, top, L:GetText("/MainWindow/ColumnHeadings/Location"), self.currentLoc);
if (self.currentLoc) then
self.location = AddTextBox(self, top - 27, self.currentLoc);
self.location.TextChanged = function(ctl)
self.currentLoc = ctl:GetText();
end
local cmd = "/" .. L:GetText("/ShellCommand/Command") .. " " .. L:GetText("/ShellCommand/SetLoc") .. " " .. L:GetClientLanguageText("/Chat/loc");
local getLocButton = Thurallor.UI.TrickButton(cmd, Turbine.ChatType.Standard, nil);
getLocButton:SetParent(self);
getLocButton:SetFont(Turbine.UI.Lotro.Font.Verdana14);
getLocButton:SetText(L:GetText("GetCurrentLocation"));
getLocButton:SetWidth(L:GetText("GetCurrentLocationWidth"));
getLocButton:SetPosition(width - getLocButton:GetWidth(), self.location:GetTop() + 1);
AddCallback(getLocButton, "MouseEnter", function()
self.window.LocationChanged = function()
self.currentLoc = self.window.location;
self.location:SetText(self.currentLoc);
end
end);
self.location:SetWidth(getLocButton:GetLeft() - self.location:GetLeft() - 4);
end
checkBox.CheckedChanged = function(ctl)
self.currentLoc = (ctl:IsChecked() and (settings.location or "")) or nil;
self:DoLayout();
end
local catNames, catExists = self.window:GetUserCategories();
checkBox, top = AddCheckBox(self, top, L:GetText("/MainWindow/ColumnHeadings/Category"), self.currentCat);
if (self.currentCat) then
dropDown = AddDropDown(self, top - 27, L:GetText("ColumnWidth"), catNames, self.currentCat);
dropDown:SetWidth(200);
dropDown.SelectionChanged = function(ctl, args)
self.currentCat = args.Item;
self:DoLayout();
end
end
checkBox.CheckedChanged = function(ctl)
self.currentCat = (ctl:IsChecked() and (settings.category or self.charSettings.autoReminders.quests.category)) or nil;
self:DoLayout();
end
local tabNames, tabExists = self.window:GetUserTabs();
checkBox, top = AddCheckBox(self, top, L:GetText("Tab"), self.currentTab);
if (self.currentTab) then
dropDown = AddDropDown(self, top - 27, L:GetText("ColumnWidth"), tabNames, self.currentTab);
dropDown:SetWidth(200);
dropDown.SelectionChanged = function(ctl, args)
self.currentTab = args.Item;
self:DoLayout();
end
end
checkBox.CheckedChanged = function(ctl)
self.currentTab = (ctl:IsChecked() and (settings.tab or self.charSettings.autoReminders.quests.tab or self.charSettings.frontTab)) or nil;
self:DoLayout();
end
self.tabCheckBox = checkBox;
top = top + 10; -- skip some space
label, top = AddLabel(self, top, L:GetText("QuestCanBeRepeated"), 14);
local expanded = (self.currentMode == "resetTimes");
self.resetTimeButton, top = AddRadioButton(self, top, L:GetText("WhenItResets"), expanded, expanded);
if (expanded) then
self.resetTimesCtl:SetParent(self);
self.resetTimesCtl:SetPosition(math.floor(0.5 + (self:GetWidth() - self.resetTimesCtl:GetWidth()) / 2), top);
top = top + self.resetTimesCtl:GetHeight();
else
self.resetTimeButton.Clicked = function()
self.currentMode = "resetTimes";
self:DoLayout();
end
end
local expanded = (self.currentMode == "delay");
self.delayButton, top = AddRadioButton(self, top + 4, L:GetText("AfterCooldownTime"), expanded, expanded);
if (expanded) then
self.delayCtl:SetParent(self);
self.delayCtl:SetPosition(math.floor(0.5 + (self:GetWidth() - self.delayCtl:GetWidth()) / 2), top);
top = top + self.delayCtl:GetHeight();
self.delayCtl.FocusGained = function()
self.delayButton:MouseClick();
end
else
self.delayButton.Clicked = function()
self.currentMode = "delay";
self:DoLayout();
end
end
local expanded = (self.currentMode == "rotation");
self.rotationButton, top = AddRadioButton(self, top + 4, L:GetText("WhenAvailableOnARotation"), expanded, expanded);
if (expanded) then
self.rotationTimesCtl:SetParent(self);
self.rotationTimesCtl:SetPosition(math.floor(0.5 + (self:GetWidth() - self.rotationTimesCtl:GetWidth()) / 2), top);
top = top + self.rotationTimesCtl:GetHeight();
else
self.rotationButton.Clicked = function()
self.currentMode = "rotation";
self:DoLayout();
end
end
Thurallor.UI.RadioButton.LinkPeers({ self.resetTimeButton, self.delayButton, self.rotationButton });
end
top = top + 10; -- skip some space
self.okButton = Turbine.UI.Lotro.Button();
self.okButton:SetFont(Turbine.UI.Lotro.Font.Verdana14);
self.okButton:SetParent(self);
local reuseExpiredReminders = self.window.settings.reuseExpiredReminders;
local nowText = L:GetText("/QuestRepeatedDialog/CreateNow");
local nowTooltipText = L:GetText("/QuestRepeatedDialog/CreateNowTooltip");
if (reuseExpiredReminders) then
local tabName = settings.tab or self.charSettings.autoReminders.quests.tab or self.charSettings.frontTab;
local desc = settings.desc or self.quest;
local cat = settings.category or self.charSettings.autoReminders.quests.category;
if (self.enabled) then
tabName = self.currentTab or tabName;
desc = self.currentDesc or desc;
cat = self.currentCat or cat;
end
if (self.window:FindOldestMatchingEvent(tabName, desc, self.charID, cat)) then
nowText = L:GetText("/QuestRepeatedDialog/UpdateNow");
nowTooltipText = L:GetText("/QuestRepeatedDialog/UpdateNowTooltip");
end
end
self.nowCheckbox = AddCheckBox(self, top + 2, nowText);
self.nowCheckbox:SetChecked(reuseExpiredReminders);
if (self.enabled) then
self.okButton:SetText(L:GetText("/QuestRepeatedDialog/RemindMe"));
self.okButton:AutoSize();
Thurallor.UI.Tooltip(nowTooltipText):Attach(self.nowCheckbox);
else
self.okButton:SetText(L:GetText("/QuestRepeatedDialog/DontRemindMe"));
self.okButton:AutoSize();
self.nowCheckbox:SetParent(nil);
end
self.okButton:SetPosition((self:GetWidth() - self.okButton:GetWidth()) / 2, top);
self.nowCheckbox:SetLeft(self:GetWidth() * 3 / 4 - self.nowCheckbox:GetWidth() / 2);
top = top + self.okButton:GetHeight();
self:SetHeight(top + 24);
L:SetContext(prevContext);
self.okButton.SetEnabled = function(_, enable)
-- Lotro.Button can't get mouse events while disabled. Need to superimpose another control.
if (enable and not self.okButton:IsEnabled()) then
self.okMask:SetParent(nil);
self.okMask = nil;
elseif (not enable and self.okButton:IsEnabled()) then
self.okMask = Turbine.UI.Control();
self.okMask:SetParent(self.okButton);
self.okMask:SetSize(self.okButton:GetSize());
Thurallor.UI.Tooltip(L:GetText("/ResetTimesDialog/NotOkTooltip")):Attach(self.okMask);
end
Turbine.UI.Lotro.Button.SetEnabled(self.okButton, enable);
end
self.okButton.Click = function()
settings.enabled = self.enabled;
settings.desc = self.currentDesc;
settings.location = self.currentLoc;
settings.category = self.currentCat;
settings.tab = self.currentTab;
if (self.currentMode == "resetTimes") then
settings.resetTimes = self.resetTimesCtl:GetTimeSpec();
settings.cooldown = nil;
settings.rotation = nil;
elseif (self.currentMode == "delay") then
settings.resetTimes = nil;
settings.cooldown = self.delayCtl:GetDelay();
settings.rotation = nil;
else -- (self.currentMode == "rotation")
settings.resetTimes = nil;
settings.cooldown = nil;
settings.rotation = self.rotationTimesCtl:GetTimeSpec();
end
if (self.enabled and self.nowCheckbox:IsChecked()) then
local event = self.window:AddQuestReminder(self.quest, self.charID, true);
if (event) then
event:ZoomToEvent(self);
end
end
self.window:SaveSettings();
self.window:UpdateOptionsPanel();
DoCallbacks(self, "Accepted");
self:Close();
end
end
function QuestRepeatedDialog:EnterKeyPressed()
DoCallbacks(self.okButton, "Click");
end
function QuestRepeatedDialog:EscapeKeyPressed()
self:Close();
end
function QuestRepeatedDialog:Closing()
QuestRepeatedDialog.instances[self.quest] = nil;
self.rotationTimesCtl:Destroy();
end