You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3848 lines
128 KiB
3848 lines
128 KiB
local _, addon = ...
|
|
local StatCardController = addon.StatCardController;
|
|
local GetCategoryNumAchievements = addon.GetCustomCategoryNumAchievements;
|
|
local IsBossCard = addon.IsBossCard;
|
|
local GetStatisticInfo = addon.GetStatisticInfo;
|
|
local DataProvider = addon.DataProvider;
|
|
local PinUtil = addon.PinUtil;
|
|
|
|
--Constant
|
|
local NUM_ACHIEVEMENT_CARDS = 8;
|
|
local LEGACY_ID = 15234;
|
|
local FEAT_OF_STRENGTH_ID = 81;
|
|
--local GUILD_FEAT_OF_STRENGTH_ID = 15093;
|
|
--local GUILD_CATEGORY_ID = 15076;
|
|
|
|
local sin = math.sin;
|
|
local cos = math.cos;
|
|
local abs = math.abs;
|
|
local min = math.min;
|
|
local max = math.max;
|
|
local sqrt = math.sqrt;
|
|
local pow = math.pow;
|
|
local pi = math.pi;
|
|
local floor = math.floor;
|
|
local ceil = math.ceil;
|
|
local After = C_Timer.After;
|
|
local gsub = string.gsub;
|
|
local bband = bit.band;
|
|
local format = string.format;
|
|
local tremove = table.remove;
|
|
local tinsert = table.insert;
|
|
|
|
local GetAchievementNumCriteria = GetAchievementNumCriteria;
|
|
local GetAchievementCriteriaInfo = GetAchievementCriteriaInfo;
|
|
local GetRewardItemID = C_AchievementInfo.GetRewardItemID;
|
|
local GetPreviousAchievement = GetPreviousAchievement;
|
|
local GetNextAchievement = GetNextAchievement;
|
|
local SetFocusedAchievement = SetFocusedAchievement; --Requset guild achievement progress from server, will fire "CRITERIA_UPDATE" after calling GetAchievementCriteriaInfo()
|
|
local FadeFrame = NarciFadeUI.Fade;
|
|
local GetParentAchievementID = NarciAPI.GetParentAchievementID;
|
|
local L = Narci.L;
|
|
|
|
local function linear(t, b, e, d)
|
|
return (e - b) * t / d + b
|
|
end
|
|
|
|
local function outSine(t, b, e, d)
|
|
return (e - b) * sin(t / d * (pi / 2)) + b
|
|
end
|
|
|
|
local function inOutSine(t, b, e, d)
|
|
return (b - e) / 2 * (cos(pi * t / d) - 1) + b
|
|
end
|
|
|
|
local function outQuart(t, b, e, d)
|
|
t = t / d - 1;
|
|
return (b - e) * (pow(t, 4) - 1) + b
|
|
end
|
|
|
|
addon.outQuart = outQuart;
|
|
|
|
--FormatShortDate Derivated from FormatShortDate (Util.lua)
|
|
local FormatDate;
|
|
if LOCALE_enGB then
|
|
function FormatDate(day, month, year, twoRowMode)
|
|
if (year) then
|
|
if twoRowMode then
|
|
return format("%1$d/%2$d\n20%3$02d", day, month, year);
|
|
else
|
|
return format("%1$d/%2$d/%3$02d", day, month, year);
|
|
end
|
|
else
|
|
return format("%1$d/%2$d", day, month);
|
|
end
|
|
end
|
|
else
|
|
function FormatDate(day, month, year, twoRowMode)
|
|
if (year) then
|
|
if twoRowMode then
|
|
return format("%2$d/%1$02d\n20%3$02d", day, month, year);
|
|
else
|
|
return format("%2$d/%1$02d/%3$02d", day, month, year);
|
|
end
|
|
else
|
|
return format("%2$d/%1$02d", day, month);
|
|
end
|
|
end
|
|
end
|
|
|
|
local themeID = 0;
|
|
local showNotEarnedMark = false;
|
|
local isDarkTheme = true;
|
|
local isGuildView = false;
|
|
local texturePrefix = "Interface\\AddOns\\Narcissus_Achievements\\Art\\DarkWood\\";
|
|
|
|
local function ReskinButton(button)
|
|
--if true then return end
|
|
button.border:SetTexture(texturePrefix.."AchievementCardBorder");
|
|
button.background:SetTexture(texturePrefix.."AchievementCardBackground");
|
|
button.bottom:SetTexture(texturePrefix.."AchievementCardBackground");
|
|
button.lion:SetTexture(texturePrefix.."Lion");
|
|
button.mask:SetTexture(texturePrefix.."AchievementCardBorderMask");
|
|
local isDarkTheme = isDarkTheme;
|
|
button.RewardFrame.background:SetShown(not isDarkTheme);
|
|
button.RewardFrame.rewardNodeLeft:SetShown(isDarkTheme);
|
|
button.RewardFrame.rewardNodeRight:SetShown(isDarkTheme);
|
|
button.RewardFrame.rewardLineLeft:SetShown(isDarkTheme);
|
|
button.RewardFrame.rewardLineRight:SetShown(isDarkTheme);
|
|
button.RewardFrame.reward:SetPoint("BOTTOM", button.RewardFrame, "BOTTOM", 0, (isDarkTheme and 3) or 1);
|
|
|
|
if isDarkTheme then
|
|
button.description:SetFontObject(NarciAchievementText);
|
|
else
|
|
button.description:SetFontObject(NarciAchievementTextBlack);
|
|
end
|
|
button.isDarkTheme = isDarkTheme;
|
|
|
|
--Reposition Elements
|
|
button.icon:ClearAllPoints();
|
|
button.lion:ClearAllPoints();
|
|
button.date:ClearAllPoints();
|
|
button.NotEarned:ClearAllPoints();
|
|
if showNotEarnedMark then
|
|
button.NotEarned:SetWidth(20);
|
|
else
|
|
button.NotEarned:SetWidth(0.1);
|
|
end
|
|
if themeID == 3 then
|
|
button.icon:SetPoint("CENTER", button.border, "LEFT", 32, 0);
|
|
button.lion:SetPoint("CENTER", button.border, "RIGHT", -28, -1);
|
|
button.date:SetPoint("RIGHT", button.border, "TOPRIGHT", -54, -25);
|
|
button.NotEarned:SetPoint("TOPLEFT", button.icon, "TOPRIGHT", 6, -2);
|
|
else
|
|
button.icon:SetPoint("CENTER", button.border, "LEFT", 27, 4);
|
|
button.lion:SetPoint("CENTER", button.border, "RIGHT", -22, 3);
|
|
button.date:SetPoint("RIGHT", button.border, "TOPRIGHT", -48, -25);
|
|
button.NotEarned:SetPoint("TOPLEFT", button.icon, "TOPRIGHT", 7, -6.5);
|
|
end
|
|
|
|
button.isDark = nil;
|
|
end
|
|
|
|
|
|
local MainFrame, InspectionFrame, MountPreview, Tooltip, ReturnButton, SummaryButton, GoToCategoryButton, FilterButton;
|
|
local CategoryContainer, AchievementContainer, DIYContainer, EditorContainer, SummaryFrame, AchievementCards, TabButtons;
|
|
local UpdateSummaryFrame;
|
|
|
|
local TabUtil = {};
|
|
addon.TabUtil = TabUtil;
|
|
|
|
local CategoryButtons = {
|
|
player = { parentButtons = {}, buttons = {}, },
|
|
guild = { parentButtons = {}, buttons = {}, },
|
|
stats = { parentButtons = {}, buttons = {}, },
|
|
};
|
|
|
|
local IS_STAT_CATEGORY = {
|
|
[-2] = true, --Used to show pinned statistics
|
|
};
|
|
|
|
function CategoryButtons:GetActiveParentButtons(tabID)
|
|
tabID = tabID or TabUtil.tabID;
|
|
if tabID == 1 then
|
|
return self.player.parentButtons;
|
|
elseif tabID == 2 then
|
|
return self.guild.parentButtons;
|
|
elseif tabID == 3 then
|
|
return self.stats.parentButtons;
|
|
end
|
|
end
|
|
|
|
local CategoryStructure = {
|
|
player = {},
|
|
guild = {},
|
|
stats = {},
|
|
};
|
|
|
|
local function IsAccountWide(flags)
|
|
--ACHIEVEMENT_FLAGS_ACCOUNT
|
|
if flags then
|
|
return bband(flags, 131072) == 131072
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
addon.IsAccountWide = IsAccountWide;
|
|
|
|
|
|
local ScrollUtil = {}; --DataProvider for ScrollFrame
|
|
|
|
--Limit the request frequency
|
|
local processor = CreateFrame("Frame");
|
|
processor:Hide();
|
|
processor:SetScript("OnUpdate", function(self, elapsed)
|
|
local processComplete;
|
|
self.cycle = self.cycle + 1;
|
|
if self.func then
|
|
self.arg2, processComplete = self.func(self.arg1, self.arg2);
|
|
if processComplete then
|
|
self:Hide();
|
|
self.func = nil;
|
|
self.callback();
|
|
if self.cycle == 2 then
|
|
ScrollUtil:UpdateScrollChild(0);
|
|
end
|
|
end
|
|
if self.cycle == 3 then
|
|
ScrollUtil:UpdateScrollChild(0);
|
|
end
|
|
else
|
|
self:Hide();
|
|
end
|
|
end)
|
|
|
|
function processor:Start()
|
|
local processComplete;
|
|
if self.func then
|
|
self.cycle = 1;
|
|
self.arg2, processComplete = self.func(self.arg1, self.arg2);
|
|
if processComplete then
|
|
self:Hide();
|
|
self.func = nil;
|
|
self.callback();
|
|
|
|
--Achievement Card Data is being constructed by OnUpdate script
|
|
--The step is 4: Meaning it takes 2 frames to build the visible area
|
|
--Update scrollframe on the 3rd frame
|
|
ScrollUtil:UpdateScrollChild(0);
|
|
else
|
|
self:Show();
|
|
end
|
|
else
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------------------------------------------------
|
|
local function HideItemPreview()
|
|
GameTooltip:Hide();
|
|
if MountPreview:IsShown() then
|
|
MountPreview:FadeOut();
|
|
end
|
|
MountPreview:ClearCallback();
|
|
end
|
|
|
|
|
|
local animFlyIn = NarciAPI_CreateAnimationFrame(0.45);
|
|
local animFlyOut = NarciAPI_CreateAnimationFrame(0.25);
|
|
|
|
animFlyIn:SetScript("OnUpdate", function(self, elapsed)
|
|
self.total = self.total + elapsed;
|
|
local alpha = outQuart(self.total, self.fromAlpha, 1, self.duration);
|
|
local scale = outQuart(self.total, 0.5, 1, 0.2);
|
|
|
|
if self.total >= 0.2 then
|
|
scale = 1;
|
|
local textAlpha = outQuart(self.total - 0.2, 0, 1, 0.2);
|
|
if textAlpha > 1 then
|
|
textAlpha = 1;
|
|
elseif textAlpha < 0 then
|
|
textAlpha = 0;
|
|
end
|
|
self.header:SetAlpha(textAlpha);
|
|
self.description:SetAlpha(textAlpha);
|
|
self.date:SetAlpha(textAlpha);
|
|
self.reward:SetAlpha(textAlpha);
|
|
end
|
|
|
|
if self.total >= self.duration then
|
|
alpha = 1;
|
|
--offsetX = 0;
|
|
--offsetY = 0;
|
|
scale = 1;
|
|
self.header:SetAlpha(1);
|
|
self.description:SetAlpha(1);
|
|
self.date:SetAlpha(1);
|
|
self.reward:SetAlpha(1);
|
|
self:Hide();
|
|
end
|
|
|
|
if alpha > 1 then
|
|
alpha = 1;
|
|
elseif alpha < 0 then
|
|
alpha = 0;
|
|
end
|
|
self.background:SetAlpha(alpha);
|
|
self.ObjectiveFrame:SetAlpha(alpha);
|
|
self.ChainFrame:SetAlpha(alpha);
|
|
self.Card:SetScale(scale);
|
|
end)
|
|
|
|
|
|
function animFlyIn:Play()
|
|
self:Hide();
|
|
self.Card:SetAlpha(1);
|
|
self.header:SetAlpha(0);
|
|
self.description:SetAlpha(0);
|
|
self.date:SetAlpha(0);
|
|
self.reward:SetAlpha(0);
|
|
self.fromAlpha = self.background:GetAlpha();
|
|
animFlyOut:Hide();
|
|
self:Show();
|
|
end
|
|
|
|
|
|
animFlyOut:SetScript("OnUpdate", function(self, elapsed)
|
|
self.total = self.total + elapsed;
|
|
local offsetX = inOutSine(self.total, self.fromX, self.toX, self.duration);
|
|
local offsetY = outSine(self.total, self.fromY, self.toY, self.duration);
|
|
local alpha = outQuart(self.total, 1, 0, self.duration);
|
|
if self.total >= self.duration then
|
|
offsetX = self.toX;
|
|
offsetY = self.toY;
|
|
alpha = 0;
|
|
InspectionFrame:Hide();
|
|
if self.button then
|
|
self.button:Show();
|
|
end
|
|
self.noTranslation = nil;
|
|
self:Hide();
|
|
end
|
|
self.background:SetAlpha(alpha);
|
|
self.ObjectiveFrame:SetAlpha(alpha);
|
|
self.ChainFrame:SetAlpha(alpha);
|
|
if self.noTranslation then
|
|
self.Card:SetAlpha(alpha);
|
|
else
|
|
self.Card:SetPoint("BOTTOM", InspectionFrame, "CENTER", offsetX, offsetY);
|
|
end
|
|
end)
|
|
|
|
function animFlyOut:Play()
|
|
animFlyIn:Hide();
|
|
self:Hide();
|
|
if self.button then
|
|
--achievement button in the scrollframe
|
|
self.button:Hide();
|
|
end
|
|
local _;
|
|
_, _, _, self.fromX, self.fromY = self.Card:GetPoint();
|
|
self:Show();
|
|
HideItemPreview();
|
|
InspectionFrame.isTransiting = true;
|
|
InspectionFrame.HotkeyShiftClick:Hide();
|
|
InspectionFrame.HotkeyMouseWheel:Hide();
|
|
InspectionFrame.GetLink:Hide();
|
|
InspectionFrame.GoToCategoryButton:Hide();
|
|
InspectionFrame.Card.ParentAchievmentButton:Hide();
|
|
InspectionFrame.PrevButton:Hide();
|
|
InspectionFrame.NextButton:Hide();
|
|
end
|
|
|
|
------------------------------------------------------------------------------------------------------
|
|
local function DisplayProgress(id, flags)
|
|
local cData, iData = {}, {};
|
|
cData.names, iData.names = {}, {};
|
|
cData.icons, iData.icons = {}, {};
|
|
cData.assetIDs, iData.assetIDs = {}, {};
|
|
cData.bars, iData.bars = {}, {};
|
|
|
|
local numCompleted, numIncomplete = 0, 0;
|
|
--if ( not ( bit.band(flags, 128) == 128 ) ) then --ACHIEVEMENT_FLAGS_HAS_PROGRESS_BAR = 128!!
|
|
local numCriteria = GetAchievementNumCriteria(id);
|
|
if numCriteria == 0 then
|
|
numCompleted = 0;
|
|
numIncomplete = 0;
|
|
else
|
|
local criteriaString, criteriaType, completed, quantity, reqQuantity, charName, flags, assetID, quantityString;
|
|
for i = 1, numCriteria do
|
|
criteriaString, criteriaType, completed, quantity, reqQuantity, charName, flags, assetID, quantityString = GetAchievementCriteriaInfo(id, i);
|
|
--print("criteriaType: "..criteriaType)
|
|
if ( bband(flags, 1) == 1 ) then --EVALUATION_TREE_FLAG_PROGRESS_BAR = 1
|
|
if ( completed == false ) then
|
|
numIncomplete = numIncomplete + 1;
|
|
tinsert(iData.bars, {quantity, reqQuantity, criteriaString});
|
|
else
|
|
numCompleted = numCompleted + 1;
|
|
tinsert(cData.bars, {quantity, reqQuantity, criteriaString});
|
|
end
|
|
else
|
|
if ( completed == false ) then
|
|
numIncomplete = numIncomplete + 1;
|
|
criteriaString = "|CFF808080" .. criteriaString .. "|r";
|
|
tinsert(iData.names, criteriaString);
|
|
if criteriaType == 8 and assetID then --CRITERIA_TYPE_ACHIEVEMENT
|
|
local icon = DataProvider:GetAchievementInfo(assetID, 10);
|
|
iData.icons[numIncomplete] = icon;
|
|
iData.assetIDs[numIncomplete] = assetID;
|
|
end
|
|
else
|
|
numCompleted = numCompleted + 1;
|
|
criteriaString = "|CFF5fbb46" .. criteriaString .. "|r"; --00FF00
|
|
tinsert(cData.names, criteriaString);
|
|
if criteriaType == 8 and assetID then --CRITERIA_TYPE_ACHIEVEMENT
|
|
local icon = DataProvider:GetAchievementInfo(assetID, 10);
|
|
cData.icons[numCompleted] = icon;
|
|
cData.assetIDs[numCompleted] = assetID;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--end
|
|
|
|
cData.count = numCompleted;
|
|
iData.count = numIncomplete;
|
|
|
|
InspectionFrame:DisplayCriteria(cData, iData);
|
|
end
|
|
|
|
|
|
local InspectCard; --function
|
|
|
|
local function ShutInspection()
|
|
InspectionFrame:Hide();
|
|
end
|
|
|
|
local function ToggleTracking(id)
|
|
if not id then return end;
|
|
|
|
if DataProvider:IsTrackedAchievement(id) then
|
|
DataProvider:StopTracking(id);
|
|
else
|
|
local MAX_TRACKED_ACHIEVEMENTS = 10;
|
|
if ( DataProvider.numTrackedAchievements >= MAX_TRACKED_ACHIEVEMENTS ) then
|
|
UIErrorsFrame:AddMessage(format(ACHIEVEMENT_WATCH_TOO_MANY, MAX_TRACKED_ACHIEVEMENTS), 1.0, 0.1, 0.1, 1.0);
|
|
return;
|
|
end
|
|
|
|
local _, _, _, completed, _, _, _, _, _, _, _, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfo(id);
|
|
if ( (completed and isGuild) or wasEarnedByMe ) then
|
|
UIErrorsFrame:AddMessage(ERR_ACHIEVEMENT_WATCH_COMPLETED, 1.0, 0.1, 0.1, 1.0);
|
|
return;
|
|
end
|
|
|
|
DataProvider:StartTracking(id);
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function ProcessModifiedClick(button)
|
|
local achievementID = button.id;
|
|
if not achievementID then return true end
|
|
|
|
local isModifiedClick = IsModifiedClick();
|
|
if isModifiedClick then
|
|
local handled = nil;
|
|
if ( IsModifiedClick("CHATLINK") ) then
|
|
local achievementLink = GetAchievementLink(achievementID);
|
|
if ( achievementLink ) then
|
|
handled = ChatEdit_InsertLink(achievementLink);
|
|
if ( not handled and SocialPostFrame and Social_IsShown() ) then
|
|
Social_InsertLink(achievementLink);
|
|
handled = true;
|
|
end
|
|
end
|
|
end
|
|
if ( not handled and IsModifiedClick("QUESTWATCHTOGGLE") ) then
|
|
local isTracking = ToggleTracking(achievementID);
|
|
button.trackIcon:SetShown(isTracking);
|
|
end
|
|
end
|
|
return isModifiedClick
|
|
end
|
|
|
|
local function AchievementCard_OnClick(self)
|
|
if not ProcessModifiedClick(self) then
|
|
InspectCard(self, true);
|
|
end
|
|
end
|
|
|
|
local function FormatRewardText(id, rewardText)
|
|
if isDarkTheme then
|
|
local itemID = GetRewardItemID(id);
|
|
if itemID then
|
|
local itemID, itemType, itemSubType, _, icon, itemClassID, itemSubClassID = GetItemInfoInstant(itemID);
|
|
if itemSubType == "Mount" then
|
|
rewardText = gsub(rewardText, ".+:(.+)", "|cff808080".. "Mount:" .."|r|cff8950c6".."%1".."|r");
|
|
elseif itemSubType == "Companion Pets" then
|
|
rewardText = gsub(rewardText, ".+:(.+)", "|cff808080".. "Pet:" .."|r|cfff2b344".."%1".."|r");
|
|
else
|
|
rewardText = "|cffa3d39c"..rewardText.."|r";
|
|
end
|
|
return rewardText, itemID
|
|
else
|
|
return ("|cffa3d39c"..rewardText.."|r"); --Pastel Yellow Green
|
|
end
|
|
else
|
|
return ("|cffffd200"..rewardText.."|r");
|
|
end
|
|
end
|
|
|
|
local function GetProgressivePoints(achievementID, basePoints)
|
|
local points;
|
|
local _, progressivePoints, completed
|
|
if basePoints then
|
|
progressivePoints = basePoints;
|
|
else
|
|
_, _, progressivePoints, completed = DataProvider:GetAchievementInfo(achievementID);
|
|
end
|
|
achievementID = GetPreviousAchievement(achievementID);
|
|
while achievementID do
|
|
_, _, points, completed = DataProvider:GetAchievementInfo(achievementID);
|
|
progressivePoints = progressivePoints + points;
|
|
achievementID = GetPreviousAchievement(achievementID);
|
|
end
|
|
|
|
if ( progressivePoints ) then
|
|
return progressivePoints;
|
|
else
|
|
return 0;
|
|
end
|
|
end
|
|
|
|
|
|
local function FormatAchievementCard(button, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe)
|
|
if not button then
|
|
return
|
|
end
|
|
local headerObject, numLines, textHeight;
|
|
|
|
button.id = id;
|
|
button.trackIcon:SetShown( DataProvider:IsTrackedAchievement(id) );
|
|
if ( not completed or ( not isGuild and not wasEarnedByMe ) ) and (showNotEarnedMark) then
|
|
button.NotEarned:Show();
|
|
else
|
|
button.NotEarned:Hide();
|
|
end
|
|
|
|
--for long text
|
|
button.header:SetText(name);
|
|
if button.header:IsTruncated() then
|
|
headerObject = button.headerLong;
|
|
headerObject:SetText(name);
|
|
button.header:Hide();
|
|
else
|
|
headerObject = button.header;
|
|
button.headerLong:Hide();
|
|
end
|
|
headerObject:Show();
|
|
|
|
if IsAccountWide(flags) then
|
|
if completed then
|
|
if isDarkTheme then
|
|
headerObject:SetTextColor(0.427, 0.812, 0.965); --(0.427, 0.812, 0.965)(0.4, 0.755, 0.9)
|
|
else
|
|
headerObject:SetTextColor(1, 1, 1);
|
|
end
|
|
else
|
|
if isDarkTheme then
|
|
headerObject:SetTextColor(0.214, 0.406, 0.484);
|
|
else
|
|
headerObject:SetTextColor(0.5, 0.5, 0.5);
|
|
end
|
|
end
|
|
else
|
|
if completed then
|
|
if isDarkTheme then
|
|
headerObject:SetTextColor(0.9, 0.82, 0.58); --(1, 0.91, 0.647); --(0.9, 0.82, 0.58) --(0.851, 0.774, 0.55)
|
|
else
|
|
headerObject:SetTextColor(1, 1, 1);
|
|
end
|
|
else
|
|
if isDarkTheme then
|
|
headerObject:SetTextColor(0.5, 0.46, 0.324);
|
|
else
|
|
headerObject:SetTextColor(0.5, 0.5, 0.5);
|
|
end
|
|
end
|
|
end
|
|
|
|
points = GetProgressivePoints(id, points);
|
|
if points == 0 then
|
|
button.points:SetText("");
|
|
button.lion:Show();
|
|
else
|
|
if points >= 100 then
|
|
if not button.useSmallPoints then
|
|
button.useSmallPoints = true;
|
|
button.points:SetFontObject(NarciAchievemtPointsSmall);
|
|
end
|
|
else
|
|
if button.useSmallPoints then
|
|
button.useSmallPoints = nil;
|
|
button.points:SetFontObject(NarciAchievemtPoints);
|
|
end
|
|
end
|
|
button.points:SetText(points);
|
|
button.lion:Hide();
|
|
end
|
|
|
|
button.icon:SetTexture(icon);
|
|
|
|
local rewardHeight;
|
|
local shadowHeight = 0;
|
|
if rewardText and rewardText ~= "" then
|
|
local itemID;
|
|
rewardHeight = 22;
|
|
rewardText, itemID = FormatRewardText(id, rewardText);
|
|
button.RewardFrame.reward:SetText(rewardText);
|
|
button.RewardFrame.itemID = itemID;
|
|
button.itemID = itemID;
|
|
button.RewardFrame:Show();
|
|
else
|
|
if isDarkTheme then
|
|
rewardHeight = 2;
|
|
else
|
|
rewardHeight = 8;
|
|
end
|
|
button.RewardFrame:Hide();
|
|
button.RewardFrame:SetHeight(2);
|
|
end
|
|
button.RewardFrame:SetHeight(rewardHeight);
|
|
button.description:SetHeight(0);
|
|
button.description:SetText(description);
|
|
textHeight = floor( button.background:GetHeight() + 0.5 );
|
|
local descriptionHeight = button.description:GetHeight();
|
|
button.description:SetHeight(descriptionHeight + 2)
|
|
numLines = ceil( descriptionHeight / 14 - 0.1 );
|
|
button:SetHeight(72 + rewardHeight + 14*(numLines - 1) );
|
|
button.shadow:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 12, - 6 - numLines * 6 - shadowHeight);
|
|
|
|
if IsAccountWide(flags) then --ACHIEVEMENT_FLAGS_ACCOUNT
|
|
if button.accountWide ~= true then
|
|
button.accountWide = true;
|
|
button.border:SetTexCoord(0.05078125, 0.94921875, 0.5, 1);
|
|
button.bottom:SetTexCoord(0.05078125, 0.94921875, 0.985, 1);
|
|
end
|
|
if textHeight <= 288 then
|
|
button.background:SetTexCoord(0.05078125, 0.94921875, 0.985 - textHeight/288/2, 0.985);
|
|
else
|
|
button.background:SetTexCoord(0.05078125, 0.94921875, 0.5, 0.985);
|
|
end
|
|
else
|
|
if button.accountWide then
|
|
button.accountWide = nil;
|
|
button.border:SetTexCoord(0.05078125, 0.94921875, 0, 0.5);
|
|
button.bottom:SetTexCoord(0.05078125, 0.94921875, 0.485, 0.5);
|
|
end
|
|
if textHeight <= 288 then
|
|
button.background:SetTexCoord(0.05078125, 0.94921875, 0.485 - textHeight/288/2, 0.485);
|
|
else
|
|
button.background:SetTexCoord(0.05078125, 0.94921875, 0, 0.485);
|
|
end
|
|
end
|
|
|
|
if completed then
|
|
button.date:SetText( FormatDate(day, month, year) );
|
|
button.RewardFrame.reward:SetAlpha(1);
|
|
|
|
if (button.isDark == nil) or (button.isDark) then
|
|
button.isDark = false;
|
|
button.icon:SetDesaturated(false);
|
|
button.points:SetTextColor(0.8, 0.8, 0.8);
|
|
if isDarkTheme then
|
|
button.description:SetTextColor(0.72, 0.72, 0.72);
|
|
else
|
|
button.description:SetTextColor(0, 0, 0);
|
|
end
|
|
button.icon:SetVertexColor(1, 1, 1);
|
|
button.lion:SetVertexColor(1, 1, 1);
|
|
button.border:SetVertexColor(1, 1, 1);
|
|
button.background:SetVertexColor(1, 1, 1);
|
|
button.bottom:SetVertexColor(1, 1, 1);
|
|
button.border:SetDesaturated(false);
|
|
button.background:SetDesaturated(false);
|
|
button.bottom:SetDesaturated(false);
|
|
end
|
|
else
|
|
button.date:SetText("");
|
|
button.RewardFrame.reward:SetAlpha(0.60);
|
|
|
|
if (button.isDark == nil) or (not button.isDark) then
|
|
button.isDark = true;
|
|
button.icon:SetDesaturated(true);
|
|
button.points:SetTextColor(0.6, 0.6, 0.6);
|
|
if isDarkTheme then
|
|
button.description:SetTextColor(0.6, 0.6, 0.6);
|
|
else
|
|
button.description:SetTextColor(0, 0, 0);
|
|
end
|
|
button.icon:SetVertexColor(0.60, 0.60, 0.60);
|
|
button.lion:SetVertexColor(0.60, 0.60, 0.60);
|
|
button.border:SetVertexColor(0.60, 0.60, 0.60);
|
|
button.background:SetVertexColor(0.72, 0.72, 0.72);
|
|
button.bottom:SetVertexColor(0.72, 0.72, 0.72);
|
|
button.border:SetDesaturation(0.6);
|
|
button.background:SetDesaturation(0.6);
|
|
button.bottom:SetDesaturation(0.6);
|
|
end
|
|
end
|
|
|
|
button:SetShown(id);
|
|
end
|
|
|
|
local function FormatAchievementCardByIndex(buttonIndex, ...)
|
|
local button = AchievementCards[buttonIndex];
|
|
if button then
|
|
FormatAchievementCard(button, ...);
|
|
if buttonIndex > 7 or buttonIndex < 0 then
|
|
button:SetAlpha(1);
|
|
else
|
|
button.toAlpha = 1; --for flip animation
|
|
end
|
|
end
|
|
end
|
|
|
|
local function InspectAchievement(achievementID)
|
|
if not achievementID then return end;
|
|
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfo(achievementID);
|
|
local displayCard;
|
|
if DataProvider:IsStatistic(achievementID) then
|
|
displayCard = InspectionFrame.StatCard;
|
|
InspectionFrame.Card:Hide();
|
|
displayCard:SetData(achievementID);
|
|
displayCard:Show();
|
|
displayCard:SetAlpha(1);
|
|
displayCard:ClearAllPoints();
|
|
displayCard:SetPoint("BOTTOM", InspectionFrame, "CENTER", 0, 36);
|
|
else
|
|
displayCard = InspectionFrame.Card;
|
|
InspectionFrame.StatCard:Hide();
|
|
FormatAchievementCardByIndex(-1, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe);
|
|
end
|
|
animFlyOut.Card = displayCard;
|
|
|
|
DisplayProgress(id, flags);
|
|
InspectionFrame.currentAchievementID = id;
|
|
InspectionFrame.currentAchievementName = name;
|
|
InspectionFrame:Show();
|
|
InspectionFrame.HotkeyShiftClick:Show();
|
|
InspectionFrame.GetLink:Show();
|
|
|
|
local itemID = GetRewardItemID(id);
|
|
if itemID then
|
|
MountPreview:SetItem(itemID);
|
|
else
|
|
HideItemPreview();
|
|
end
|
|
|
|
InspectionFrame:UpdateChain(id, completed);
|
|
InspectionFrame:FindParentAchievementID(id);
|
|
GoToCategoryButton:SetAchievement(id, isGuild);
|
|
|
|
return completed, displayCard:GetHeight()/2
|
|
end
|
|
|
|
local function FormatStatCard(buttonIndex, id)
|
|
local button = StatCardController:Accquire(buttonIndex);
|
|
if button then
|
|
button:SetData(id);
|
|
end
|
|
end
|
|
|
|
ScrollUtil.heightData = {};
|
|
ScrollUtil.achievementID = {};
|
|
ScrollUtil.totalHeight = 0;
|
|
ScrollUtil.positionToButton = {};
|
|
ScrollUtil.formatFunc = FormatAchievementCardByIndex;
|
|
|
|
function ScrollUtil:ResetHeights()
|
|
self.totalHeight = 18;
|
|
self.position = 1;
|
|
self.lastOffset = 0;
|
|
self.nextOffset = 0;
|
|
wipe(self.heightData);
|
|
end
|
|
|
|
function ScrollUtil:GetScrollRange()
|
|
local range = self.totalHeight - (AchievementContainer:GetHeight() or 0) + 18;
|
|
if range < 0 then
|
|
range = 0;
|
|
end
|
|
return range;
|
|
end
|
|
|
|
function ScrollUtil:SetCardData(cardIndex, achievementID, description, rewardText)
|
|
local rewardHeight;
|
|
if rewardText and rewardText ~= "" then
|
|
rewardHeight = 22;
|
|
else
|
|
if isDarkTheme then
|
|
rewardHeight = 2;
|
|
else
|
|
rewardHeight = 8;
|
|
end
|
|
end
|
|
self.textReference:SetText("");
|
|
self.textReference:SetHeight(0);
|
|
self.textReference:SetText(description);
|
|
local descriptionHeight = self.textReference:GetHeight();
|
|
local numLines = ceil( descriptionHeight / 14 - 0.1 );
|
|
local buttonHeight = 72 + rewardHeight + 14*(numLines - 1) + 4; --4 is the Gap
|
|
|
|
self.heightData[cardIndex] = self.totalHeight;
|
|
self.achievementID[cardIndex] = achievementID;
|
|
self.totalHeight = self.totalHeight + buttonHeight;
|
|
|
|
return buttonHeight;
|
|
end
|
|
|
|
function ScrollUtil:SetStatCardData(cardIndex, achievementID)
|
|
local buttonHeight;
|
|
if achievementID < 0 then
|
|
buttonHeight = 48;
|
|
else
|
|
if IsBossCard(achievementID) then
|
|
--boss card
|
|
buttonHeight = 94;
|
|
else
|
|
buttonHeight = 72;
|
|
end
|
|
end
|
|
|
|
self.heightData[cardIndex] = self.totalHeight;
|
|
self.achievementID[cardIndex] = achievementID;
|
|
self.totalHeight = self.totalHeight + buttonHeight;
|
|
|
|
return buttonHeight;
|
|
end
|
|
|
|
function ScrollUtil:GetTopButtonIndex(scrollOffset)
|
|
if scrollOffset > self.nextOffset then
|
|
local p = self.position + 1;
|
|
if self.heightData[p] then
|
|
self.position = p;
|
|
self.lastOffset = self.heightData[p];
|
|
self.nextOffset = self.heightData[p + 1];
|
|
self:UpdateScrollChild(-1);
|
|
end
|
|
elseif scrollOffset < self.lastOffset then
|
|
local p = self.position - 1;
|
|
if self.heightData[p] then
|
|
self.nextOffset = self.heightData[p + 1];
|
|
self.lastOffset = self.heightData[p];
|
|
if p < 1 then
|
|
p = 1;
|
|
end
|
|
self.position = p;
|
|
self:UpdateScrollChild(1);
|
|
end
|
|
end
|
|
end
|
|
|
|
function ScrollUtil:UpdateScrollChild(direction)
|
|
if direction < 0 then
|
|
local topButton = tremove(self.activeCards, 1);
|
|
tinsert(self.activeCards, topButton);
|
|
elseif direction > 0 then
|
|
local bottomButton = tremove(self.activeCards);
|
|
tinsert(self.activeCards, 1, bottomButton);
|
|
end
|
|
wipe(self.positionToButton);
|
|
local p = self.position;
|
|
local id;
|
|
local positionIndex;
|
|
local realID, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe;
|
|
local card;
|
|
for i = 1, NUM_ACHIEVEMENT_CARDS do
|
|
card = self.activeCards[i];
|
|
if not card then break end;
|
|
positionIndex = p + i - 1;
|
|
card.positionIndex = positionIndex;
|
|
--card.TableIndex:SetText(i);
|
|
if self.heightData[positionIndex] then
|
|
card:SetPoint("TOP", AchievementContainer.ScrollChild, "TOP", 0, -self.heightData[positionIndex]);
|
|
self.positionToButton[positionIndex] = card;
|
|
id = self.achievementID[positionIndex];
|
|
if id then
|
|
if card.id ~= id then
|
|
realID, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfo(id);
|
|
self.formatFunc(i, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe);
|
|
card:Show();
|
|
else
|
|
card:Show();
|
|
end
|
|
else
|
|
card:Hide();
|
|
end
|
|
else
|
|
card:Hide();
|
|
end
|
|
end
|
|
end
|
|
|
|
function ScrollUtil:GetOffsetByPositionIndex(index)
|
|
return self.heightData[index] or 0
|
|
end
|
|
|
|
function ScrollUtil:GetAchievementIDByPositionIndex(index)
|
|
return self.achievementID[index];
|
|
end
|
|
|
|
function ScrollUtil:GetCardByPositionIndex(index)
|
|
return self.positionToButton[index];
|
|
end
|
|
|
|
function InspectCard(button, playAnimation) --Private
|
|
local index = button.positionIndex;
|
|
if not index then return end;
|
|
|
|
local Card = InspectionFrame.Card;
|
|
local id = button.id;
|
|
Card:ClearAllPoints();
|
|
Card:SetPoint("BOTTOM", InspectionFrame, "CENTER", 0, 36);
|
|
|
|
InspectionFrame.pauseScroll = nil;
|
|
InspectionFrame.dataIndex = index;
|
|
|
|
local numAchievements = InspectionFrame.numAchievements;
|
|
|
|
if index <= 1 then
|
|
index = 1;
|
|
InspectionFrame.PrevButton:Disable();
|
|
InspectionFrame.NextButton:Enable();
|
|
InspectionFrame.NextButton:Show();
|
|
elseif index >= numAchievements then
|
|
index = numAchievements;
|
|
InspectionFrame.PrevButton:Enable();
|
|
InspectionFrame.PrevButton:Show();
|
|
InspectionFrame.NextButton:Disable();
|
|
else
|
|
InspectionFrame.PrevButton:Enable();
|
|
InspectionFrame.NextButton:Enable();
|
|
InspectionFrame.PrevButton:Show();
|
|
InspectionFrame.NextButton:Show();
|
|
end
|
|
if numAchievements > 0 then
|
|
InspectionFrame.HotkeyMouseWheel:Show();
|
|
else
|
|
InspectionFrame.HotkeyMouseWheel:Hide();
|
|
end
|
|
|
|
local completed, extraY = InspectAchievement(id);
|
|
|
|
--Animation
|
|
local x0, y0 = InspectionFrame:GetCenter();
|
|
local x1, y1 = button:GetCenter();
|
|
local offsetX = x1 - x0;
|
|
local offsetY = y1 - y0 - extraY;
|
|
|
|
--animFlyIn.fromX, animFlyIn.fromY = offsetX, offsetY;
|
|
animFlyOut.toX, animFlyOut.toY = offsetX, offsetY;
|
|
animFlyOut.button = button;
|
|
animFlyOut.duration = max(0.2, 0.2*(sqrt(offsetX^2 + (offsetY - 36)^2))/150 );
|
|
|
|
if playAnimation then
|
|
InspectionFrame:SyncBlurOffset(index);
|
|
animFlyIn:Play();
|
|
if DataProvider:IsStatistic(id) then
|
|
InspectionFrame.StatCard:SetAlpha(0);
|
|
FadeFrame(InspectionFrame.StatCard, 0.2, 1);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function Slice_UpdateAchievementCards(categoryID, startIndex)
|
|
--from 1st complete achievement to bottom
|
|
local slice = 4;
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe;
|
|
local processComplete = false;
|
|
local numProcessed = 0;
|
|
|
|
--print("process: "..startIndex);
|
|
for i = startIndex, startIndex + slice do
|
|
id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfoByOrder(categoryID, i);
|
|
if i > 0 and id then
|
|
if i <= NUM_ACHIEVEMENT_CARDS then
|
|
FormatAchievementCardByIndex(i, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe);
|
|
end
|
|
ScrollUtil:SetCardData(i, id, description, rewardText);
|
|
numProcessed = i;
|
|
else
|
|
processComplete = true;
|
|
break;
|
|
end
|
|
end
|
|
|
|
return numProcessed + 1, processComplete
|
|
end
|
|
|
|
local function Slice_ReverselyUpdateAchievementCards_Callback(categoryID, startIndex)
|
|
--from 1st complete achievement to 1st incomplete
|
|
local slice = 4;
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe;
|
|
local processComplete = false;
|
|
local numProcessed = 0;
|
|
local numAchievements, numCompleted, numIncomplete = GetCategoryNumAchievements(categoryID, false);
|
|
local index;
|
|
for i = startIndex, startIndex + slice do
|
|
id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfoByOrder(categoryID, i);
|
|
if i <= numCompleted then
|
|
index = i + numIncomplete;
|
|
if i <= NUM_ACHIEVEMENT_CARDS then
|
|
FormatAchievementCardByIndex(index, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe);
|
|
end
|
|
ScrollUtil:SetCardData(index, id, description, rewardText);
|
|
numProcessed = i;
|
|
else
|
|
processComplete = true;
|
|
break;
|
|
end
|
|
end
|
|
|
|
return numProcessed + 1, processComplete
|
|
end
|
|
|
|
local function Slice_ReverselyUpdateAchievementCards(categoryID, startIndex)
|
|
--from 1st incomplete achievement to the bottom
|
|
local slice = 4;
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe;
|
|
local processComplete = false;
|
|
local numProcessed = 0;
|
|
local numAchievements, numCompleted = GetCategoryNumAchievements(categoryID, false);
|
|
|
|
--print("reverse process: "..startIndex);
|
|
for i = startIndex, startIndex + slice do
|
|
id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe = DataProvider:GetAchievementInfoByOrder(categoryID, numCompleted + i);
|
|
if id then
|
|
--print("id #"..id)
|
|
if not completed then
|
|
if i <= NUM_ACHIEVEMENT_CARDS then
|
|
FormatAchievementCardByIndex(i, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe);
|
|
end
|
|
ScrollUtil:SetCardData(i, id, description, rewardText);
|
|
numProcessed = i;
|
|
end
|
|
else
|
|
--print("Break, begin forward")
|
|
processor:Hide();
|
|
processor.arg1 = categoryID;
|
|
processor.arg2 = 1; --startIndex
|
|
processor.func = Slice_ReverselyUpdateAchievementCards_Callback --Slice_UpdateAchievementCards;
|
|
processor:Show();
|
|
return 1, false
|
|
end
|
|
end
|
|
|
|
return numProcessed + 1, processComplete
|
|
end
|
|
|
|
local function Slice_UpdateStatCards(categoryID, startIndex)
|
|
--from 1st complete achievement to bottom
|
|
local slice = 4;
|
|
local id;
|
|
local processComplete = false;
|
|
local numProcessed = 0;
|
|
|
|
for i = startIndex, startIndex + slice do
|
|
id = GetStatisticInfo(categoryID, i);
|
|
if i > 0 and id then
|
|
ScrollUtil:SetStatCardData(i, id);
|
|
numProcessed = i;
|
|
else
|
|
processComplete = true;
|
|
break;
|
|
end
|
|
end
|
|
|
|
return numProcessed + 1, processComplete
|
|
end
|
|
|
|
local function UpdateAchievementScrollRange()
|
|
local scrollBar = AchievementContainer.scrollBar;
|
|
local range = ScrollUtil:GetScrollRange();
|
|
scrollBar:SetMinMaxValues(0, range);
|
|
AchievementContainer.range = range;
|
|
scrollBar:SetShown(range ~= 0);
|
|
end
|
|
|
|
processor.func = Slice_ReverselyUpdateAchievementCards --Slice_UpdateAchievementCards;
|
|
processor.callback = UpdateAchievementScrollRange;
|
|
|
|
|
|
local animFlip = CreateFrame("Frame");
|
|
|
|
function animFlip:Play(groupIndex)
|
|
self:Hide();
|
|
self.t = 0;
|
|
local objects;
|
|
if groupIndex == 1 then
|
|
objects = AchievementCards;
|
|
else
|
|
return
|
|
end
|
|
local numObjects = #objects;
|
|
numObjects = min(numObjects, 6);
|
|
for i = 1, numObjects do
|
|
objects[i]:SetAlpha(0);
|
|
end
|
|
|
|
local oT, card;
|
|
local scale, offset1, offset2, alpha;
|
|
local fullDuration = numObjects * 0.05 + 0.4;
|
|
self:SetScript("OnUpdate", function(f, elapsed)
|
|
self.t = self.t + elapsed;
|
|
for i = 1, numObjects do
|
|
oT = self.t - 0.05 * (i - 1);
|
|
if oT > 0 then
|
|
if oT < 0.4 then
|
|
scale = outQuart(oT, 1.25, 1, 0.4);
|
|
offset1 = outQuart(oT, 24, 0, 0.4);
|
|
offset2 = outQuart(oT, -72, -48, 0.4);
|
|
alpha = min(1, linear(oT, 0, 1, 0.25));
|
|
else
|
|
scale = 1;
|
|
offset1 = 0;
|
|
offset2 = -48;
|
|
alpha = 1;
|
|
end
|
|
card = objects[i];
|
|
card:SetAlpha(alpha);
|
|
card.border:SetPoint("TOP", 0, offset1);
|
|
card.description:SetPoint("TOP", 0, offset2);
|
|
card.points:SetScale(scale);
|
|
card.icon:SetScale(scale);
|
|
card.lion:SetScale(scale);
|
|
card.border:SetScale(scale);
|
|
end
|
|
end
|
|
if self.t > fullDuration then
|
|
self:Hide();
|
|
end
|
|
end);
|
|
self:Show();
|
|
end
|
|
|
|
|
|
local SORT_FUNC = Slice_ReverselyUpdateAchievementCards;
|
|
local function UpdateAchievementCardsBySlice(categoryID)
|
|
ScrollUtil:ResetHeights();
|
|
|
|
processor:Hide();
|
|
AchievementContainer.scrollBar:SetValue(0);
|
|
for i = 1, NUM_ACHIEVEMENT_CARDS do
|
|
AchievementCards[i]:Hide();
|
|
end
|
|
|
|
local numAchievements, numCompleted, numIncomplete = GetCategoryNumAchievements(categoryID, false);
|
|
DataProvider.numAchievements = numAchievements;
|
|
processor.arg1 = categoryID;
|
|
processor.arg2 = 1; --fromIndex
|
|
processor.func = SORT_FUNC;
|
|
processor:Start();
|
|
|
|
--animation
|
|
if numAchievements ~= 0 then
|
|
animFlip:Play(1);
|
|
end
|
|
end
|
|
|
|
local function SwitchToSortMethod(index)
|
|
if index == 2 then
|
|
SORT_FUNC = Slice_UpdateAchievementCards;
|
|
else
|
|
SORT_FUNC = Slice_ReverselyUpdateAchievementCards;
|
|
end
|
|
|
|
local categoryID = DataProvider.currentCategory;
|
|
if categoryID and categoryID > 0 then
|
|
UpdateAchievementCardsBySlice(categoryID);
|
|
end
|
|
end
|
|
|
|
local function UpdateStatCardsBySlice(categoryID)
|
|
ScrollUtil:ResetHeights();
|
|
processor:Hide();
|
|
AchievementContainer.scrollBar:SetValue(0);
|
|
local card;
|
|
local numAchievements = GetCategoryNumAchievements(categoryID, false);
|
|
local numCards = math.min(numAchievements, NUM_ACHIEVEMENT_CARDS);
|
|
for i = 1, numCards do
|
|
card = StatCardController:Accquire(i);
|
|
card:Show();
|
|
--card:SetStat(categoryID, i);
|
|
end
|
|
StatCardController:HideRest(numCards + 1);
|
|
|
|
DataProvider.numAchievements = numAchievements;
|
|
processor.arg1 = categoryID;
|
|
processor.arg2 = 1; --fromIndex
|
|
processor.func = Slice_UpdateStatCards;
|
|
processor:Start();
|
|
|
|
StatCardController:PlayAnimation();
|
|
end
|
|
|
|
---------------------------------------------------------------------------------------------------
|
|
local function UpdateCategoryScrollRange()
|
|
local button, buttons;
|
|
local totalHeight = 0;
|
|
local parentButtons = CategoryButtons:GetActiveParentButtons();
|
|
if not parentButtons then return end;
|
|
|
|
for i = 1, #parentButtons do
|
|
button = parentButtons[i];
|
|
if button.expanded then
|
|
totalHeight = totalHeight + ( button.expandedHeight or 32);
|
|
else
|
|
totalHeight = totalHeight + 32;
|
|
end
|
|
|
|
totalHeight = totalHeight + 4;
|
|
end
|
|
|
|
local scrollBar = CategoryContainer.scrollBar;
|
|
local newRange = max(0, totalHeight - CategoryContainer:GetHeight() + 52);
|
|
local _, oldRange = scrollBar:GetMinMaxValues();
|
|
|
|
CategoryContainer.positionFunc = nil;
|
|
if (newRange < oldRange) and (scrollBar:GetValue() > newRange) then
|
|
CategoryContainer.positionFunc = function(endValue, delta, scrollBar)
|
|
if scrollBar:GetValue() <= newRange then
|
|
CategoryContainer.positionFunc = nil;
|
|
scrollBar:SetShown(newRange ~= 0);
|
|
scrollBar:SetMinMaxValues(0, newRange);
|
|
CategoryContainer.range = newRange;
|
|
end
|
|
end
|
|
else
|
|
scrollBar:SetShown(newRange ~= 0);
|
|
scrollBar:SetMinMaxValues(0, newRange);
|
|
CategoryContainer.range = newRange;
|
|
end
|
|
end
|
|
|
|
|
|
local animExpand = NarciAPI_CreateAnimationFrame(0.25);
|
|
animExpand:SetScript("OnUpdate", function(self, elapsed)
|
|
self.total = self.total + elapsed;
|
|
local height = outSine(self.total, self.fromHeight, self.toHeight, self.duration);
|
|
if self.total >= self.duration then
|
|
self:Hide()
|
|
height = self.toHeight;
|
|
end
|
|
animExpand.object:SetHeight(height);
|
|
end)
|
|
|
|
function animExpand:Set(object, toHeight)
|
|
if self:IsShown() then
|
|
if object == self.object then
|
|
self:Hide();
|
|
else
|
|
--Snap to destination
|
|
self.object:SetHeight(self.toHeight);
|
|
self:Hide();
|
|
end
|
|
end
|
|
local fromHeight = object:GetHeight();
|
|
self.object = object;
|
|
self.fromHeight = fromHeight;
|
|
self.toHeight = toHeight;
|
|
local duration = sqrt(abs(fromHeight - toHeight)/32)*0.085;
|
|
if duration > 0.01 then
|
|
self.duration = duration;
|
|
self:Show();
|
|
end
|
|
end
|
|
|
|
function animExpand:CollapseAll()
|
|
self:Hide();
|
|
local button;
|
|
local parentButtons = CategoryButtons:GetActiveParentButtons();
|
|
|
|
for i = 1, #parentButtons do
|
|
button = parentButtons[i];
|
|
button.box:SetHeight(32);
|
|
button.drawer:Hide();
|
|
button.drawer:SetAlpha(0);
|
|
button.expanded = nil;
|
|
if not button.isStats then
|
|
button.progress:Hide();
|
|
button.percentSign:Show();
|
|
button.value:Show();
|
|
end
|
|
end
|
|
local lastButton = DataProvider:GetCategoryButtonByID(DataProvider.currentCategory);
|
|
if lastButton then
|
|
lastButton.label:SetTextColor(0.8, 0.8, 0.8);
|
|
end
|
|
|
|
CategoryContainer.scrollBar:SetValue(0);
|
|
UpdateCategoryScrollRange();
|
|
end
|
|
|
|
|
|
local function SetCategoryButtonProgress(button, numAchievements, numCompleted, isFeatsOfStrength)
|
|
if numAchievements == 0 or numCompleted == 0 then
|
|
button.fill:Hide();
|
|
button.fillEnd:Hide();
|
|
button.progress:SetText(0 .."/".. numAchievements);
|
|
else
|
|
if isFeatsOfStrength then
|
|
button.fill:Hide();
|
|
button.fillEnd:Hide();
|
|
button.progress:SetText(numCompleted);
|
|
else
|
|
local percentage = numCompleted / numAchievements;
|
|
if percentage == 1 then
|
|
button.fill:Hide();
|
|
button.fillEnd:Hide();
|
|
button.progress:SetText(numAchievements);
|
|
button.label:SetPoint("LEFT", 27, 0);
|
|
button.greenCheck:Show();
|
|
else
|
|
button.fill:Show();
|
|
button.fillEnd:Show();
|
|
button.fill:SetWidth(button.fillWidth * percentage);
|
|
button.fill:SetTexCoord(0, percentage * 0.75, 0, 1);
|
|
button.progress:SetText(numCompleted .."/".. numAchievements);
|
|
button.label:SetPoint("LEFT", 10, 0);
|
|
button.greenCheck:Hide();
|
|
end
|
|
end
|
|
end
|
|
button.progress:Show();
|
|
button.percentSign:Hide();
|
|
button.value:Hide();
|
|
button.numAchievements, button.numCompleted = numAchievements, numCompleted;
|
|
end
|
|
|
|
local function UpdateCategoryButtonProgress(button)
|
|
local categoryID = button.id;
|
|
local totalAchievements, totalCompleted = GetCategoryNumAchievements(categoryID, true); --ACHIEVEMENT_COMPARISON_SUMMARY_ID
|
|
|
|
button.numAchievements, button.numCompleted = totalAchievements, totalCompleted;
|
|
|
|
if button.isStats then
|
|
button.progress:SetText(totalAchievements);
|
|
button.progress:Show();
|
|
button.percentSign:Hide();
|
|
button.value:Hide();
|
|
if button.subCategories then
|
|
local numAchievements;
|
|
for i = 1, #button.subCategories do
|
|
categoryID = button.subCategories[i];
|
|
numAchievements = GetCategoryNumAchievements(categoryID, true);
|
|
totalAchievements = totalAchievements + numAchievements;
|
|
local childButton = DataProvider:GetCategoryButtonByID(categoryID);
|
|
if childButton then
|
|
childButton.progress:SetText(numAchievements);
|
|
childButton.progress:Show();
|
|
childButton.percentSign:Hide();
|
|
childButton.value:Hide();
|
|
end
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
local noPercent = button.noPercent;
|
|
if noPercent then
|
|
button.progress:SetText(totalCompleted);
|
|
else
|
|
button.progress:SetText(totalCompleted .."/".. totalAchievements);
|
|
end
|
|
|
|
if button.expanded then
|
|
button.progress:Show();
|
|
button.percentSign:Hide();
|
|
button.value:Hide();
|
|
else
|
|
button.progress:Hide();
|
|
button.percentSign:Show();
|
|
button.value:Show();
|
|
end
|
|
|
|
|
|
if button.subCategories then
|
|
local numAchievements, numCompleted;
|
|
for i = 1, #button.subCategories do
|
|
categoryID = button.subCategories[i];
|
|
numAchievements, numCompleted = GetCategoryNumAchievements(categoryID, true);
|
|
totalAchievements = totalAchievements + numAchievements;
|
|
totalCompleted = totalCompleted + numCompleted;
|
|
local childButton = DataProvider:GetCategoryButtonByID(categoryID);
|
|
if childButton then
|
|
SetCategoryButtonProgress(childButton, numAchievements, numCompleted, noPercent);
|
|
end
|
|
end
|
|
end
|
|
|
|
button.totalAchievements, button.totalCompleted = totalAchievements, totalCompleted;
|
|
|
|
|
|
if totalAchievements == 0 or totalCompleted == 0 then
|
|
button.fill:Hide();
|
|
button.fillEnd:Hide();
|
|
button.value:SetText("0");
|
|
else
|
|
if noPercent then
|
|
button.fill:Hide();
|
|
button.fillEnd:Hide();
|
|
button.value:SetText(totalCompleted);
|
|
else
|
|
button.fill:Show();
|
|
button.fillEnd:Show();
|
|
|
|
local percentage = totalCompleted / totalAchievements;
|
|
button.fill:SetWidth(button.fillWidth * percentage);
|
|
button.fill:SetTexCoord(0, percentage * 0.75, 0, 1);
|
|
if percentage == 1 then
|
|
button.value:SetText("100");
|
|
else
|
|
button.value:SetText( floor(100 * percentage) );
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function UpdateCategoryButtonProgressByCategoryID(categoryID)
|
|
local button = DataProvider:GetCategoryButtonByID(categoryID);
|
|
if button then
|
|
UpdateCategoryButtonProgress(button)
|
|
end
|
|
end
|
|
|
|
local function ReleaseAchievementCard()
|
|
for _, card in pairs(AchievementCards) do
|
|
--card:ClearAllPoints();
|
|
card:Hide();
|
|
end
|
|
end
|
|
|
|
local function SelectCategory(categoryID)
|
|
if IS_STAT_CATEGORY[categoryID] then
|
|
--statistics
|
|
AchievementContainer:Show();
|
|
ScrollUtil.formatFunc = FormatStatCard;
|
|
ScrollUtil.activeCards = StatCardController:GetTable();
|
|
UpdateStatCardsBySlice(categoryID);
|
|
ReleaseAchievementCard();
|
|
SummaryFrame:Hide();
|
|
InspectionFrame.numAchievements = GetCategoryNumAchievements(categoryID, false);
|
|
else
|
|
AchievementContainer:Show();
|
|
ScrollUtil.formatFunc = FormatAchievementCardByIndex;
|
|
ScrollUtil.activeCards = AchievementCards;
|
|
StatCardController:ReleaseAll();
|
|
if categoryID == -1 then
|
|
UpdateSummaryFrame();
|
|
SummaryFrame:Show();
|
|
else
|
|
UpdateAchievementCardsBySlice(categoryID);
|
|
SummaryFrame:Hide();
|
|
InspectionFrame.numAchievements = GetCategoryNumAchievements(categoryID, false);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ToggleFeatOfStrenghtText(button)
|
|
if button.isFoS then
|
|
local _, totalCompleted = GetCategoryNumAchievements(button.id, false);
|
|
if totalCompleted == 0 then
|
|
if isGuildView then
|
|
MainFrame.FeatOfStrengthText:SetText(GUILD_FEAT_OF_STRENGTH_DESCRIPTION);
|
|
else
|
|
MainFrame.FeatOfStrengthText:SetText(FEAT_OF_STRENGTH_DESCRIPTION);
|
|
end
|
|
MainFrame.FeatOfStrengthText:Show();
|
|
else
|
|
MainFrame.FeatOfStrengthText:Hide();
|
|
end
|
|
else
|
|
MainFrame.FeatOfStrengthText:Hide();
|
|
end
|
|
end
|
|
|
|
local function SubCategoryButton_OnClick(button)
|
|
local categoryID = button.id;
|
|
if categoryID ~= DataProvider.currentCategory then
|
|
--print(categoryID);
|
|
local lastButton = DataProvider:GetCategoryButtonByID(DataProvider.currentCategory);
|
|
DataProvider.currentCategory = categoryID;
|
|
if lastButton then
|
|
lastButton.label:SetTextColor(0.8, 0.8, 0.8);
|
|
end
|
|
button.label:SetTextColor(1, 0.91, 0.647);
|
|
SelectCategory(categoryID);
|
|
else
|
|
--print("old")
|
|
end
|
|
ToggleFeatOfStrenghtText(button);
|
|
end
|
|
|
|
local function CategoryButton_OnClick(button, mouse)
|
|
SummaryButton:Show();
|
|
|
|
local expandedHeight = button.expandedHeight;
|
|
local isExpanded = not button.expanded;
|
|
if expandedHeight ~= 32 then
|
|
if (mouse == "RightButton" or DataProvider.currentCategory == button.id) and (not isExpanded) then
|
|
FadeFrame(button.drawer, 0.15, 0);
|
|
animExpand:Set(button.box, 32);
|
|
button.expanded = nil;
|
|
else
|
|
FadeFrame(button.drawer, 0.2, 1);
|
|
animExpand:Set(button.box, expandedHeight);
|
|
button.expanded = true;
|
|
if mouse ~= "RightButton" then
|
|
SubCategoryButton_OnClick(button);
|
|
end
|
|
end
|
|
else
|
|
button.expanded = isExpanded;
|
|
SubCategoryButton_OnClick(button);
|
|
end
|
|
|
|
if button.isStats then
|
|
|
|
else
|
|
if button.expanded then
|
|
button.progress:Show();
|
|
button.percentSign:Hide();
|
|
button.value:Hide();
|
|
else
|
|
button.progress:Hide();
|
|
button.percentSign:Show();
|
|
button.value:Show();
|
|
end
|
|
end
|
|
|
|
|
|
UpdateCategoryScrollRange();
|
|
|
|
|
|
----
|
|
ToggleFeatOfStrenghtText(button);
|
|
end
|
|
|
|
local function ExpandCategoryButtonNoAnimation(button)
|
|
if not button then return end;
|
|
|
|
if not button.expanded then
|
|
button.progress:Show();
|
|
button.percentSign:Hide();
|
|
button.value:Hide();
|
|
|
|
local expandedHeight = button.expandedHeight;
|
|
if expandedHeight ~= 32 then
|
|
button.box:SetHeight(expandedHeight);
|
|
button.drawer:Show();
|
|
button.drawer:SetAlpha(1);
|
|
end
|
|
button.expanded = true;
|
|
|
|
UpdateCategoryScrollRange();
|
|
ToggleFeatOfStrenghtText(button);
|
|
end
|
|
end
|
|
|
|
local function BuildCategoryStructure(tabID)
|
|
local GUILD_FEAT_OF_STRENGTH_ID = 15093;
|
|
local GUILD_CATEGORY_ID = 15076;
|
|
|
|
|
|
local categories, structure, feats, legacys;
|
|
if tabID == 2 then
|
|
categories = GetGuildCategoryList();
|
|
structure = CategoryStructure.guild;
|
|
feats = { FEAT_OF_STRENGTH_ID };
|
|
legacys = {};
|
|
elseif tabID == 1 then
|
|
categories = GetCategoryList();
|
|
structure = CategoryStructure.player;
|
|
feats = { GUILD_FEAT_OF_STRENGTH_ID };
|
|
legacys = { LEGACY_ID };
|
|
elseif tabID == 3 then
|
|
categories = GetStatisticsCategoryList();
|
|
structure = CategoryStructure.stats;
|
|
feats = {};
|
|
legacys = {};
|
|
tinsert(categories, 12080000); --reserved for Narcissus Stat
|
|
for k, id in pairs(categories) do
|
|
IS_STAT_CATEGORY[id] = true;
|
|
end
|
|
end
|
|
|
|
local id;
|
|
local name, parentID;
|
|
local id2Order = {};
|
|
local subCategories = {};
|
|
|
|
local numParent = 0;
|
|
|
|
for i = 1, #categories do
|
|
id = categories[i];
|
|
name, parentID = DataProvider:GetCategoryInfo(id);
|
|
--print(name, parentID)
|
|
if (parentID == -1 or parentID == 15076) then
|
|
if not id2Order[id] then
|
|
numParent = numParent + 1;
|
|
structure[ numParent ] = { ["id"] = id, ["name"] = name, ["children"] = {} };
|
|
id2Order[ id ] = numParent;
|
|
end
|
|
else
|
|
tinsert(subCategories, id);
|
|
end
|
|
|
|
if parentID == LEGACY_ID then
|
|
tinsert(legacys, id);
|
|
elseif parentID == FEAT_OF_STRENGTH_ID then
|
|
tinsert(feats, id);
|
|
end
|
|
end
|
|
|
|
local order;
|
|
for i = 1, #subCategories do
|
|
id = subCategories[i];
|
|
name, parentID = DataProvider:GetCategoryInfo(id);
|
|
|
|
order = id2Order[parentID];
|
|
tinsert( structure[ order ].children, id);
|
|
end
|
|
|
|
structure.numCategories = #categories;
|
|
end
|
|
|
|
local function CreateCategoryButtons(tabID)
|
|
local frame;
|
|
local button, parentButton, parentData, id;
|
|
local structure;
|
|
local numButtons = 0;
|
|
local parentButtons, buttons;
|
|
|
|
if not CategoryButtons.buttons then
|
|
CategoryButtons.buttons = {};
|
|
end
|
|
|
|
local isStats;
|
|
local parentButtons = CategoryButtons:GetActiveParentButtons(tabID);
|
|
if tabID == 1 then
|
|
buttons = CategoryButtons.player.buttons;
|
|
structure = CategoryStructure.player;
|
|
frame = CategoryContainer.ScrollChild.PlayerCategory;
|
|
--CategoryContainer.ScrollChild.GuildCategory:Hide();
|
|
elseif tabID == 2 then
|
|
buttons = CategoryButtons.guild.buttons;
|
|
structure = CategoryStructure.guild;
|
|
frame = CategoryContainer.ScrollChild.GuildCategory;
|
|
--CategoryContainer.ScrollChild.PlayerCategory:Hide();
|
|
elseif tabID == 3 then
|
|
buttons = CategoryButtons.stats.buttons;
|
|
structure = CategoryStructure.stats;
|
|
frame = CategoryContainer.ScrollChild.StatsCategory;
|
|
isStats = true;
|
|
--CategoryContainer.ScrollChild.GuildCategory:Hide();
|
|
end
|
|
--frame:Show();
|
|
|
|
for i = 1, #structure do
|
|
numButtons = numButtons + 1;
|
|
parentButton = buttons[numButtons];
|
|
parentData = structure[i];
|
|
id = parentData.id;
|
|
|
|
if not parentButton then
|
|
parentButton = CreateFrame("Button", nil, frame, "NarciAchievementCategoryButtonTemplate");
|
|
tinsert(buttons, parentButton);
|
|
tinsert(parentButtons, parentButton);
|
|
parentButton.isParentButton = true;
|
|
parentButton:SetScript("OnClick", CategoryButton_OnClick);
|
|
end
|
|
|
|
DataProvider.id2Button[id] = parentButton;
|
|
parentButton:SetParent(frame);
|
|
parentButton:ClearAllPoints();
|
|
|
|
if i == 1 then
|
|
parentButton:SetPoint("TOP", frame, "TOP", 2 , -24);
|
|
else
|
|
parentButton:SetPoint("TOP", parentButtons[i - 1].box, "BOTTOM", 0, -2);
|
|
end
|
|
|
|
if id == LEGACY_ID or id == FEAT_OF_STRENGTH_ID or id == 15093 then
|
|
parentButton.noPercent = true;
|
|
parentButton.percentSign:SetText("");
|
|
parentButton.value:SetPoint("RIGHT", parentButton, "RIGHT", -10, 0);
|
|
if id == FEAT_OF_STRENGTH_ID or id == 15093 then
|
|
parentButton.isFoS = true;
|
|
end
|
|
else
|
|
parentButton.noPercent = nil;
|
|
parentButton.percentSign:SetText("%");
|
|
parentButton.value:SetPoint("RIGHT", parentButton, "RIGHT", -16, 0);
|
|
end
|
|
|
|
parentButton.id = id;
|
|
parentButton.label:SetText(parentData.name);
|
|
parentButton.subCategories = parentData.children;
|
|
|
|
local numChildren = #parentData.children;
|
|
parentButton.expandedHeight = numChildren * 32 + 32;
|
|
|
|
if isStats then
|
|
parentButton.isStats = true;
|
|
end
|
|
|
|
for j = 1, numChildren do
|
|
button = buttons[numButtons + 1];
|
|
id = parentData.children[j];
|
|
if not button then
|
|
button = CreateFrame("Button", nil, parentButton.drawer, "NarciAchievementSubCategoryButtonTemplate");
|
|
button.label:SetWidth(130);
|
|
tinsert(buttons, button);
|
|
button:SetScript("OnClick", SubCategoryButton_OnClick);
|
|
end
|
|
DataProvider.id2Button[id] = button;
|
|
button:SetParent(parentButton.drawer);
|
|
|
|
button:ClearAllPoints();
|
|
if j == 1 then
|
|
button:SetPoint("TOPRIGHT", parentButton.drawer, "BOTTOMRIGHT", 0, 0);
|
|
else
|
|
button:SetPoint("TOPRIGHT", buttons[numButtons], "BOTTOMRIGHT", 0, 0);
|
|
end
|
|
numButtons = numButtons + 1;
|
|
|
|
button.id = id;
|
|
button.label:SetText( DataProvider:GetCategoryInfo(id, 1) );
|
|
button.noPercent = nil;
|
|
|
|
if isStats then
|
|
button.isStats = true;
|
|
end
|
|
end
|
|
|
|
UpdateCategoryButtonProgress(parentButton);
|
|
end
|
|
end
|
|
|
|
|
|
local function CreateAchievementButtons(frame)
|
|
local button;
|
|
local buttons = {};
|
|
local numButtons = 0;
|
|
|
|
for i = 1, NUM_ACHIEVEMENT_CARDS do
|
|
button = CreateFrame("Button", nil, frame, "NarciAchievementLargeCardTemplate");
|
|
button:SetScript("OnClick", AchievementCard_OnClick);
|
|
button.index = i;
|
|
--button.AbsoluteIndex:SetText(i)
|
|
tinsert(buttons, button);
|
|
if i == 1 then
|
|
button:SetPoint("TOP", frame, "TOP", 0, -18);
|
|
else
|
|
button:SetPoint("TOP", buttons[i - 1], "BOTTOM", 0, -4);
|
|
end
|
|
ReskinButton(button);
|
|
end
|
|
|
|
frame.buttons = buttons;
|
|
AchievementCards = buttons;
|
|
|
|
--Pop-up Card : Achievement details
|
|
local Card = InspectionFrame.Card
|
|
Card:SetScript("OnClick", AchievementCard_OnClick);
|
|
AchievementCards[-1] = Card;
|
|
animFlyIn.Card = Card;
|
|
animFlyOut.Card = Card;
|
|
animFlyIn.header = Card.header;
|
|
animFlyIn.description = Card.description;
|
|
animFlyIn.date = Card.date;
|
|
animFlyIn.reward = Card.RewardFrame;
|
|
end
|
|
|
|
------------------------------------------------
|
|
NarciAchievementInspectionFrameMixin = {};
|
|
|
|
function NarciAchievementInspectionFrameMixin:OnLoad()
|
|
if not self.isLoaded then
|
|
self.isLoaded = true;
|
|
else
|
|
return
|
|
end
|
|
|
|
InspectionFrame = self;
|
|
|
|
local CompleteFrame = self.CriteriaFrame.LeftInset;
|
|
CompleteFrame.header:SetText(string.upper(CRITERIA_COMPLETED or "Completed"));
|
|
CompleteFrame.header:SetTextColor(0.216, 0.502, 0.2);
|
|
CompleteFrame.count:SetTextColor(0.216, 0.502, 0.2);
|
|
self.numCompleted = CompleteFrame.count;
|
|
|
|
local IncompleteFrame = self.CriteriaFrame.RightInset;
|
|
IncompleteFrame.header:SetText(string.upper(INCOMPLETE or "Incomplete"));
|
|
IncompleteFrame.header:SetTextColor(0.502, 0.2, 0.2);
|
|
IncompleteFrame.count:SetTextColor(0.502, 0.2, 0.2);
|
|
self.numIncomplete = IncompleteFrame.count;
|
|
|
|
animFlyIn.background = self.blur;
|
|
animFlyIn.ObjectiveFrame = self.CriteriaFrame;
|
|
animFlyIn.ChainFrame = self.ChainFrame;
|
|
animFlyOut.background = self.blur;
|
|
animFlyOut.ObjectiveFrame = self.CriteriaFrame;
|
|
animFlyOut.ChainFrame = self.ChainFrame;
|
|
|
|
self.dataIndex = 1;
|
|
|
|
|
|
self.TextContainerLeft = self.CriteriaFrame.LeftInset.TextFrame;
|
|
self.TextContainerRight = self.CriteriaFrame.RightInset.TextFrame;
|
|
self.MetaContainerLeft = self.CriteriaFrame.LeftInset.MetaFrame;
|
|
self.MetaContainerRight = self.CriteriaFrame.RightInset.MetaFrame;
|
|
self.BarContainerLeft = self.CriteriaFrame.LeftInset.BarFrame;
|
|
self.BarContainerRight = self.CriteriaFrame.RightInset.BarFrame;
|
|
|
|
|
|
--Achievement Container Blur
|
|
local BlurFrame = self.blur;
|
|
local BlurAnchor = BlurFrame.ScrollChild;
|
|
local blur1 = BlurFrame.ScrollChild.blur1;
|
|
local blur2 = BlurFrame.ScrollChild.blur2;
|
|
|
|
local deltaRatio = 1;
|
|
local speedRatio = 0.24;
|
|
local blurHeight = 77;
|
|
local range = 20000;
|
|
local RepositionBlur = function(value, delta)
|
|
local index;
|
|
if delta < 0 then
|
|
index = ceil( (value - 200) /940);
|
|
else
|
|
index = ceil( (value - 200) /940) - 1;
|
|
end
|
|
if index < 0 then
|
|
index = 1;
|
|
end
|
|
if index ~= self.blurOffset then
|
|
self.blurOffset = index;
|
|
if index % 2 == 1 then
|
|
blur2:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, -index * 940);
|
|
blur2:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, -index * 940);
|
|
else
|
|
blur1:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, -index * 940);
|
|
blur1:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, -index * 940);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(BlurFrame, deltaRatio, speedRatio, RepositionBlur, blurHeight, range);
|
|
local Blur_OnMouseWheel = BlurFrame:GetScript("OnMouseWheel");
|
|
|
|
function self:ScrollBlur(delta)
|
|
if delta ~= 0 then
|
|
Blur_OnMouseWheel(BlurFrame, delta);
|
|
ReturnButton:Hide();
|
|
end
|
|
end
|
|
|
|
function self:SyncBlurOffset(buttonIndex)
|
|
self.blurOffset = -1;
|
|
local value = (buttonIndex - 1) * blurHeight;
|
|
BlurFrame.scrollBar:SetValue(value);
|
|
|
|
local index = ceil( (value - 200) /940);
|
|
if index < 0 then
|
|
index = 1;
|
|
end
|
|
if index % 2 == 1 then
|
|
blur1:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, (1 - index) * 940);
|
|
blur1:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, (1 - index) * 940);
|
|
blur2:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, -index * 940);
|
|
blur2:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, -index * 940);
|
|
else
|
|
blur1:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, -index * 940);
|
|
blur1:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, -index * 940);
|
|
blur2:SetPoint("TOPLEFT", BlurAnchor, "TOPLEFT", 0, (1- index) * 940);
|
|
blur2:SetPoint("TOPRIGHT", BlurAnchor, "TOPRIGHT", 0, (1 -index) * 940);
|
|
end
|
|
end
|
|
|
|
--ScrollFrames: Criteria: Text, Meta
|
|
local function UpdateScrollFrameDivider(value, delta, scrollBar)
|
|
local minVal, maxVal = scrollBar:GetMinMaxValues();
|
|
|
|
if value >= maxVal - 0.1 then
|
|
scrollBar.divLeft:Hide();
|
|
scrollBar.divCenter:Hide();
|
|
scrollBar.divRight:Hide();
|
|
elseif maxVal ~= 0 then
|
|
scrollBar.divLeft:Show();
|
|
scrollBar.divCenter:Show();
|
|
scrollBar.divRight:Show();
|
|
end
|
|
end
|
|
|
|
local positionFunc = UpdateScrollFrameDivider;
|
|
local parentScrollFunc = function(delta)
|
|
InspectionFrame:OnMouseWheel(delta);
|
|
end
|
|
|
|
local numLines = 30;
|
|
local deltaRatio = 2;
|
|
local speedRatio = 0.24;
|
|
local buttonHeight = 26;
|
|
local range = numLines * buttonHeight - IncompleteFrame:GetHeight();
|
|
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(IncompleteFrame.TextFrame, deltaRatio, speedRatio, positionFunc, buttonHeight, range, parentScrollFunc);
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(CompleteFrame.TextFrame, deltaRatio, speedRatio, positionFunc, buttonHeight, range, parentScrollFunc);
|
|
|
|
local buttonHeight = 36;
|
|
local deltaRatio = 2;
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(IncompleteFrame.MetaFrame, deltaRatio, speedRatio, positionFunc, buttonHeight, range, parentScrollFunc);
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(CompleteFrame.MetaFrame, deltaRatio, speedRatio, positionFunc, buttonHeight, range, parentScrollFunc);
|
|
|
|
self:SetScript("OnLoad", nil);
|
|
self.OnLoad = nil;
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:OnShow()
|
|
self.isTransiting = nil;
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:OnMouseDown()
|
|
if not self.NextButton:IsMouseOver() and not self.PrevButton:IsMouseOver() then
|
|
animFlyOut:Play();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:ScrollToCategoryButton(button)
|
|
if button then
|
|
local topButton = CategoryButtons.player.buttons[1];
|
|
local offset = max(0, topButton:GetTop() - button:GetTop() - (CategoryContainer:GetHeight()/2 or 32) +32); --Attempt to position it to the vertical center
|
|
CategoryContainer.scrollBar:SetValue(offset);
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:ScrollToPosition(positionIndex)
|
|
local offset = ScrollUtil:GetOffsetByPositionIndex(positionIndex) - 18;
|
|
AchievementContainer.scrollBar:SetValue(offset);
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:OnMouseWheel(delta, stopLooping)
|
|
if self.isTransiting or self.pauseScroll then return end;
|
|
|
|
local index = self.dataIndex;
|
|
if delta > 0 then
|
|
index = index - 1;
|
|
else
|
|
index = index + 1;
|
|
end
|
|
if index < 1 or index > self.numAchievements then
|
|
return
|
|
else
|
|
self.dataIndex = index;
|
|
end
|
|
|
|
self.dataIndex = index;
|
|
self:ScrollBlur(delta);
|
|
self:ScrollToPosition(index);
|
|
|
|
local newButton = ScrollUtil:GetCardByPositionIndex(index);
|
|
if newButton then
|
|
if newButton.isHeader and not stopLooping then
|
|
--skip statistic header
|
|
self:OnMouseWheel(delta, true);
|
|
return
|
|
end
|
|
InspectCard(newButton);
|
|
end
|
|
end
|
|
|
|
local function FormatTextButtons(container, data, count, completed)
|
|
if not container.buttons then
|
|
container.buttons = {};
|
|
end
|
|
local buttons = container.buttons;
|
|
local button, numLines;
|
|
|
|
for i = 1, count do
|
|
button = buttons[i];
|
|
if not button then
|
|
button = CreateFrame("Button", nil, container.ScrollChild, "NarciAchievementObjectiveTextButton");
|
|
tinsert(buttons, button);
|
|
if i == 1 then
|
|
button:SetPoint("TOPLEFT", container.ScrollChild, "TOPLEFT", 0, 0);
|
|
button:SetPoint("TOPRIGHT", container.ScrollChild, "TOPRIGHT", 0, 0);
|
|
elseif i % 5 == 1 then
|
|
--bigger distance for every 5 entries
|
|
button:SetPoint("TOPLEFT", buttons[i - 1], "BOTTOMLEFT", 0, -14);
|
|
button:SetPoint("TOPRIGHT", buttons[i - 1], "TOPRIGHT", 0, -14);
|
|
else
|
|
button:SetPoint("TOPLEFT", buttons[i - 1], "BOTTOMLEFT", 0, 0);
|
|
button:SetPoint("TOPRIGHT", buttons[i - 1], "TOPRIGHT", 0, 0);
|
|
end
|
|
|
|
if not completed then
|
|
button.dash:SetTextColor(0.6, 0.6, 0.6);
|
|
button.icon:SetDesaturated(true);
|
|
else
|
|
button.dash:SetText("|CFF5fbb46- |r");
|
|
button.icon:SetDesaturated(false);
|
|
end
|
|
end
|
|
button.name:SetText(data.names[i]);
|
|
numLines = ceil( button.name:GetHeight() / 12 - 0.1 );
|
|
button.icon:SetTexture(nil);
|
|
button:SetHeight(18 + (numLines - 1)*12 );
|
|
button:Show();
|
|
end
|
|
|
|
for i = count + 1, #buttons do
|
|
buttons[i]:Hide();
|
|
end
|
|
|
|
--Update Scroll Range
|
|
local scrollBar = container.scrollBar;
|
|
local range;
|
|
if count == 0 then
|
|
range = 0;
|
|
else
|
|
range = max(0, buttons[1]:GetTop() - buttons[count]:GetBottom() - container:GetHeight() + 4);
|
|
range = floor(range + 0.2);
|
|
end
|
|
scrollBar:SetValue(0);
|
|
scrollBar:SetMinMaxValues(0, range);
|
|
scrollBar:SetShown(range ~= 0);
|
|
container.positionFunc(0, 1, scrollBar);
|
|
container.range = range;
|
|
end
|
|
|
|
local function FormatMetaButtons(container, data, count, completed)
|
|
if not container.buttons then
|
|
container.buttons = {};
|
|
end
|
|
local buttons = container.buttons;
|
|
local button, icon;
|
|
|
|
for i = 1, count do
|
|
button = buttons[i];
|
|
if not button then
|
|
button = CreateFrame("Button", nil, container.ScrollChild, "NarciAchievementObjectiveMetaAchievementButton");
|
|
tinsert(buttons, button);
|
|
if i == 1 then
|
|
local buttonWidth = button:GetWidth();
|
|
button:SetPoint("TOP", container.ScrollChild, "TOP", -(buttonWidth + 1) * 3, 0);
|
|
elseif i % 7 == 1 then
|
|
button:SetPoint("TOPLEFT", buttons[i - 7], "BOTTOMLEFT", 0, -1);
|
|
else
|
|
button:SetPoint("TOPLEFT", buttons[i - 1], "TOPRIGHT", 1, 0);
|
|
end
|
|
if not completed then
|
|
button.icon:SetDesaturated(true);
|
|
end
|
|
end
|
|
icon = data.icons[i];
|
|
button.icon:SetTexture(icon);
|
|
local id = data.assetIDs[i];
|
|
button.id = id;
|
|
if id then
|
|
button.textMode = nil;
|
|
button.criteriaString = nil;
|
|
else
|
|
button.textMode = true;
|
|
button.criteriaString = data.names[i];
|
|
if completed then
|
|
button.icon:SetTexture(461267); --ThumbsUp
|
|
else
|
|
button.icon:SetTexture(456031); --Thumbsdown
|
|
end
|
|
end
|
|
button.trackIcon:SetShown( DataProvider:IsTrackedAchievement(id) );
|
|
button:Show();
|
|
end
|
|
for i = count + 1, #buttons do
|
|
buttons[i]:Hide();
|
|
end
|
|
|
|
local header = container.name;
|
|
local numRow = ceil( count / 7);
|
|
|
|
header:ClearAllPoints();
|
|
if numRow < 3 then
|
|
header:SetPoint("TOPLEFT", buttons[1 + (numRow - 1)*7], "BOTTOMLEFT", 3, -4);
|
|
else
|
|
header:SetPoint("TOPLEFT", container, "BOTTOMLEFT", 3, -16);
|
|
end
|
|
|
|
if completed then
|
|
header:SetText("");
|
|
container.description:SetText("");
|
|
container.points:SetText("");
|
|
container.shield:Hide();
|
|
else
|
|
buttons[1]:SetAchievement();
|
|
end
|
|
|
|
--Update Scroll Range
|
|
local scrollBar = container.scrollBar;
|
|
local range;
|
|
if count == 0 then
|
|
range = 0;
|
|
else
|
|
range = max(0, buttons[1]:GetTop() - buttons[count]:GetBottom() - container:GetHeight());
|
|
end
|
|
scrollBar:SetValue(0);
|
|
scrollBar:SetMinMaxValues(0, range);
|
|
scrollBar:SetShown(range ~= 0);
|
|
container.positionFunc(0, 1, scrollBar);
|
|
container.range = range;
|
|
end
|
|
|
|
local function FormatStatusBars(container, data, count, completed)
|
|
if not container.bars then
|
|
container.bars = {};
|
|
end
|
|
local bars = container.bars;
|
|
local numBars = #data.bars;
|
|
local bar, barData;
|
|
|
|
for i = 1, numBars do
|
|
bar = bars[i];
|
|
if not bar then
|
|
bar = CreateFrame("Button", nil, container, "NarciAchievementObjectiveStatusBar");
|
|
tinsert(bars, bar);
|
|
if i == 1 then
|
|
bar:SetPoint("TOP", container, "TOP", 0, -2);
|
|
else
|
|
bar:SetPoint("TOP", bars[i - 1], "BOTTOM", 0, -16);
|
|
end
|
|
if completed then
|
|
bar.label:SetTextColor(0.8, 0.8, 0.8);
|
|
else
|
|
bar.label:SetTextColor(0.6, 0.6, 0.6);
|
|
end
|
|
end
|
|
barData = data.bars[i];
|
|
bar:SetMinMaxValues(0, barData[2]);
|
|
bar:SetValue(barData[1], true);
|
|
bar.label:SetText(barData[3]);
|
|
bar:SetHeight(bar.label:GetHeight() + 22);
|
|
bar:Show();
|
|
end
|
|
for i = numBars + 1, #bars do
|
|
bars[i]:Hide();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:FindParentAchievementID(achievementID)
|
|
local parentAchievementID = GetParentAchievementID(achievementID);
|
|
local button = AchievementCards[-1].ParentAchievmentButton;
|
|
if parentAchievementID then
|
|
local _, name, _, completed, month, day, year, _, _, icon = DataProvider:GetAchievementInfo(parentAchievementID);
|
|
if completed then
|
|
button:SetAlpha(1);
|
|
else
|
|
button:SetAlpha(0.60);
|
|
end
|
|
button.name = name;
|
|
button.id = parentAchievementID;
|
|
button.icon:SetTexture(icon);
|
|
button.icon:SetDesaturated(not completed);
|
|
button:Show();
|
|
if not button.hasInitialized then
|
|
button.hasInitialized = true;
|
|
button.border:SetTexture("Interface\\AddOns\\Narcissus_Achievements\\Art\\Shared\\IconBorderMiniPointRight");
|
|
end
|
|
else
|
|
button:Hide();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:UpdateChain(achievementID, currentIsCompleted)
|
|
local ChainFrame = self.ChainFrame;
|
|
if not ChainFrame.buttons then
|
|
ChainFrame.buttons = {};
|
|
end
|
|
local buttons = ChainFrame.buttons;
|
|
local button;
|
|
local achievements = { achievementID };
|
|
local currentAchievementID = achievementID;
|
|
local currentPosition = 1;
|
|
|
|
achievementID = GetPreviousAchievement(currentAchievementID);
|
|
while achievementID do
|
|
tinsert(achievements, 1, achievementID);
|
|
achievementID = GetPreviousAchievement(achievementID);
|
|
currentPosition = currentPosition + 1;
|
|
end
|
|
|
|
achievementID = GetNextAchievement(currentAchievementID);
|
|
while achievementID do
|
|
tinsert(achievements, achievementID);
|
|
achievementID = GetNextAchievement(achievementID);
|
|
end
|
|
|
|
local numAchievements = #achievements;
|
|
|
|
if numAchievements > 1 then
|
|
local gap = 1;
|
|
local extraHeight = 0;
|
|
local buttonWidth;
|
|
local id, completed, month, day, year, icon, _;
|
|
local numCompleted = 0;
|
|
for i = 1, numAchievements do
|
|
button = buttons[i];
|
|
if not button then
|
|
button = CreateFrame("Button", nil, ChainFrame, "NarciAchievementChainButton");
|
|
button.date.flyIn.hold1:SetDuration( (i - 1)*0.025 );
|
|
button.date.flyIn.hold2:SetDuration( (i - 1)*0.025 );
|
|
tinsert(buttons, button);
|
|
end
|
|
|
|
id = achievements[i];
|
|
_, _, _, completed, month, day, year, _, _, icon = DataProvider:GetAchievementInfo(id);
|
|
if completed then
|
|
numCompleted = numCompleted + 1;
|
|
end
|
|
|
|
button:ClearAllPoints();
|
|
if i == 1 then
|
|
buttonWidth = button:GetWidth();
|
|
local numButtonsFirstRow = min(15, numAchievements);
|
|
button:SetPoint("CENTER", ChainFrame.reference, "TOP", (buttonWidth + gap)*(1 - numButtonsFirstRow)/2 , -buttonWidth/2);
|
|
buttonWidth = buttonWidth + gap;
|
|
elseif i % 15 == 1 then
|
|
--15 buttons per row
|
|
local numButtonsThisRow = mod(numAchievements, 15);
|
|
extraHeight = extraHeight + buttonWidth;
|
|
local offsetY;
|
|
if ChainFrame.showDates and completed then
|
|
offsetY = -78;
|
|
else
|
|
offsetY = -1.5 * buttonWidth;
|
|
end
|
|
button:SetPoint("CENTER", ChainFrame.reference, "TOP", (buttonWidth + gap)*(1 - numButtonsThisRow)/2, offsetY);
|
|
else
|
|
button:SetPoint("CENTER", buttons[i - 1], "CENTER", buttonWidth, 0);
|
|
end
|
|
|
|
if i == currentPosition then
|
|
button.border:SetTexture("Interface\\AddOns\\Narcissus_Achievements\\Art\\Shared\\IconBorderPointyMini");
|
|
button:SetAlpha(1);
|
|
else
|
|
button.border:SetTexture("Interface\\AddOns\\Narcissus_Achievements\\Art\\Shared\\IconBorderMini");
|
|
if completed then
|
|
button:SetAlpha(0.60);
|
|
else
|
|
button:SetAlpha(0.33);
|
|
end
|
|
end
|
|
|
|
if completed then
|
|
button.date:SetText( FormatDate(day, month, year, true) );
|
|
else
|
|
button.date:SetText("");
|
|
end
|
|
|
|
button.icon:SetDesaturated(not completed);
|
|
button.id = id;
|
|
button.icon:SetTexture(icon);
|
|
button:Show();
|
|
end
|
|
|
|
for i = numAchievements + 1, #buttons do
|
|
buttons[i]:Hide();
|
|
end
|
|
|
|
ChainFrame.count:SetText( numCompleted .."/".. numAchievements);
|
|
|
|
ChainFrame.reference:SetHeight(34 + extraHeight); --base height 34
|
|
ChainFrame:Show();
|
|
|
|
return true
|
|
else
|
|
ChainFrame:Hide();
|
|
return false
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:DisplayCriteria(cData, iData)
|
|
local numCompleted = cData.count;
|
|
local numIncomplete = iData.count;
|
|
|
|
self.numCompleted:SetText(numCompleted);
|
|
self.numIncomplete:SetText(numIncomplete);
|
|
|
|
local TextContainer = self.TextContainerLeft;
|
|
local MetaContainer = self.MetaContainerLeft;
|
|
local BarContainer = self.BarContainerLeft;
|
|
local icon = cData.icons[1];
|
|
local numBars = #cData.bars;
|
|
local type = 1;
|
|
if numBars ~= 0 then
|
|
type = 3
|
|
elseif icon then
|
|
type = 2;
|
|
end
|
|
|
|
if numCompleted == 0 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Hide();
|
|
BarContainer:Hide();
|
|
else
|
|
if type == 2 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Show();
|
|
BarContainer:Hide();
|
|
FormatMetaButtons(MetaContainer, cData, numCompleted, true);
|
|
elseif type == 3 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Hide();
|
|
BarContainer:Show();
|
|
FormatStatusBars(BarContainer, cData, numCompleted, true);
|
|
else
|
|
TextContainer:Show();
|
|
MetaContainer:Hide();
|
|
BarContainer:Hide();
|
|
FormatTextButtons(TextContainer, cData, numCompleted, true);
|
|
end
|
|
end
|
|
|
|
--
|
|
local TextContainer = self.TextContainerRight;
|
|
local MetaContainer = self.MetaContainerRight;
|
|
local BarContainer = self.BarContainerRight;
|
|
local icon = iData.icons[1];
|
|
local numBars = #iData.bars;
|
|
local type = 1;
|
|
if numBars ~= 0 then
|
|
type = 3
|
|
elseif icon then
|
|
type = 2;
|
|
end
|
|
|
|
if numIncomplete == 0 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Hide();
|
|
BarContainer:Hide();
|
|
else
|
|
if type == 2 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Show();
|
|
BarContainer:Hide();
|
|
FormatMetaButtons(MetaContainer, iData, numIncomplete);
|
|
elseif type == 3 then
|
|
TextContainer:Hide();
|
|
MetaContainer:Hide();
|
|
BarContainer:Show();
|
|
FormatStatusBars(BarContainer, iData, numIncomplete);
|
|
else
|
|
TextContainer:Show();
|
|
MetaContainer:Hide();
|
|
BarContainer:Hide();
|
|
FormatTextButtons(TextContainer, iData, numIncomplete);
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciAchievementInspectionFrameMixin:ShowOrHideChainDates()
|
|
local ChainFrame = self.ChainFrame;
|
|
local showDates = ChainFrame.showDates;
|
|
local buttons = ChainFrame.buttons;
|
|
local button;
|
|
|
|
local offsetY;
|
|
if showDates then
|
|
offsetY = -78;
|
|
else
|
|
offsetY = -52.5;
|
|
end
|
|
|
|
for i = 1, #buttons do
|
|
button = buttons[i];
|
|
button.date:SetShown(showDates);
|
|
if showDates then
|
|
button.date.flyIn:Play();
|
|
else
|
|
button.date.flyIn:Stop();
|
|
end
|
|
|
|
if i ~= 1 and i % 15 == 1 then
|
|
local date = button.date:GetText();
|
|
if date and date ~= "" then
|
|
local point, relativeTo, relativePoint, xOfs, yOfs = button:GetPoint();
|
|
button:SetPoint(point, relativeTo, relativePoint, xOfs, offsetY);
|
|
end
|
|
end
|
|
end
|
|
|
|
--Update toggle visual
|
|
if showDates then
|
|
ChainFrame.DateToggle:SetLabelText(L["Hide Dates"]);
|
|
else
|
|
ChainFrame.DateToggle:SetLabelText(L["Show Dates"]);
|
|
end
|
|
ChainFrame.count:SetShown(not showDates);
|
|
ChainFrame.header:SetShown(not showDates);
|
|
ChainFrame.divLeft:SetShown(not showDates);
|
|
ChainFrame.divRight:SetShown(not showDates);
|
|
end
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
NarciAchievementGoToCategoryButtonMixin = {};
|
|
|
|
function NarciAchievementGoToCategoryButtonMixin:OnLoad()
|
|
GoToCategoryButton = self;
|
|
self:OnLeave();
|
|
end
|
|
|
|
function NarciAchievementGoToCategoryButtonMixin:OnEnter()
|
|
self.Label:SetTextColor(0.8, 0.8, 0.8);
|
|
self.Icon:SetTexCoord(0.5, 1, 0, 1);
|
|
self.Icon:SetAlpha(0.6);
|
|
end
|
|
|
|
function NarciAchievementGoToCategoryButtonMixin:OnLeave()
|
|
self.Label:SetTextColor(0.6, 0.6, 0.6);
|
|
self.Icon:SetTexCoord(0, 0.5, 0, 1);
|
|
self.Icon:SetAlpha(0.4);
|
|
end
|
|
|
|
function NarciAchievementGoToCategoryButtonMixin:OnClick()
|
|
if self.categoryID then
|
|
local categoryButton = DataProvider:GetCategoryButtonByID(self.categoryID, self.isGuild);
|
|
if categoryButton and (self.categoryID ~= DataProvider.currentCategory) then
|
|
if not categoryButton.isParentButton then
|
|
local parentCategoryButton = DataProvider:GetCategoryButtonByID(self.parentCategoryID, self.isGuild);
|
|
ExpandCategoryButtonNoAnimation(parentCategoryButton);
|
|
end
|
|
categoryButton:Click();
|
|
animFlyOut.noTranslation = true;
|
|
animFlyOut:Play();
|
|
|
|
InspectionFrame:ScrollToCategoryButton(categoryButton);
|
|
|
|
AchievementContainer:Show();
|
|
SummaryButton:Show();
|
|
else
|
|
animFlyOut:Play();
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciAchievementGoToCategoryButtonMixin:SetAchievement(achievementID, isGuild)
|
|
local categoryID = DataProvider:GetAchievementCategory(achievementID);
|
|
local name, parentCategoryID = DataProvider:GetCategoryInfo(categoryID);
|
|
if categoryID then
|
|
self.categoryID = categoryID;
|
|
self.parentCategoryID = parentCategoryID;
|
|
self.isGuild = isGuild;
|
|
self.Label:SetText(name);
|
|
self:Show();
|
|
self:SetWidth(max(self.Label:GetWidth() + 60, 96));
|
|
end
|
|
end
|
|
|
|
|
|
NarciMetaAchievementButtonMixin = {};
|
|
|
|
function NarciMetaAchievementButtonMixin:SetAchievement()
|
|
local id = self.id;
|
|
if id then
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText = DataProvider:GetAchievementInfo(id);
|
|
local parent = self:GetParent():GetParent();
|
|
parent.name:SetText(name);
|
|
parent.description:SetText(description);
|
|
parent.points:SetText(points);
|
|
parent.shield:SetShown(points ~= 0);
|
|
if completed then
|
|
if IsAccountWide(flags) then
|
|
parent.name:SetTextColor(0.427, 0.812, 0.965);
|
|
else
|
|
parent.name:SetTextColor(1, 0.91, 0.647);
|
|
end
|
|
else
|
|
parent.name:SetTextColor(0.8, 0.8, 0.8);
|
|
end
|
|
|
|
self.name = name;
|
|
end
|
|
end
|
|
|
|
function NarciMetaAchievementButtonMixin:OnEnter()
|
|
if self.textMode then
|
|
local parent = self:GetParent():GetParent();
|
|
parent.name:SetText(self.criteriaString);
|
|
parent.description:SetText(nil);
|
|
parent.points:SetText(nil);
|
|
parent.shield:Hide();
|
|
else
|
|
self:SetAchievement();
|
|
end
|
|
self.icon.animIn:Play();
|
|
self.border.animIn:Play();
|
|
end
|
|
|
|
function NarciMetaAchievementButtonMixin:OnLeave()
|
|
self.icon.animIn:Stop();
|
|
self.border.animIn:Stop();
|
|
self.icon:SetScale(1);
|
|
self.border:SetScale(1);
|
|
end
|
|
|
|
function NarciMetaAchievementButtonMixin:OnClick()
|
|
if ProcessModifiedClick(self) then return end;
|
|
|
|
local id = InspectionFrame.currentAchievementID;
|
|
if id and id ~= self.id then
|
|
ReturnButton:AddToQueue(id, InspectionFrame.currentAchievementName);
|
|
InspectAchievement(self.id);
|
|
end
|
|
end
|
|
|
|
NarciAchievementChainButtonMixin = {};
|
|
|
|
function NarciAchievementChainButtonMixin:OnLoad()
|
|
|
|
end
|
|
|
|
function NarciAchievementChainButtonMixin:OnEnter()
|
|
self:SetAchievement();
|
|
self.icon.animIn:Play();
|
|
self.border.animIn:Play();
|
|
end
|
|
|
|
function NarciAchievementChainButtonMixin:OnLeave()
|
|
self.icon.animIn:Stop();
|
|
self.border.animIn:Stop();
|
|
self.icon:SetScale(1);
|
|
self.border:SetScale(1);
|
|
|
|
Tooltip:FadeOut();
|
|
local ChainFrame = self:GetParent();
|
|
if ChainFrame.DateToggle and not ChainFrame:IsMouseOver() then
|
|
ChainFrame.DateToggle:FadeOut();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementChainButtonMixin:SetAchievement()
|
|
local id = self.id;
|
|
if id then
|
|
Tooltip:ClearAllPoints();
|
|
Tooltip:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 1, -2);
|
|
Tooltip:SetAchievement(id);
|
|
end
|
|
end
|
|
|
|
function NarciAchievementChainButtonMixin:OnMouseDown()
|
|
Tooltip:FadeOut();
|
|
end
|
|
|
|
NarciAchievementTooltipMixin = {};
|
|
|
|
function NarciAchievementTooltipMixin:OnLoad()
|
|
NarciAPI.NineSliceUtil.SetUpBorder(self.FrameBorder, "whiteBorder", -12, 0.67, 0.67, 0.67);
|
|
|
|
local animFade = NarciAPI_CreateAnimationFrame(0.25);
|
|
self.animFade = animFade;
|
|
animFade:SetScript("OnUpdate", function(frame, elapsed)
|
|
frame.total = frame.total + elapsed;
|
|
local alpha = outQuart(frame.total, frame.fromAlpha, frame.toAlpha, frame.duration);
|
|
if frame.total >= frame.duration then
|
|
frame:Hide();
|
|
alpha = frame.toAlpha;
|
|
if alpha == 0 then
|
|
self:Hide();
|
|
end
|
|
end
|
|
self:SetAlpha(alpha);
|
|
end)
|
|
|
|
function self:FadeIn()
|
|
if InspectionFrame.isTransiting then return end;
|
|
self:Show();
|
|
animFade:Hide();
|
|
animFade.fromAlpha = self:GetAlpha();
|
|
animFade.toAlpha = 1;
|
|
animFade:Show();
|
|
end
|
|
|
|
function self:FadeOut()
|
|
animFade.toAlpha = 0;
|
|
if not self:IsShown() then return end;
|
|
animFade:Hide();
|
|
animFade.fromAlpha = self:GetAlpha();
|
|
animFade:Show();
|
|
end
|
|
|
|
local showDelay = NarciAPI_CreateAnimationFrame(0.12);
|
|
self.showDelay = showDelay;
|
|
showDelay:SetScript("OnUpdate", function(frame, elapsed)
|
|
frame.total = frame.total + elapsed;
|
|
if frame.total >= frame.duration then
|
|
frame:Hide();
|
|
if animFade.toAlpha == 1 then
|
|
self:FadeIn();
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
function NarciAchievementTooltipMixin:OnHide()
|
|
self:Hide();
|
|
self:SetAlpha(0);
|
|
end
|
|
|
|
function NarciAchievementTooltipMixin:ResizeAndShow()
|
|
self:SetHeight( self.name:GetHeight() + self.description:GetHeight() + 4 + 24 );
|
|
self:SetWidth( max(self.name:GetWrappedWidth() + (self.points:IsShown() and 48 or 0), self.description:GetWrappedWidth() + (self.date:IsShown() and 88 or 0) ) + 24);
|
|
|
|
if not self:IsShown() then
|
|
self.animFade.toAlpha = 1;
|
|
self.showDelay:Show();
|
|
elseif self.animFade.toAlpha == 0 then
|
|
self:FadeIn();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementTooltipMixin:SetAchievement(id)
|
|
local _, name, points, completed, month, day, year, description, flags, icon = DataProvider:GetAchievementInfo(id);
|
|
|
|
self.name:SetText(name);
|
|
self.description:SetText(description);
|
|
|
|
if completed then
|
|
if IsAccountWide(flags) then
|
|
self.name:SetTextColor(0.427, 0.812, 0.965);
|
|
else
|
|
self.name:SetTextColor(1, 0.91, 0.647);
|
|
end
|
|
self.date:SetText( FormatDate(day, month, year) );
|
|
self.date:Show();
|
|
else
|
|
self.name:SetTextColor(0.8, 0.8, 0.8);
|
|
self.date:SetText("");
|
|
self.date:Hide();
|
|
end
|
|
|
|
if points == 0 then
|
|
self.shield:Hide();
|
|
self.points:Hide();
|
|
else
|
|
self.shield:Show();
|
|
self.points:SetText(points);
|
|
self.points:Show();
|
|
end
|
|
|
|
self:ResizeAndShow();
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
NarciAchievementReturnButtonMixin = {};
|
|
|
|
function NarciAchievementReturnButtonMixin:OnLoad()
|
|
ReturnButton = self;
|
|
self.structure = {};
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:PlayFlyIn()
|
|
self.flyIn:Play();
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:OnEnter()
|
|
self.label:SetTextColor(0.88, 0.88, 0.88);
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:OnLeave()
|
|
self.label:SetTextColor(0.6, 0.6, 0.6);
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:OnHide()
|
|
self:Hide();
|
|
self:StopAnimating();
|
|
wipe(self.structure);
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:SetLabelText(text)
|
|
self.label:SetText("");
|
|
self.label:SetWidth(0);
|
|
self.label:SetText(text);
|
|
|
|
local textWidth = min(140, self.label:GetWidth());
|
|
self.label:SetWidth(textWidth)
|
|
self:SetWidth(textWidth + 24);
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:AddToQueue(achievementID, achievementName)
|
|
for i = 1, #self.structure + 1 do
|
|
if self.structure[i] == nil then
|
|
self.structure[i] = {id = achievementID, name = achievementName};
|
|
break;
|
|
end
|
|
end
|
|
self:SetLabelText(achievementName);
|
|
self:Show();
|
|
self:PlayFlyIn();
|
|
end
|
|
|
|
function NarciAchievementReturnButtonMixin:OnClick()
|
|
for i = #self.structure, 1, -1 do
|
|
local info = self.structure[i];
|
|
if info and info.id then
|
|
InspectAchievement(info.id);
|
|
if i == 1 then
|
|
self:Hide();
|
|
else
|
|
self:SetLabelText(self.structure[i - 1].name)
|
|
end
|
|
self.structure[i] = nil;
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
NarciAchievementSearchBoxMixin = {};
|
|
|
|
local function InspectResult(button)
|
|
local playAnimation = not InspectionFrame:IsShown();
|
|
|
|
local id = button.id;
|
|
local Card = InspectionFrame.Card;
|
|
Card:ClearAllPoints();
|
|
Card:SetPoint("BOTTOM", InspectionFrame, "CENTER", 0, 36);
|
|
|
|
InspectionFrame.PrevButton:Disable();
|
|
InspectionFrame.NextButton:Disable();
|
|
InspectionFrame.pauseScroll = true;
|
|
|
|
InspectAchievement(id);
|
|
|
|
animFlyOut.button = nil;
|
|
animFlyOut.fromX, animFlyOut.toX, animFlyOut.fromY, animFlyOut.toY = 0, 0, 0, 0;
|
|
animFlyOut.noTranslation = true;
|
|
|
|
if playAnimation then
|
|
animFlyIn:Play();
|
|
if DataProvider:IsStatistic(id) then
|
|
InspectionFrame.StatCard:SetAlpha(0);
|
|
FadeFrame(InspectionFrame.StatCard, 0.25, 1);
|
|
end
|
|
end
|
|
end
|
|
|
|
addon.InspectResult = InspectResult;
|
|
|
|
|
|
--------------------------------------------------------------
|
|
local DateUtil = {};
|
|
function DateUtil:GetToday()
|
|
self.today = time();
|
|
end
|
|
|
|
function DateUtil:GetDifference(day, month, year)
|
|
year = 2000 + year;
|
|
local past = time( {day = day, month = month, year = year} )
|
|
if not self.today then
|
|
self.today = time();
|
|
end
|
|
return (self.today - past)
|
|
end
|
|
|
|
function DateUtil:GetPastDays(day, month, year)
|
|
local diff = self:GetDifference(day, month, year);
|
|
local d = floor(diff / 86400);
|
|
if d <= 0 then
|
|
return L["Today"]
|
|
elseif d == 1 then
|
|
return L["Yesterday"]
|
|
elseif d < 31 then
|
|
return format(L["Format Days Ago"], d);
|
|
else
|
|
local m = floor(d / 30.5);
|
|
if m <= 1 then
|
|
return L["A Month Ago"]
|
|
elseif m < 12 then
|
|
return format(L["Format Months Ago"], m);
|
|
else
|
|
local y = floor(m / 12 + 0.15);
|
|
if y == 1 then
|
|
return L["A Year Ago"]
|
|
else
|
|
return format(L["Format Years Ago"], y);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local UpdateHeaderFrame;
|
|
|
|
function UpdateSummaryFrame(breakLoop)
|
|
local recentAchievements = { GetLatestCompletedAchievements(isGuildView) };
|
|
local numAchievements = #recentAchievements;
|
|
if (numAchievements < 5) and (not breakLoop) then
|
|
After(0.05, function()
|
|
UpdateSummaryFrame(true);
|
|
end);
|
|
return
|
|
end
|
|
|
|
ScrollUtil:ResetHeights();
|
|
processor:Hide();
|
|
AchievementContainer.scrollBar:SetValue(0);
|
|
for i = 1, NUM_ACHIEVEMENT_CARDS do
|
|
AchievementCards[i]:Hide();
|
|
end
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild;
|
|
for i = 1, #recentAchievements do
|
|
id = recentAchievements[i];
|
|
if id then
|
|
id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild = DataProvider:GetAchievementInfo(id);
|
|
if i <= NUM_ACHIEVEMENT_CARDS then
|
|
FormatAchievementCardByIndex(i, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, true);
|
|
AchievementCards[i].date:SetText( DateUtil:GetPastDays(day, month, year) );
|
|
end
|
|
ScrollUtil:SetCardData(i, id, description, rewardText);
|
|
else
|
|
break;
|
|
end
|
|
end
|
|
UpdateAchievementScrollRange();
|
|
ScrollUtil:UpdateScrollChild(0);
|
|
UpdateHeaderFrame(isGuildView);
|
|
if numAchievements ~= 0 then
|
|
animFlip:Play(1);
|
|
end
|
|
InspectionFrame.numAchievements = numAchievements;
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
|
|
function TabUtil:SaveOffset()
|
|
--currentTab before switching
|
|
local button = DataProvider:GetCategoryButtonByID(DataProvider.currentCategory);
|
|
local offset = CategoryContainer.scrollBar:GetValue();
|
|
if self.tabID == 1 then
|
|
--achievement
|
|
self.lastPlayerButton = button;
|
|
self.lastPlayerScrollValue = offset;
|
|
|
|
elseif self.tabID == 2 then
|
|
--guild
|
|
self.lastGuildButton = button;
|
|
self.lastGuildScrollValue = offset;
|
|
|
|
elseif self.tabID == 3 then
|
|
--statistics
|
|
self.lastStatButton = button;
|
|
self.lastStatScrollValue = offset;
|
|
end
|
|
ShutInspection();
|
|
end
|
|
|
|
function TabUtil:ResumeOffset()
|
|
local lastButton, lastOffset;
|
|
if self.tabID == 1 then
|
|
lastButton = self.lastPlayerButton;
|
|
lastOffset = self.lastPlayerScrollValue;
|
|
elseif self.tabID == 2 then
|
|
lastButton = self.lastGuildButton;
|
|
lastOffset = self.lastGuildScrollValue;
|
|
elseif self.tabID == 3 then
|
|
lastButton = self.lastStatButton;
|
|
lastOffset = self.lastStatScrollValue;
|
|
end
|
|
if lastButton then
|
|
AchievementContainer:Show();
|
|
SummaryButton:Show();
|
|
SubCategoryButton_OnClick(lastButton);
|
|
ToggleFeatOfStrenghtText(lastButton);
|
|
else
|
|
if self.tabID == 4 then
|
|
|
|
else
|
|
SummaryButton:Click();
|
|
end
|
|
end
|
|
AchievementContainer.scrollBar:SetValue(0);
|
|
CategoryContainer.scrollBar:SetValue(lastOffset or 0);
|
|
end
|
|
|
|
function TabUtil:ToggleAchievement(tabID)
|
|
if tabID ~= self.tabID then
|
|
self:SaveOffset();
|
|
self.tabID = tabID;
|
|
local isGuild = (tabID == 2);
|
|
isGuildView = isGuild;
|
|
CategoryContainer.ScrollChild.PlayerCategory:SetShown(not isGuild);
|
|
CategoryContainer.ScrollChild.GuildCategory:SetShown(isGuild);
|
|
CategoryContainer.ScrollChild.StatsCategory:Hide();
|
|
DIYContainer:Hide();
|
|
EditorContainer:Hide();
|
|
CategoryContainer:Show();
|
|
UpdateCategoryScrollRange();
|
|
MainFrame.HeaderFrame.points:SetText( BreakUpLargeNumbers(GetTotalAchievementPoints(isGuild)) );
|
|
FilterButton:Enable();
|
|
SummaryButton:SetMode(1);
|
|
self:ResumeOffset();
|
|
self:EnableSearchBox(true);
|
|
end
|
|
end
|
|
|
|
function TabUtil:ToggleStats()
|
|
if self.tabID == 3 then return end;
|
|
self:SaveOffset();
|
|
self.tabID = 3;
|
|
CategoryContainer.ScrollChild.StatsCategory:Show();
|
|
CategoryContainer.ScrollChild.PlayerCategory:Hide();
|
|
CategoryContainer.ScrollChild.GuildCategory:Hide();
|
|
MainFrame.FeatOfStrengthText:Hide();
|
|
MainFrame:UpdatePinCount();
|
|
DIYContainer:Hide();
|
|
EditorContainer:Hide();
|
|
CategoryContainer:Show();
|
|
UpdateCategoryScrollRange();
|
|
FilterButton:Disable();
|
|
SummaryButton:SetMode(2);
|
|
self:ResumeOffset();
|
|
self:EnableSearchBox(true);
|
|
end
|
|
|
|
function TabUtil:ToggleDIY()
|
|
if self.tabID == 4 then return end;
|
|
self:SaveOffset();
|
|
self.tabID = 4;
|
|
DataProvider.currentCategory = nil;
|
|
DIYContainer:Show();
|
|
if not TabUtil.isDIYLoaded then
|
|
TabUtil.isDIYLoaded = true;
|
|
DIYContainer:Refresh();
|
|
DIYContainer.scrollBar:SetValue(0);
|
|
end
|
|
|
|
EditorContainer:Show();
|
|
CategoryContainer:Hide();
|
|
AchievementContainer:Hide();
|
|
FilterButton:Disable();
|
|
SummaryButton:SetMode(3);
|
|
MainFrame.FeatOfStrengthText:Hide();
|
|
self:EnableSearchBox(false);
|
|
end
|
|
|
|
function TabUtil:GetTabID()
|
|
return self.tabID or 1;
|
|
end
|
|
--------------------------------------------------------------
|
|
NarciAchievementFilterButtonMixin = {};
|
|
|
|
function NarciAchievementFilterButtonMixin:OnLoad()
|
|
self:OnLeave();
|
|
FilterButton = self;
|
|
self.OnLoad = nil;
|
|
self:SetScript("OnLoad", nil);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnClick()
|
|
local state = not NarciAchievementOptions.IncompleteFirst;
|
|
NarciAchievementOptions.IncompleteFirst = state;
|
|
self:UpdateFilter();
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnEnable()
|
|
self.label:SetTextColor(0.8, 0.8, 0.8);
|
|
self:EnableMouse(true);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnDisable()
|
|
self.label:SetTextColor(0.5, 0.5, 0.5);
|
|
self:EnableMouse(false);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:UpdateFilter()
|
|
if NarciAchievementOptions.IncompleteFirst then
|
|
self.label:SetText(L["Incomplete First"]);
|
|
SwitchToSortMethod(1);
|
|
else
|
|
self.label:SetText(L["Earned First"]);
|
|
SwitchToSortMethod(2);
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnMouseDown()
|
|
self.texture:SetTexCoord(0, 1, 0.5, 1);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnMouseUp()
|
|
self.texture:SetTexCoord(0, 1, 0, 0.5);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnEnter()
|
|
self.texture:SetVertexColor(1, 1, 1);
|
|
end
|
|
|
|
function NarciAchievementFilterButtonMixin:OnLeave()
|
|
self.texture:SetVertexColor(0.66, 0.66, 0.66);
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
NarciAchievementSummaryButtonMixin = {};
|
|
|
|
function NarciAchievementSummaryButtonMixin:OnClick()
|
|
self:Hide();
|
|
local categoryID;
|
|
if self.modeID == 2 then
|
|
AchievementContainer:Show();
|
|
SelectCategory(-2);
|
|
animExpand:CollapseAll();
|
|
categoryID = - 2;
|
|
else
|
|
categoryID = -1;
|
|
SelectCategory(-1);
|
|
end
|
|
if DataProvider.currentCategory ~= categoryID then
|
|
animExpand:CollapseAll();
|
|
DataProvider.currentCategory = categoryID;
|
|
end
|
|
MainFrame.FeatOfStrengthText:Hide();
|
|
end
|
|
|
|
function NarciAchievementSummaryButtonMixin:OnMouseDown()
|
|
self.texture:SetTexCoord(0, 1, 0.5, 0.8125);
|
|
self.label:SetTextColor(0.6, 0.6, 0.6);
|
|
end
|
|
|
|
function NarciAchievementSummaryButtonMixin:OnMouseUp()
|
|
self.texture:SetTexCoord(0, 1, 0, 0.3125);
|
|
self.label:SetTextColor(0.8, 0.8, 0.8);
|
|
end
|
|
|
|
function NarciAchievementSummaryButtonMixin:SetMode(modeID)
|
|
self.modeID = modeID;
|
|
if modeID == 3 then
|
|
self:Show();
|
|
self:Disable();
|
|
self.label:SetText("DIY");
|
|
else
|
|
if modeID == 1 then
|
|
self.label:SetText(ACHIEVEMENT_SUMMARY_CATEGORY);
|
|
else
|
|
self.label:SetText(L["Pinned Entries"]);
|
|
end
|
|
self:Enable();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementSummaryButtonMixin:OnEnable()
|
|
self:EnableMouse(true);
|
|
self:OnMouseUp();
|
|
end
|
|
|
|
function NarciAchievementSummaryButtonMixin:OnDisable()
|
|
self:EnableMouse();
|
|
self:OnMouseDown();
|
|
end
|
|
------------------------------------------------------------------
|
|
|
|
|
|
local function CreateTabButtons()
|
|
local tabNames = {ACHIEVEMENTS, ACHIEVEMENTS_GUILD_TAB, STATISTICS, "DIY", L["Settings"]};
|
|
local frame = Narci_AchievementFrame;
|
|
local buttons = {};
|
|
local function DeselectRest(button)
|
|
for i = 1, #buttons do
|
|
if buttons[i] ~= button then
|
|
buttons[i]:Deselect();
|
|
end
|
|
end
|
|
end
|
|
|
|
local funcs = {
|
|
function(self)
|
|
TabUtil:ToggleAchievement(1);
|
|
DeselectRest(self);
|
|
self:Select();
|
|
end,
|
|
|
|
function(self)
|
|
TabUtil:ToggleAchievement(2);
|
|
DeselectRest(self);
|
|
self:Select();
|
|
end,
|
|
|
|
function(self)
|
|
TabUtil:ToggleStats();
|
|
DeselectRest(self);
|
|
self:Select();
|
|
end,
|
|
|
|
function(self)
|
|
TabUtil:ToggleDIY();
|
|
DeselectRest(self);
|
|
self:Select();
|
|
end,
|
|
|
|
function(self)
|
|
MainFrame.Settings:Toggle();
|
|
end,
|
|
}
|
|
|
|
local numTabs = #tabNames;
|
|
for i = 1, numTabs do
|
|
local button = CreateFrame("Button", nil, frame, "NarciAchievementTabButtonTemplate");
|
|
tinsert(buttons, button);
|
|
button:SetLabel(tabNames[i]);
|
|
button.id = i;
|
|
|
|
if i == 1 then
|
|
button:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 23, 0);
|
|
button:Select();
|
|
elseif i == numTabs then
|
|
--settings
|
|
button:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", -23, 0);
|
|
MainFrame.Settings.linkedTabButton = button;
|
|
else
|
|
button:SetPoint("TOPLEFT", buttons[i - 1], "TOPRIGHT", 14, 0);
|
|
end
|
|
|
|
button:SetScript("OnClick", funcs[i]);
|
|
end
|
|
|
|
TabButtons = buttons;
|
|
|
|
TabUtil:ToggleAchievement(1);
|
|
end
|
|
----------------------------------------------------------------------------------
|
|
local function GetInspectedCardLink()
|
|
local achievementID = InspectionFrame.currentAchievementID;
|
|
if not achievementID then return end;
|
|
|
|
local URL = NarciLanguageUtil:GetWowheadLink();
|
|
URL = URL .. "achievement=" .. tostring(achievementID);
|
|
|
|
return URL
|
|
end
|
|
|
|
NarciAchievementGetLinkButtonMixin = {};
|
|
|
|
function NarciAchievementGetLinkButtonMixin:OnLoad()
|
|
self.Label:SetText(L["External Link"]);
|
|
local textWidth = max(40, floor( self.Label:GetWidth() + 0.5 ) );
|
|
self:SetWidth(textWidth + 40 + 16);
|
|
|
|
local range = textWidth + 24;
|
|
self.Icon:SetPoint("RIGHT", self, "RIGHT", -18, 0);
|
|
|
|
|
|
local animShow = NarciAPI_CreateAnimationFrame(0.25);
|
|
self.animShow = animShow;
|
|
animShow:SetScript("OnUpdate", function(frame, elapsed)
|
|
frame.total = frame.total + elapsed;
|
|
local offsetX = inOutSine(frame.total, frame.fromX, frame.toX, frame.duration);
|
|
local textOffset = inOutSine(frame.total, frame.fromTextX, frame.toTextX, frame.duration);
|
|
local alpha = outQuart(frame.total, frame.fromAlpha, frame.toAlpha, frame.duration);
|
|
if frame.total >= frame.duration then
|
|
offsetX = frame.toX;
|
|
textOffset = frame.toTextX;
|
|
alpha = frame.toAlpha;
|
|
frame:Hide();
|
|
|
|
if alpha == 0 then
|
|
self.Clipboard:Hide();
|
|
end
|
|
end
|
|
self.Icon:SetPoint("RIGHT", self, "RIGHT", offsetX, 0);
|
|
self.Label:SetPoint("RIGHT", self, textOffset, 0);
|
|
self.Label:SetAlpha(alpha);
|
|
self.Clipboard:SetAlpha(alpha);
|
|
end);
|
|
|
|
function self:AnimShow()
|
|
animShow:Hide();
|
|
local offsetX, _;
|
|
_, _, _, offsetX = self.Icon:GetPoint();
|
|
_, _, _, animShow.fromTextX = self.Label:GetPoint();
|
|
animShow.duration = ( sqrt(1 - abs(offsetX)/ range) * 0.4);
|
|
animShow.fromX = offsetX;
|
|
animShow.toX = -range;
|
|
--animShow.fromTextX = -28; --keep label still
|
|
animShow.toTextX = -28;
|
|
animShow.fromAlpha = self.Label:GetAlpha();
|
|
animShow.toAlpha = 1;
|
|
animShow:Show();
|
|
end
|
|
|
|
function self:AnimHide()
|
|
animShow:Hide();
|
|
local offsetX, _;
|
|
_, _, _, offsetX = self.Icon:GetPoint();
|
|
_, _, _, animShow.fromTextX = self.Label:GetPoint();
|
|
animShow.duration = ( sqrt(abs(offsetX)/ range) * 0.5);
|
|
animShow.fromX = offsetX;
|
|
animShow.toX = -20;
|
|
animShow.toTextX = -10;
|
|
animShow.fromAlpha = self.Label:GetAlpha();
|
|
animShow.toAlpha = 0;
|
|
animShow:Show();
|
|
end
|
|
|
|
self.Clipboard:SetScript("OnLeave", function()
|
|
self:OnLeave();
|
|
end);
|
|
self.Clipboard.EditBox:SetScript("OnLeave", function()
|
|
self:OnLeave();
|
|
end);
|
|
|
|
self.Clipboard:ReAnchorTooltipToObject(self.Label);
|
|
self.Clipboard.EditBox.onQuitFunc = function()
|
|
self:OnLeave();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementGetLinkButtonMixin:OnClick()
|
|
self.Clipboard:ShowClipboard();
|
|
self.Clipboard:SetText( GetInspectedCardLink() );
|
|
self.Clipboard:SetFocus();
|
|
self.Label:Hide();
|
|
end
|
|
|
|
function NarciAchievementGetLinkButtonMixin:OnEnter()
|
|
--self.Label:SetTextColor(1, 1, 1);
|
|
self.Icon:SetTexCoord(0.5, 1, 0, 1);
|
|
self.Icon:SetAlpha(0.6);
|
|
self:AnimShow();
|
|
self.Label:Show();
|
|
end
|
|
|
|
function NarciAchievementGetLinkButtonMixin:OnLeave()
|
|
if not self:IsMouseOver() and not self.Clipboard:HasFocus() then
|
|
self.Label:SetTextColor(0.8, 0.8, 0.8);
|
|
self.Icon:SetTexCoord(0, 0.5, 0, 1);
|
|
self.Icon:SetAlpha(0.4);
|
|
self:AnimHide();
|
|
self.Clipboard.EditBox:HighlightText(0, 0);
|
|
end
|
|
end
|
|
|
|
|
|
--------------------------------------------------------
|
|
local function InitializeFrame(frame)
|
|
--Category
|
|
CategoryContainer = frame.CategoryFrame;
|
|
local isGuild = true;
|
|
CreateCategoryButtons(2);
|
|
isGuild = not isGuild;
|
|
CreateCategoryButtons(1);
|
|
CreateCategoryButtons(3);
|
|
local numCategories = CategoryStructure.player.numCategories;
|
|
local deltaRatio = 2;
|
|
local speedRatio = 0.15;
|
|
local buttonHeight = 32;
|
|
local range = numCategories * (buttonHeight + 4) - CategoryContainer:GetHeight();
|
|
local positionFunc;
|
|
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(CategoryContainer, deltaRatio, speedRatio, positionFunc, buttonHeight, range);
|
|
UpdateCategoryScrollRange();
|
|
|
|
|
|
--Sort Method
|
|
FilterButton:UpdateFilter();
|
|
showNotEarnedMark = NarciAchievementOptions.ShowRedMark;
|
|
|
|
--Achievement
|
|
AchievementContainer = frame.AchievementCardFrame;
|
|
CreateAchievementButtons(AchievementContainer.ScrollChild);
|
|
|
|
local numCards = #AchievementCards;
|
|
local deltaRatio = 1;
|
|
local speedRatio = 0.24;
|
|
local buttonHeight = 64;
|
|
local range = numCards * (buttonHeight + 4) - AchievementContainer:GetHeight();
|
|
local positionFunc;
|
|
NarciAPI_ApplySmoothScrollToScrollFrame(AchievementContainer, deltaRatio, speedRatio, positionFunc, buttonHeight, range);
|
|
local scrollBar = AchievementContainer.scrollBar;
|
|
scrollBar:SetScript("OnValueChanged", function(bar, value)
|
|
AchievementContainer:SetVerticalScroll(value);
|
|
ScrollUtil:GetTopButtonIndex(value);
|
|
end);
|
|
UpdateAchievementScrollRange();
|
|
|
|
--Model Preview
|
|
MountPreview = CreateFrame("ModelScene", nil, frame,"NarciAchievementRewardModelTemplate");
|
|
MountPreview:ClearAllPoints();
|
|
MountPreview:SetPoint("LEFT", frame, "RIGHT", 4, 0);
|
|
|
|
Tooltip = frame.Tooltip;
|
|
|
|
--Header Filter, Total Points, Search, Close
|
|
local HeaderFrame = frame.HeaderFrame;
|
|
|
|
SummaryButton = frame.SummaryButton;
|
|
|
|
function UpdateHeaderFrame(isGuild) --Private
|
|
local total, completed = GetNumCompletedAchievements(isGuild);
|
|
HeaderFrame.totalAchievements:SetText(completed.."/"..total);
|
|
HeaderFrame.points:SetText( BreakUpLargeNumbers(GetTotalAchievementPoints(isGuild)) );
|
|
if completed > 0 then
|
|
HeaderFrame.fill:Show();
|
|
local percentage = completed / total;
|
|
HeaderFrame.fill:SetWidth(198 * percentage);
|
|
HeaderFrame.fill:SetTexCoord(0, percentage * 0.75, 0, 1);
|
|
if percentage == 1 then
|
|
HeaderFrame.value:SetText("100");
|
|
HeaderFrame.fillEnd:Hide();
|
|
else
|
|
HeaderFrame.value:SetText( floor(100 * percentage) );
|
|
HeaderFrame.fillEnd:Show();
|
|
end
|
|
end
|
|
HeaderFrame.value:Show();
|
|
HeaderFrame.percentSign:Show();
|
|
HeaderFrame.progress:Hide();
|
|
end
|
|
|
|
--SummaryFrame
|
|
SummaryFrame = frame.SummaryFrame;
|
|
|
|
--DIY Achievements
|
|
DIYContainer = frame.DIYContainer;
|
|
EditorContainer = frame.EditorContainer;
|
|
|
|
--Tabs
|
|
CreateTabButtons();
|
|
NarciAchievement_SelectTheme(NarciAchievementOptions.Theme or 1);
|
|
|
|
frame:Show();
|
|
UpdateSummaryFrame();
|
|
|
|
--Reclaim Temp
|
|
wipe(CategoryStructure);
|
|
CategoryStructure = nil;
|
|
CreateCategoryButtons = nil;
|
|
CreateAchievementButtons = nil;
|
|
CreateTabButtons = nil;
|
|
InitializeFrame = nil;
|
|
end
|
|
|
|
-----------------------------------------
|
|
local FloatingCard = addon.FloatingCard;
|
|
|
|
|
|
local function RefreshInspection(achievementID)
|
|
--Refresh inspection card
|
|
if InspectionFrame:IsShown() then
|
|
if achievementID then
|
|
if (achievementID == InspectionFrame.Card.id) then
|
|
InspectAchievement(achievementID);
|
|
end
|
|
else
|
|
if InspectionFrame.Card.id then
|
|
InspectAchievement(InspectionFrame.Card.id);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--------------------------------------------------------------------
|
|
--Public
|
|
NarciAchievementFrameMixin = {};
|
|
|
|
function NarciAchievementFrameMixin:OnLoad()
|
|
MainFrame = self;
|
|
|
|
ScrollUtil.textReference = self.TextHeightRetriever;
|
|
|
|
self:RegisterForDrag("LeftButton");
|
|
self:SetAttribute("nodeignore", true); --ConsolePort: Ignore this frame
|
|
end
|
|
|
|
local function AchievementFrame_OnKeyDown(self, key)
|
|
if key == "ESCAPE" then
|
|
self:SetPropagateKeyboardInput(false);
|
|
self:Hide();
|
|
else
|
|
self:SetPropagateKeyboardInput(true);
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:OnShow()
|
|
if self.pendingCategoryID then
|
|
SelectCategory(self.pendingCategoryID);
|
|
self.pendingCategoryID = nil;
|
|
elseif self.pendingUpdate then
|
|
self.pendingUpdate = nil;
|
|
UpdateSummaryFrame();
|
|
end
|
|
self:RegisterDynamicEvent(true);
|
|
RefreshInspection();
|
|
StatCardController:UpdateList();
|
|
self:SetScript("OnKeyDown", AchievementFrame_OnKeyDown);
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:OnHide()
|
|
self:RegisterDynamicEvent(false);
|
|
self:SetScript("OnKeyDown", nil);
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:RegisterDynamicEvent(state)
|
|
if state then
|
|
self:RegisterEvent("CRITERIA_UPDATE");
|
|
self:RegisterEvent("CRITERIA_COMPLETE");
|
|
else
|
|
self:UnregisterEvent("CRITERIA_UPDATE");
|
|
self:UnregisterEvent("CRITERIA_COMPLETE");
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:OnEvent(event, ...)
|
|
RefreshInspection(...);
|
|
if event == "CRITERIA_UPDATE" then
|
|
StatCardController:UpdateList();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:ShowRedMark(visible)
|
|
showNotEarnedMark = visible;
|
|
for i = 1, #AchievementCards do
|
|
if visible then
|
|
AchievementCards[i].NotEarned:SetWidth(20);
|
|
else
|
|
AchievementCards[i].NotEarned:SetWidth(0.1);
|
|
end
|
|
end
|
|
if MainFrame:IsShown() then
|
|
local categoryID = DataProvider.currentCategory;
|
|
if categoryID and categoryID ~= 0 then
|
|
SelectCategory(categoryID);
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:LocateAchievement(achievementID, clickAgainToClose)
|
|
local Card = InspectionFrame.Card;
|
|
|
|
if (not achievementID) or ( clickAgainToClose and (Card.id == achievementID) and MainFrame:IsShown() and InspectionFrame:IsShown() ) then
|
|
MainFrame:Hide();
|
|
return
|
|
end
|
|
|
|
MainFrame:Show();
|
|
local playAnimation = not InspectionFrame:IsShown();
|
|
Card:ClearAllPoints();
|
|
Card:SetPoint("BOTTOM", InspectionFrame, "CENTER", 0, 36);
|
|
|
|
InspectionFrame.PrevButton:Disable();
|
|
InspectionFrame.NextButton:Disable();
|
|
InspectionFrame.pauseScroll = true;
|
|
|
|
InspectAchievement(achievementID);
|
|
|
|
animFlyOut.button = nil;
|
|
animFlyOut.fromX, animFlyOut.toX, animFlyOut.fromY, animFlyOut.toY = 0, 0, 0, 0;
|
|
animFlyOut.noTranslation = true;
|
|
|
|
if playAnimation then
|
|
animFlyIn:Play();
|
|
end
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:OnDragStart()
|
|
self:StartMoving();
|
|
|
|
--Anchor settings frame to self
|
|
local f = self.Settings;
|
|
f:ClearAllPoints();
|
|
f:SetPoint("TOPLEFT", self, "TOPRIGHT", 8, -4);
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:OnDragStop()
|
|
self:StopMovingOrSizing();
|
|
|
|
self.Settings.AnchorToUIParent();
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:UpdatePinCount()
|
|
local HeaderFrame = self.HeaderFrame;
|
|
local total, cap = PinUtil:GetTotal();
|
|
HeaderFrame.totalAchievements:SetText(L["Pinned Entries"]);
|
|
HeaderFrame.progress:SetText(string.format("%d/%d", total, cap));
|
|
HeaderFrame.progress:Show();
|
|
HeaderFrame.value:Hide();
|
|
HeaderFrame.percentSign:Hide();
|
|
|
|
if total > 0 then
|
|
HeaderFrame.fill:Show();
|
|
local percentage = total / cap;
|
|
HeaderFrame.fill:SetWidth(198 * percentage);
|
|
HeaderFrame.fill:SetTexCoord(0, percentage * 0.75, 0, 1);
|
|
if percentage == 1 then
|
|
HeaderFrame.fillEnd:Hide();
|
|
else
|
|
HeaderFrame.fillEnd:Show();
|
|
end
|
|
else
|
|
HeaderFrame.fill:Hide();
|
|
HeaderFrame.fillEnd:Hide();
|
|
end
|
|
end
|
|
|
|
--[[
|
|
function NarciAchievement_FormatAlertCard(card)
|
|
local achievementID = card.id;
|
|
local uiScale = MainFrame:GetEffectiveScale();
|
|
card.uiScale = uiScale;
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText = DataProvider:GetAchievementInfo(achievementID);
|
|
FormatFloatingCard(card, id, name, points, completed, month, day, year, description, flags, icon, rewardText);
|
|
ReskinButton(card);
|
|
end
|
|
|
|
function NarciAchievement_ReskinButton(card)
|
|
ReskinButton(card);
|
|
card.isDarkTheme = isDarkTheme;
|
|
end
|
|
--]]
|
|
|
|
NarciAchievementLargeCardMixin = {};
|
|
|
|
function NarciAchievementLargeCardMixin:OnDragStart()
|
|
--Create Floating Card
|
|
if not self.id then return end;
|
|
self.AnimPushed:Stop();
|
|
self:Hide();
|
|
|
|
local card = FloatingCard:CreateFromCard(self, 1);
|
|
end
|
|
|
|
function NarciAchievementLargeCardMixin:OnLoad()
|
|
self:RegisterForDrag("LeftButton");
|
|
self:SetScript("OnLoad", nil);
|
|
self.OnLoad = nil;
|
|
end
|
|
|
|
function NarciAchievementLargeCardMixin:OnMouseDown()
|
|
self.AnimPushed:Stop();
|
|
self.AnimPushed.hold:SetDuration(20);
|
|
self.AnimPushed:Play();
|
|
end
|
|
|
|
function NarciAchievementLargeCardMixin:OnMouseUp()
|
|
self.AnimPushed.hold:SetDuration(0);
|
|
end
|
|
|
|
function NarciAchievementLargeCardMixin:UpdateTheme()
|
|
ReskinButton(self);
|
|
if self.id then
|
|
local visibility = self:IsShown();
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, earnedByMe = DataProvider:GetAchievementInfo(self.id);
|
|
FormatAchievementCard(self, id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, earnedByMe);
|
|
self:SetShown(visibility);
|
|
end
|
|
end
|
|
|
|
function NarciAchievement_SelectTheme(index)
|
|
if not index or index > 3 or index < 1 then
|
|
index = 1;
|
|
end
|
|
if index == themeID then return end;
|
|
|
|
themeID = index;
|
|
NarciAchievementOptions.Theme = index;
|
|
|
|
if index == 3 then
|
|
isDarkTheme = true;
|
|
texturePrefix = "Interface\\AddOns\\Narcissus_Achievements\\Art\\Flat\\";
|
|
elseif index == 2 then
|
|
isDarkTheme = false;
|
|
texturePrefix = "Interface\\AddOns\\Narcissus_Achievements\\Art\\Classic\\";
|
|
else
|
|
isDarkTheme = true;
|
|
texturePrefix = "Interface\\AddOns\\Narcissus_Achievements\\Art\\DarkWood\\";
|
|
end
|
|
|
|
--Statistics
|
|
StatCardController:SetTheme(index);
|
|
InspectionFrame.StatCard:UpdateTheme();
|
|
for i = 1, #AchievementCards do
|
|
ReskinButton(AchievementCards[i]);
|
|
end
|
|
|
|
ReskinButton(AchievementCards[-1]);
|
|
|
|
--DIY Cards
|
|
if DIYContainer.cards then
|
|
for i = 1, #DIYContainer.cards do
|
|
ReskinButton(DIYContainer.cards[i]);
|
|
DIYContainer.cards[i].isDarkTheme = isDarkTheme;
|
|
end
|
|
end
|
|
DIYContainer:RefreshTheme();
|
|
DIYContainer.NewEntry.background:SetTexture(texturePrefix.."NewEntry");
|
|
if index == 1 then
|
|
EditorContainer.notes:SetFontObject(NarciAchievementText);
|
|
EditorContainer.notes:SetTextColor(0.68, 0.58, 0.51);
|
|
elseif index == 2 then
|
|
EditorContainer.notes:SetFontObject(NarciAchievementTextBlack);
|
|
EditorContainer.notes:SetTextColor(0, 0, 0);
|
|
else
|
|
EditorContainer.notes:SetFontObject(NarciAchievementText);
|
|
EditorContainer.notes:SetTextColor(0.5, 0.5, 0.5);
|
|
end
|
|
|
|
local inspectedAchievementID = AchievementCards[-1].id;
|
|
if inspectedAchievementID then
|
|
local id, name, points, completed, month, day, year, description, flags, icon, rewardText = DataProvider:GetAchievementInfo(inspectedAchievementID);
|
|
FormatAchievementCardByIndex(-1, id, name, points, completed, month, day, year, description, flags, icon, rewardText);
|
|
end
|
|
|
|
if SummaryFrame:IsVisible() then
|
|
UpdateSummaryFrame();
|
|
else
|
|
if not DIYContainer:IsShown() then
|
|
local categoryID = DataProvider.currentCategory;
|
|
SelectCategory(categoryID);
|
|
end
|
|
end
|
|
|
|
--Search Results:
|
|
local ResultFrame = MainFrame.HeaderFrame.SearchBox.ClipFrame.ResultFrame;
|
|
local resultButtonGap;
|
|
if index == 3 then
|
|
resultButtonGap = -1;
|
|
else
|
|
resultButtonGap = -2
|
|
end
|
|
ResultFrame.background:SetTexture(texturePrefix.."SearchResultFrame");
|
|
for i = 1, #ResultFrame.buttons do
|
|
ResultFrame.buttons[i].background:SetTexture(texturePrefix.."ResultButton");
|
|
ResultFrame.buttons[i].mask:SetTexture(texturePrefix.."ResultButtonMask");
|
|
if i ~= 1 then
|
|
ResultFrame.buttons[i]:SetPoint("TOP", ResultFrame.buttons[i - 1], "BOTTOM", 0, resultButtonGap);
|
|
end
|
|
end
|
|
|
|
--Border Skin
|
|
local HeaderFrame = MainFrame.HeaderFrame;
|
|
HeaderFrame.background:SetTexture(texturePrefix.."BoxHeaderBorder");
|
|
HeaderFrame.mask:SetTexture(texturePrefix.."BoxHeaderBorderMask");
|
|
|
|
MainFrame.background:SetTexture(texturePrefix.."BoxRight");
|
|
MainFrame.categoryBackground:SetTexture(texturePrefix.."BoxLeft");
|
|
|
|
AchievementContainer.OverlayFrame.top:SetTexture(texturePrefix.."BoxRight");
|
|
AchievementContainer.OverlayFrame.bottom:SetTexture(texturePrefix.."BoxRight");
|
|
AchievementContainer.scrollBar.Thumb:SetTexture(texturePrefix.."SliderThumb");
|
|
|
|
CategoryContainer.OverlayFrame.top:SetTexture(texturePrefix.."BoxLeft");
|
|
CategoryContainer.OverlayFrame.bottom:SetTexture(texturePrefix.."BoxLeft");
|
|
CategoryContainer.scrollBar.Thumb:SetTexture(texturePrefix.."SliderThumb");
|
|
|
|
DIYContainer.OverlayFrame.top:SetTexture(texturePrefix.."BoxRight");
|
|
DIYContainer.OverlayFrame.bottom:SetTexture(texturePrefix.."BoxRight");
|
|
DIYContainer.scrollBar.Thumb:SetTexture(texturePrefix.."SliderThumb");
|
|
|
|
EditorContainer.OverlayFrame.top:SetTexture(texturePrefix.."BoxLeft");
|
|
EditorContainer.OverlayFrame.bottom:SetTexture(texturePrefix.."BoxLeft");
|
|
EditorContainer.scrollBar.Thumb:SetTexture(texturePrefix.."SliderThumb");
|
|
|
|
--Scroll frame inner Shadow
|
|
local showShadow = index == 1;
|
|
AchievementContainer.OverlayFrame.topShadow:SetShown(showShadow);
|
|
AchievementContainer.OverlayFrame.bottomShadow:SetShown(showShadow);
|
|
DIYContainer.OverlayFrame.topShadow:SetShown(showShadow);
|
|
DIYContainer.OverlayFrame.bottomShadow:SetShown(showShadow);
|
|
CategoryContainer.OverlayFrame.topShadow:SetShown(showShadow);
|
|
CategoryContainer.OverlayFrame.bottomShadow:SetShown(showShadow);
|
|
EditorContainer.OverlayFrame.topShadow:SetShown(showShadow);
|
|
EditorContainer.OverlayFrame.bottomShadow:SetShown(showShadow);
|
|
|
|
--Category Buttons
|
|
local cateButtons = {CategoryButtons.player.buttons, CategoryButtons.guild.buttons, CategoryButtons.stats.buttons};
|
|
for _, buttons in pairs(cateButtons) do
|
|
for i = 1, #buttons do
|
|
if buttons[i].isParentButton then
|
|
buttons[i].background:SetTexture(texturePrefix.."CategoryButton");
|
|
else
|
|
buttons[i].background:SetTexture(texturePrefix.."SubCategoryButton");
|
|
end
|
|
buttons[i].fill:SetTexture(texturePrefix.."CategoryButtonBar");
|
|
buttons[i].fillEnd:SetTexture(texturePrefix.."CategoryButtonBar");
|
|
end
|
|
end
|
|
|
|
HeaderFrame.fill:SetTexture(texturePrefix.."CategoryButtonBar");
|
|
HeaderFrame.fillEnd:SetTexture(texturePrefix.."CategoryButtonBar");
|
|
|
|
--Header Reposition
|
|
local offsetY = 0;
|
|
if index == 2 then
|
|
offsetY = -6;
|
|
end
|
|
|
|
local FilterButton = MainFrame.FilterButton;
|
|
FilterButton:ClearAllPoints();
|
|
FilterButton:SetPoint("TOPRIGHT", MainFrame, "TOP", -2, -12 + offsetY);
|
|
FilterButton.texture:SetTexture(texturePrefix.."DropDownButton");
|
|
|
|
local CloseButton = MainFrame.CloseButton;
|
|
CloseButton:ClearAllPoints();
|
|
CloseButton:SetPoint("TOPRIGHT", MainFrame, "TOPRIGHT", -11, -11 + offsetY);
|
|
CloseButton.texture:SetTexture(texturePrefix.."CloseButton");
|
|
if index == 2 then
|
|
CloseButton:SetSize(39, 26);
|
|
else
|
|
CloseButton:SetSize(36, 26);
|
|
end
|
|
|
|
local SearchBox = HeaderFrame.SearchBox
|
|
SearchBox:ClearAllPoints();
|
|
SearchBox:SetPoint("TOPRIGHT", HeaderFrame, "TOPRIGHT", -67, -5 + offsetY);
|
|
|
|
local points = HeaderFrame.points;
|
|
points:ClearAllPoints();
|
|
points:SetPoint("TOPRIGHT", HeaderFrame, "TOP", 137, -17 + offsetY);
|
|
|
|
local reference = HeaderFrame.reference; --Summary All Points/Achv
|
|
if index == 2 then
|
|
reference:SetHeight(35);
|
|
else
|
|
reference:SetHeight(32);
|
|
end
|
|
|
|
SummaryButton:ClearAllPoints();
|
|
SummaryButton:SetPoint("TOPLEFT", MainFrame, "TOPLEFT", 32, -8 + offsetY);
|
|
SummaryButton.texture:SetTexture(texturePrefix.."SummaryButton");
|
|
|
|
|
|
--Tab buttons
|
|
for i = 1, #TabButtons do
|
|
TabButtons[i]:SetButtonTexture(texturePrefix.."TabButton");
|
|
if index == 1 then
|
|
TabButtons[i]:SetTextOffset(28);
|
|
else
|
|
TabButtons[i]:SetTextOffset(20);
|
|
end
|
|
end
|
|
|
|
|
|
--AlertSystem
|
|
|
|
--Floating Cards
|
|
FloatingCard:SetTheme(index);
|
|
end
|
|
|
|
|
|
--------------------------------------------------------------------
|
|
local function UpdateTrackAchievements()
|
|
local changedAchievementID = DataProvider:GetTrackedAchievements();
|
|
if not changedAchievementID then return end
|
|
|
|
local currentCategory = DataProvider.currentCategory;
|
|
local categoryID = DataProvider:GetAchievementCategory(changedAchievementID);
|
|
local shouldUpdate;
|
|
if categoryID == currentCategory then
|
|
shouldUpdate = true;
|
|
end
|
|
local isTracked = DataProvider:IsTrackedAchievement(changedAchievementID);
|
|
|
|
if shouldUpdate then
|
|
local numAchievements = DataProvider.numAchievements or 0;
|
|
local card;
|
|
for i = 1, numAchievements do
|
|
card = AchievementCards[i];
|
|
if card then
|
|
if card.id == changedAchievementID then
|
|
card.trackIcon:SetShown(isTracked);
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if (InspectionFrame:IsShown()) and (changedAchievementID == InspectionFrame.Card.id) then
|
|
InspectionFrame.Card.trackIcon:SetShown(isTracked);
|
|
end
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
function NarciAchievementFrameMixin:Init()
|
|
DataProvider:GetTrackedAchievements();
|
|
PinUtil:Load();
|
|
addon.LoadDIY();
|
|
self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED");
|
|
BuildCategoryStructure(2);
|
|
BuildCategoryStructure(1);
|
|
BuildCategoryStructure(3);
|
|
InitializeFrame(Narci_AchievementFrame);
|
|
self:RegisterEvent("ACHIEVEMENT_EARNED");
|
|
self:RegisterEvent("CRITERIA_EARNED");
|
|
self.Init = nil;
|
|
end
|
|
|
|
function NarciAchievementFrameMixin:InspectCard(card, playAnimation)
|
|
InspectCard(card, playAnimation);
|
|
end
|
|
|
|
|
|
local function OnAchivementEarned(achievementID)
|
|
DataProvider:UpdateAchievementCache(achievementID);
|
|
RefreshInspection(achievementID);
|
|
|
|
local categoryID = DataProvider:GetAchievementCategory(achievementID);
|
|
if categoryID then
|
|
if DataProvider.achievementOrderCache[categoryID] then
|
|
wipe(DataProvider.achievementOrderCache[categoryID]);
|
|
end
|
|
UpdateCategoryButtonProgressByCategoryID(categoryID);
|
|
if categoryID == DataProvider.currentCategory then
|
|
if MainFrame:IsShown() then
|
|
SelectCategory(categoryID);
|
|
else
|
|
MainFrame.pendingCategoryID = categoryID;
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
if SummaryFrame:IsShown() then
|
|
MainFrame.pendingUpdate = true;
|
|
end
|
|
end
|
|
|
|
local EventListener = CreateFrame("Frame");
|
|
EventListener:RegisterEvent("ACHIEVEMENT_EARNED");
|
|
EventListener:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED");
|
|
|
|
EventListener:SetScript("OnEvent", function(self, event, ...)
|
|
if event == "ACHIEVEMENT_EARNED" then
|
|
local achievementID = ...;
|
|
OnAchivementEarned(achievementID);
|
|
if not self.pauseUpdate then
|
|
self.pauseUpdate = true;
|
|
After(0, function()
|
|
UpdateHeaderFrame(isGuildView);
|
|
self.pauseUpdate = nil;
|
|
end);
|
|
end
|
|
elseif event == "TRACKED_ACHIEVEMENT_LIST_CHANGED" then
|
|
UpdateTrackAchievements();
|
|
end
|
|
end)
|
|
|
|
|
|
|
|
addon.ReskinButton = ReskinButton;
|
|
addon.FormatAchievementCard = FormatAchievementCard;
|
|
|
|
local function IsDarkTheme()
|
|
return isDarkTheme;
|
|
end
|
|
|
|
addon.IsDarkTheme = IsDarkTheme;
|