RotationTimesControl = class(Turbine.UI.Control);
function RotationTimesControl:Constructor(timeSpec)
Turbine.UI.Control.Constructor(self);
if (not timeSpec) then
local numDays, hour = 3, 3;
local day = Time():GetDayInRotation(numDays, hour);
timeSpec = day .. "/" .. numDays .. ":" .. hour;
end
self:SetTimeSpec(timeSpec);
self.endOfToday = Time():GetNextServerResetTime():GetGameTime();
self:SetWantsUpdates(true); -- monitor for daily reset time
end
function RotationTimesControl:Destroy()
self:SetWantsUpdates(false);
end
function RotationTimesControl:SetTimeSpec(timeSpec)
self.schedule = Schedule(timeSpec);
self.valid = true;
self:Redraw();
end
function RotationTimesControl:Update()
local currentTime = Turbine.Engine.GetGameTime();
if (currentTime > self.endOfToday) then
-- Daily reset time passed. Need to update the selected day.
self.endOfToday = self.endOfToday + Time.lengthOfDay();
self:Redraw();
end
end
function RotationTimesControl:GetTimeSpec()
return self.schedule:GetStr(); -- will return nil in lieu of ""
end
function RotationTimesControl:Redraw()
self:GetControls():Clear();
local font = Turbine.UI.Lotro.Font.Verdana14;
function AddXButton(parent, left, top)
local button = Turbine.UI.Control();
button:SetParent(parent);
button:SetSize(16, 16);
button:SetPosition(left, top);
button:SetBackground(0x41000196);
button:SetBlendMode(Turbine.UI.BlendMode.Overlay);
button.MouseEnter = function(ctl) ctl:SetBackground(0x41000198) end;
button.MouseLeave = function(ctl) ctl:SetBackground(0x41000196) end;
button.MouseDown = function(ctl) ctl:SetBackground(0x41000197) end;
button.MouseUp = function(ctl) ctl:SetBackground(0x41000198) end;
Thurallor.UI.Tooltip(L:GetText("/RotationTimesControl/DeleteThisRotationTime")):Attach(button);
return button, left + 16, top + 16;
end
local function AddNudger(parent, left, top, value, minValue, maxValue)
local nudger = Nudger(parent, font, value, minValue, maxValue);
AddCallback(nudger, "FocusGained", function()
DoCallbacks(self, "FocusGained");
end);
nudger:SetPosition(left, top);
nudger:SetWidth(30);
return nudger, left + 30, top + nudger:GetHeight();
end
local function AddLabel(parent, left, top, text)
local label = Turbine.UI.Label();
label:SetFont(font);
label:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);
label:SetText(text);
label:SetMultiline(false);
label:AutoSize();
label:SetSize(label:GetWidth() + 8, 20)
label:SetParent(parent);
label:SetPosition(left, top);
return label, left + label:GetWidth(), top + 20;
end
local function AddRotationTime(top, numDays, availableDays)
local container = Turbine.UI.Control();
container:SetParent(self);
container:SetPosition(0, top);
local left, label = 0;
local text = L:GetText("/RotationTimesControl/InEvery");
text = text:gsub("<number>", #availableDays);
label, left = AddLabel(container, left, 13, text);
local nudger;
nudger, left = AddNudger(container, left, 0, numDays, 2, 10);
nudger.prevValue = numDays;
AddCallback(nudger, "ValueChanged", function(ctl)
local newValue = tonumber(ctl:GetText());
self:ChangeRotationLength(ctl.prevValue, newValue);
self:Redraw();
end);
container.nudger = nudger;
label, left = AddLabel(container, left, 13, L:GetText("/RotationTimesControl/DaysIncluding"));
-- Functions for converting between day number and the pulldown menu index
local currentDay = Time():GetDayInRotation(numDays, 3);
local function day_to_index(day)
return 1 + (numDays + day - currentDay) % numDays;
end
local function index_to_day(index)
return 1 + (index + currentDay - 2) % numDays;
end
-- Sort availableDays by the pulldown menu index
table.sort(availableDays, function(day1, day2)
local index1 = day_to_index(day1);
local index2 = day_to_index(day2);
return (index1 < index2);
end);
-- Add pulldown menu for each day in availableDays
for d, day in ipairs(availableDays) do
local dayOfWeekCtl = DayOfWeekControl(numDays, day_to_index(day));
dayOfWeekCtl:SetParent(container);
dayOfWeekCtl:SetPosition(left, 14 + top);
dayOfWeekCtl.prevDay = day;
AddCallback(dayOfWeekCtl, "SelectionChanged", function(ctl, index)
self:RemoveDayFromSchedule(numDays, ctl.prevDay);
self:AddDayToSchedule(numDays, index_to_day(index));
self:Redraw();
end);
container["dayOfWeekCtl" .. tostring(d)] = dayOfWeekCtl;
if (#availableDays > 1) then
local xButton = AddXButton(container, left + dayOfWeekCtl:GetWidth() + 2, 16 + top);
xButton.day = day;
xButton.MouseClick = function(ctl, args)
if (args.Button == Turbine.UI.MouseButton.Left) then
self:RemoveDayFromSchedule(numDays, ctl.day);
self:Redraw();
end
end
container["xButton" .. tostring(d)] = xButton;
end
top = top + dayOfWeekCtl:GetHeight() + 2;
end
-- Add "..." control which adds another day
if (#availableDays < numDays - 1) then
local addDayCtl = DayOfWeekControl(numDays, 0);
addDayCtl:SetParent(container);
addDayCtl:SetPosition(left, 14 + top);
top = top + addDayCtl:GetHeight() + 2;
AddCallback(addDayCtl, "SelectionChanged", function(_, index)
local day = 1 + (index + currentDay - 2) % numDays;
self:AddDayToSchedule(numDays, day);
self:Redraw();
end);
container.addDayCtl = addDayCtl;
end
container:AutoSize(true);
return container, container:GetHeight(), container:GetWidth();
end
self:GetControls():Clear();
collectgarbage();
-- For now, we only support a single 'numDays' value, although there can be more than one 'day'.
-- For now, we only support 'hour' = 3.0.
local rotationLengthDays;
local availableDays = {};
for numDays, day, hour in self.schedule:rotation_entries() do
if (not rotationLengthDays or (rotationLengthDays == numDays)) then
rotationLengthDays = numDays;
table.insert(availableDays, day);
end
end
local top, width, box = 0, 0;
box, top, width = AddRotationTime(top, rotationLengthDays, availableDays);
self:SetSize(width, top);
end
function RotationTimesControl:AddDayToSchedule(numDays, day)
self.schedule:AddTimeOfRotation(numDays, day, 3);
DoCallbacks(self, "ValueChanged");
end
function RotationTimesControl:RemoveDayFromSchedule(numDays, day)
local newSchedule = Schedule();
for _numDays, _day, _hour in self.schedule:rotation_entries() do
if ((numDays ~= _numDays) or (day ~= _day)) then
newSchedule:AddTimeOfRotation(_numDays, _day, _hour);
end
end
self.schedule = newSchedule;
DoCallbacks(self, "ValueChanged");
end
function RotationTimesControl:ChangeRotationLength(oldNumDays, newNumDays)
local newSchedule = Schedule();
local retained = 0;
for _numDays, _day, _hour in self.schedule:rotation_entries() do
if (retained < newNumDays - 1) then
if (_numDays == oldNumDays) then
local oldTime = Time():SetDayInRotation(oldNumDays, _day, _hour);
_day = oldTime:GetDayInRotation(newNumDays, _hour);
retained = retained + 1;
end
newSchedule:AddTimeOfRotation(newNumDays, _day, _hour);
end
end
self.schedule = newSchedule;
DoCallbacks(self, "ValueChanged");
end