--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 format = string.format ;
local tremove = table.remove ;
local tinsert = table.insert ;
local GetAchievementCategory = GetAchievementCategory ;
local GetAchievementInfo = GetAchievementInfo ;
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 GetCategoryNumAchievements = GetCategoryNumAchievements ;
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
--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 \n 20%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 \n 20%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 \\ Art \\ Modules \\ Achievement \\ 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 ) ;
if isDarkTheme then
button.description : SetFontObject ( NarciAchievementText ) ;
else
button.description : SetFontObject ( NarciAchievementTextBlack ) ;
end
--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 ;
local CategoryContainer , AchievementContainer , DIYContainer , EditorContainer , SummaryFrame , AchievementCards , SummaryCards , ResultFrame , ResultButtons , TabButtons ;
local CategoryButtons = {
player = { parentButtons = { } , buttons = { } , } ,
guild = { parentButtons = { } , buttons = { } , } ,
} ;
function CategoryButtons : GetActiveParentButtons ( isGuild )
if isGuild or isGuildView then
return self.guild . parentButtons ;
else
return self.player . parentButtons ;
end
end
local CategoryStructure = {
player = { } ,
guild = { } ,
} ;
local DataProvider = { } ;
DataProvider.categoryCache = { } ;
DataProvider.achievementCache = { } ;
DataProvider.achievementOrderCache = { } ;
DataProvider.id2Button = { } ;
DataProvider.currentCategory = 0 ;
DataProvider.isTrackedAchievements = { } ;
DataProvider.trackedAchievements = { } ;
function DataProvider : ClearCache ( )
wipe ( self.categoryCache ) ;
wipe ( self.achievementCache ) ;
collectgarbage ( " collect " ) ;
end
function DataProvider : GetCategoryInfo ( id , index )
if not self.categoryCache [ id ] then
local name , parentID , flags = GetCategoryInfo ( id ) ;
if name then
self.categoryCache [ id ] = { name , parentID , flags } ;
end
return name , parentID , flags ;
else
if index then
return self.categoryCache [ id ] [ index ] ;
else
return unpack ( self.categoryCache [ id ] ) ;
end
end
end
function DataProvider : GetAchievementInfo ( id , index )
if not self.achievementCache [ id ] then
local id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe , earnedBy = GetAchievementInfo ( id ) ;
if isGuild then
SetFocusedAchievement ( id ) ;
end
if description then
self.achievementCache [ id ] = { id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe } ;
end
if index then
if self.achievementCache [ id ] then
return self.achievementCache [ id ] [ index ] ;
end
else
return id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe , earnedBy
end
else
if index then
return self.achievementCache [ id ] [ index ] ;
else
return unpack ( self.achievementCache [ id ] ) ;
end
end
end
function DataProvider : UpdateAchievementCache ( id )
if self.achievementCache [ id ] then
local id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe , earnedBy = GetAchievementInfo ( id ) ;
if isGuild then
SetFocusedAchievement ( id ) ;
end
if description then
self.achievementCache [ id ] = { id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe } ;
end
end
end
function DataProvider : GetAchievementInfoByOrder ( categoryID , order )
if not self.achievementOrderCache [ categoryID ] then
self.achievementOrderCache [ categoryID ] = { } ;
end
if not self.achievementOrderCache [ categoryID ] [ order ] then
local id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe , earnedBy = GetAchievementInfo ( categoryID , order ) ;
if isGuild then
SetFocusedAchievement ( id ) ;
end
if description then
self.achievementOrderCache [ categoryID ] [ order ] = id ;
self.achievementCache [ id ] = { id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe } ;
end
return id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe , earnedBy
else
local id = self.achievementOrderCache [ categoryID ] [ order ] ;
return self : GetAchievementInfo ( id )
end
end
function DataProvider : GetCategoryButtonByID ( categoryID , isGuild )
return self.id2Button [ categoryID ] ;
end
function DataProvider : GetTrackedAchievements ( )
local new = { GetTrackedAchievements ( ) } or { } ;
local old = self.trackedAchievements ;
local numNew , numOld = # new , # old ;
local dif ;
if numNew >= numOld then
local lookup = { } ;
for i = 1 , # old do
lookup [ old [ i ] ] = true ;
end
for i = 1 , # new do
if not lookup [ new [ i ] ] then
dif = new [ i ] ;
break
end
end
else
local lookup = { } ;
for i = 1 , # new do
lookup [ new [ i ] ] = true ;
end
for i = 1 , # old do
if not lookup [ old [ i ] ] then
dif = old [ i ] ;
break
end
end
end
self.trackedAchievements = new ;
self.numTrackedAchievements = # new ;
wipe ( self.isTrackedAchievements ) ;
for index , id in pairs ( new ) do
self.isTrackedAchievements [ id ] = true ;
end
return dif
end
function DataProvider : IsTrackedAchievement ( id )
return self.isTrackedAchievements [ id ]
end
local ScrollCard = { } ; --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
ScrollCard : UpdateScrollChild ( 0 ) ;
end
end
if self.cycle == 3 then
ScrollCard : 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
ScrollCard : 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 ) ;
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
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 = inOutSine ( 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 ( ) ;
self.Card . ParentAchievmentButton : 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 ( bit.band ( 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 ToggleTracking ( id )
if not id then return end ;
if DataProvider : IsTrackedAchievement ( id ) then
RemoveTrackedAchievement ( 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
AddTrackedAchievement ( 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 ( buttonIndex , id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe )
local button = AchievementCards [ buttonIndex ] ;
if not button then
return
end
local headerObject , numLines , textHeight ;
button.id = id ;
button.trackIcon : SetShown ( DataProvider : IsTrackedAchievement ( id ) ) ;
if ( not ( wasEarnedByMe and completed ) ) and ( showNotEarnedMark ) and ( not isGuildView ) 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 flags == 131072 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 = 24 ;
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 flags == 131072 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 , 1 ) ;
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 buttonIndex > 7 or buttonIndex < 0 then
button : SetAlpha ( 1 ) ;
else
button.toAlpha = 1 ;
-- button:SetAlpha(0); --for flip animation
end
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.8 , 0.8 , 0.8 ) ;
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 buttonIndex > 7 or buttonIndex < 0 then
button : SetAlpha ( 1 ) ; --0.5
else
button.toAlpha = 1 --0.5;
--button:SetAlpha(0); --for flip animation
end
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 InspectAchievement ( id )
if not id then return end ;
local id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe = DataProvider : GetAchievementInfo ( id ) ;
FormatAchievementCard ( - 1 , id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe ) ;
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 , AchievementCards [ - 1 ] : GetHeight ( ) / 2
end
ScrollCard.heightData = { } ;
ScrollCard.achievementID = { } ;
ScrollCard.totalHeight = 0 ;
ScrollCard.positionToButton = { } ;
HEIGHTS = ScrollCard.heightData
function ScrollCard : ResetHeights ( )
self.totalHeight = 18 ;
self.position = 1 ;
self.lastOffset = 0 ;
self.nextOffset = 0 ;
wipe ( self.heightData ) ;
end
function ScrollCard : GetScrollRange ( )
local range = self.totalHeight - ( AchievementContainer : GetHeight ( ) or 0 ) + 18 ;
if range < 0 then
range = 0 ;
end
return range ;
end
function ScrollCard : SetCardData ( cardIndex , achievementID , description , rewardText )
local rewardHeight ;
if rewardText and rewardText ~= " " then
rewardHeight = 24 ;
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 ScrollCard : 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 ScrollCard : UpdateScrollChild ( direction )
if direction < 0 then
local topButton = tremove ( AchievementCards , 1 ) ;
tinsert ( AchievementCards , topButton ) ;
elseif direction > 0 then
local bottomButton = tremove ( AchievementCards ) ;
tinsert ( AchievementCards , 1 , bottomButton ) ;
end
wipe ( self.positionToButton ) ;
local p = self.position ;
local id ;
local positionIndex ;
local name , points , completed , month , day , year , description , flags , icon , rewardText ;
local card ;
for i = 1 , NUM_ACHIEVEMENT_CARDS do
card = AchievementCards [ i ] ;
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
id , name , points , completed , month , day , year , description , flags , icon , rewardText = DataProvider : GetAchievementInfo ( id ) ;
FormatAchievementCard ( i , id , name , points , completed , month , day , year , description , flags , icon , rewardText ) ;
else
card : Show ( ) ;
end
else
card : Hide ( ) ;
end
else
card : Hide ( ) ;
end
end
end
function ScrollCard : GetOffsetByPositionIndex ( index )
return self.heightData [ index ] or 0
end
function ScrollCard : GetAchievementIDByPositionIndex ( index )
return self.achievementID [ index ] ;
end
function ScrollCard : 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 ( ) ;
elseif index >= numAchievements then
index = numAchievements ;
InspectionFrame.PrevButton : Enable ( ) ;
InspectionFrame.NextButton : Disable ( ) ;
else
InspectionFrame.PrevButton : Enable ( ) ;
InspectionFrame.NextButton : Enable ( ) ;
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 ( ) ;
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
FormatAchievementCard ( i , id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe ) ;
end
ScrollCard : 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
FormatAchievementCard ( index , id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe ) ;
end
ScrollCard : 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
FormatAchievementCard ( i , id , name , points , completed , month , day , year , description , flags , icon , rewardText , isGuild , wasEarnedByMe ) ;
end
ScrollCard : 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 UpdateAchievementScrollRange ( )
local scrollBar = AchievementContainer.scrollBar ;
local range = ScrollCard : 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
objects = SummaryCards ;
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 )
ScrollCard : 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 UpdateCategoryScrollRange ( )
local button , buttons ;
local totalHeight = 0 ;
local parentButtons = CategoryButtons : GetActiveParentButtons ( ) ;
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 ;
button.progress : Hide ( ) ;
button.percentSign : Show ( ) ;
button.value : Show ( ) ;
end
local lastButton = DataProvider : GetCategoryButtonByID ( DataProvider.currentCategory ) ;
if lastButton then
lastButton.label : SetTextColor ( 0.8 , 0.8 , 0.8 ) ;
end
DataProvider.currentCategory = 0 ;
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 ;
--print(button.label:GetText().." ".. totalCompleted .. "/" ..totalAchievements);
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 SelectCategory ( categoryID )
local numAchievements = GetCategoryNumAchievements ( categoryID , false ) ;
InspectionFrame.numAchievements = numAchievements ;
UpdateAchievementCardsBySlice ( categoryID ) ;
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
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 CategoryButton_OnClick ( button , mouse )
AchievementContainer : Show ( ) ;
SummaryFrame : Hide ( ) ;
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.expanded then
button.progress : Show ( ) ;
button.percentSign : Hide ( ) ;
button.value : Hide ( ) ;
else
button.progress : Hide ( ) ;
button.percentSign : Show ( ) ;
button.value : Show ( ) ;
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 ( isGuild )
local GUILD_FEAT_OF_STRENGTH_ID = 15093 ;
local GUILD_CATEGORY_ID = 15076 ;
local categories , structure , feats , legacys ;
if isGuild then
categories = GetGuildCategoryList ( ) ;
structure = CategoryStructure.guild ;
feats = { FEAT_OF_STRENGTH_ID } ;
legacys = { } ;
else
categories = GetCategoryList ( ) ;
structure = CategoryStructure.player ;
feats = { GUILD_FEAT_OF_STRENGTH_ID } ;
legacys = { LEGACY_ID } ;
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 ( isGuild )
local frame ;
local button , parentButton , parentData , id ;
local structure ;
local numButtons = 0 ;
local parentButtons , buttons ;
if not CategoryButtons.buttons then
CategoryButtons.buttons = { } ;
end
local parentButtons = CategoryButtons : GetActiveParentButtons ( isGuild ) ;
if isGuild then
buttons = CategoryButtons.guild . buttons ;
structure = CategoryStructure.guild ;
frame = CategoryContainer.ScrollChild . GuildCategory ;
CategoryContainer.ScrollChild . PlayerCategory : Hide ( ) ;
else
buttons = CategoryButtons.player . buttons ;
structure = CategoryStructure.player ;
frame = CategoryContainer.ScrollChild . PlayerCategory ;
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 ;
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 ;
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 , " NarciAchievementCardLargeTemplate " ) ;
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 ( " 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 ( " INCOMPLETED " ) ;
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 = ScrollCard : GetOffsetByPositionIndex ( positionIndex ) - 18 ;
AchievementContainer.scrollBar : SetValue ( offset ) ;
end
function NarciAchievementInspectionFrameMixin : OnMouseWheel ( delta )
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 = ScrollCard : GetCardByPositionIndex ( index ) ;
--InspectAchievement( ScrollCard:GetAchievementIDByPositionIndex(index) );
InspectCard ( newButton ) ;
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 \\ Art \\ Modules \\ Achievement \\ 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 \\ Art \\ Modules \\ Achievement \\ Shared \\ IconBorderPointyMini " ) ;
button : SetAlpha ( 1 ) ;
else
button.border : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ Art \\ Modules \\ Achievement \\ 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 ( ) ;
SummaryFrame : Hide ( ) ;
SummaryButton : Show ( ) ;
else
animFlyOut : Play ( ) ;
end
end
end
function NarciAchievementGoToCategoryButtonMixin : SetAchievement ( achievementID , isGuild )
local categoryID = 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 flags and flags == 131072 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 ( )
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 ) ;
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 flags and flags == 131072 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 ) ) ;
else
self.name : SetTextColor ( 0.8 , 0.8 , 0.8 ) ;
self.date : SetText ( " " ) ;
end
if points == 0 then
self.shield : Hide ( ) ;
self.points : Hide ( ) ;
else
self.shield : Show ( ) ;
self.points : SetText ( points ) ;
end
self : ResizeAndShow ( ) ;
end
----------------------------------------------------------------------------------
NarciAchievementNavigationButtonMixin = { } ;
function NarciAchievementNavigationButtonMixin : OnEnter ( )
self : StopAnimating ( ) ;
self.highlight . flyIn : Play ( ) ;
self.flyIn . hold : SetDuration ( 60 ) ;
end
function NarciAchievementNavigationButtonMixin : OnLeave ( )
self.flyIn . hold : SetDuration ( 0 ) ;
self.highlight . fadeOut : Play ( ) ;
end
function NarciAchievementNavigationButtonMixin : OnMouseDown ( )
self.background : SetScale ( 0.9 ) ;
if not self : IsEnabled ( ) then
self : GetParent ( ) : OnMouseDown ( ) ;
end
end
function NarciAchievementNavigationButtonMixin : OnMouseUp ( )
self.background : SetScale ( 1 ) ;
end
function NarciAchievementNavigationButtonMixin : OnClick ( )
InspectionFrame : OnMouseWheel ( self.delta ) ;
end
function NarciAchievementNavigationButtonMixin : OnDisable ( )
self : SetAlpha ( 0 ) ;
end
function NarciAchievementNavigationButtonMixin : OnEnable ( )
self : SetAlpha ( 1 ) ;
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 ( ) ;
end
end
function NarciAchievementSearchBoxMixin : OnLoad ( )
SearchBoxTemplate_OnLoad ( self ) ;
self.Left : Hide ( ) ;
self.Middle : Hide ( ) ;
self.Right : Hide ( ) ;
local delayedSearch = NarciAPI_CreateAnimationFrame ( 0.5 ) ;
self.delayedSearch = delayedSearch ;
delayedSearch : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed ;
if frame.total >= frame.duration then
frame : Hide ( ) ;
SetAchievementSearchString ( self.keyword ) ;
end
end )
---
local ClipFrame = self.ClipFrame ;
---
ResultFrame = ClipFrame.ResultFrame ;
self.ResultFrame = ResultFrame ;
local buttons = { } ;
local button ;
for i = 1 , 5 do
button = CreateFrame ( " Button " , nil , ResultFrame , " NarciAchievementSearchResultButtonTemplate " ) ;
button : SetScript ( " OnClick " , function ( button )
InspectResult ( button ) ;
ResultFrame : Hide ( ) ;
end ) ;
tinsert ( buttons , button ) ;
if i == 1 then
button : SetPoint ( " TOP " , ResultFrame , " TOP " , 0 , - 24 ) ;
else
button : SetPoint ( " TOP " , buttons [ i - 1 ] , " BOTTOM " , 0 , - 2 ) ;
end
button : Hide ( ) ;
end
ResultFrame.buttons = buttons ;
ResultButtons = buttons ;
self.ResultFrame : SetScript ( " OnMouseWheel " , function ( frame , delta )
if self.numResults and self.numResults > 5 then
if delta > 0 then
if self.currentPage > 1 then
self.currentPage = self.currentPage - 1 ;
self : UpdatePage ( ) ;
end
else
if self.currentPage < self.maxPage then
self.currentPage = self.currentPage + 1 ;
self : UpdatePage ( ) ;
end
end
end
end )
--Animation
local animDrop = NarciAPI_CreateAnimationFrame ( 0.35 ) ;
animDrop : 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
ResultFrame : Hide ( ) ;
end
end
ResultFrame : SetAlpha ( alpha ) ;
end )
function self : ShowResults ( )
animDrop : Hide ( ) ;
animDrop.fromAlpha = ResultFrame : GetAlpha ( ) ;
animDrop.toAlpha = 1 ;
ResultFrame : Show ( ) ;
animDrop : Show ( ) ;
end
function self : HideResults ( )
animDrop : Hide ( ) ;
animDrop.fromAlpha = ResultFrame : GetAlpha ( ) ;
animDrop.toAlpha = 0 ;
animDrop : Show ( ) ;
end
ResultFrame : SetAlpha ( 0 ) ;
--ResultFrame:SetHeight(24);
end
function NarciAchievementSearchBoxMixin : OnUpdate ( )
self.pauseUpdate = true ;
end
function NarciAchievementSearchBoxMixin : OnTextChanged ( )
SearchBoxTemplate_OnTextChanged ( self ) ;
self.keyword = self : GetText ( ) ;
if ( strlen ( self.keyword ) >= MIN_CHARACTER_SEARCH ) then
self.delayedSearch . total = 0 ;
self.delayedSearch : Show ( ) ;
else
self.delayedSearch : Hide ( ) ;
end
end
function NarciAchievementSearchBoxMixin : OnEditFocusGained ( )
self : RegisterEvent ( " ACHIEVEMENT_SEARCH_UPDATED " ) ;
local numResults = GetNumFilteredAchievements ( ) ;
--this filter might be removed by using the original AchievementFrame so we need to set again
if numResults and numResults > 0 then
self : ShowResults ( ) ;
else
if self : GetText ( ) ~= " " then
self : OnTextChanged ( ) ;
end
end
end
function NarciAchievementSearchBoxMixin : OnEditFocusLost ( )
SearchBoxTemplate_OnEditFocusLost ( self ) ;
if not self.ResultFrame : IsMouseOver ( ) then
--self.ResultFrame:Hide();
self : HideResults ( ) ;
end
self : UnregisterEvent ( " ACHIEVEMENT_SEARCH_UPDATED " ) ;
end
function NarciAchievementSearchBoxMixin : OnEnterPressed ( )
self : ClearFocus ( ) ;
if self : GetText ( ) ~= " " then
local button1 = self.ResultFrame . buttons [ 1 ] ;
if button1 : IsShown ( ) then
button1 : Click ( ) ;
end
end
end
function NarciAchievementSearchBoxMixin : OnHide ( )
self : UnregisterEvent ( " ACHIEVEMENT_SEARCH_UPDATED " ) ;
self.ResultFrame : Hide ( ) ;
end
function NarciAchievementSearchBoxMixin : ProcessResults ( )
local numResults = GetNumFilteredAchievements ( ) ;
self.numResults = numResults ;
self.ResultFrame . count : SetText ( numResults .. " |cff808080Results|r " ) ;
local numPages = ceil ( numResults / 5 ) ;
self.maxPage = numPages ;
if ( numResults > 0 ) then
self.currentPage = 1 ;
--self.ResultFrame:Show();
self : ShowResults ( ) ;
end
self : UpdatePage ( ) ;
end
function NarciAchievementSearchBoxMixin : OnEvent ( event )
self : ProcessResults ( ) ;
end
function NarciAchievementSearchBoxMixin : UpdatePage ( )
local page = self.currentPage or 1 ;
local numPages = ceil ( self.numResults / 5 ) ;
local buttons = self.ResultFrame . buttons ;
if numPages > 0 then
self.ResultFrame . pageText : SetText ( page .. " / " .. numPages ) ;
local firstID = 5 * ( page - 1 ) ;
local button ;
local index ;
local id , name , points , completed , _ , _ , _ , _ , flags , icon ;
for i = 1 , 5 do
index = i + firstID ;
button = buttons [ i ] ;
if index <= self.numResults then
local achievementID = GetFilteredAchievementID ( index ) ;
id , name , points , completed , _ , _ , _ , _ , flags , icon = DataProvider : GetAchievementInfo ( achievementID ) ;
button.id = achievementID ;
button.header : SetText ( name ) ;
button.icon : SetTexture ( icon ) ;
if flags == 131072 then --ACHIEVEMENT_FLAGS_ACCOUNT
button.header : SetTextColor ( 0.427 , 0.812 , 0.965 ) ;
button.background : SetTexCoord ( 0 , 1 , 0.5 , 1 ) ;
else
button.header : SetTextColor ( 1 , 0.91 , 0.647 ) ;
button.background : SetTexCoord ( 0 , 1 , 0 , 0.5 ) ;
end
local categoryID = GetAchievementCategory ( achievementID ) ;
local categoryName , parentCategoryID = DataProvider : GetCategoryInfo ( categoryID ) ;
local path = categoryName ;
while ( not ( parentCategoryID == - 1 ) ) do
categoryName , parentCategoryID = DataProvider : GetCategoryInfo ( parentCategoryID ) ;
path = categoryName .. " > " .. path ;
end
button.path : SetText ( path ) ;
if completed then
button.icon : SetDesaturated ( false ) ;
button.header : SetAlpha ( 1 ) ;
button.icon : SetVertexColor ( 1 , 1 , 1 ) ;
button.background : SetVertexColor ( 1 , 1 , 1 ) ;
else
button.icon : SetDesaturated ( true ) ;
button.header : SetAlpha ( 0.5 ) ;
button.icon : SetVertexColor ( 0.5 , 0.5 , 0.5 ) ;
button.background : SetVertexColor ( 0.5 , 0.5 , 0.5 ) ;
end
button : Show ( ) ;
else
button : Hide ( ) ;
end
end
else
self.ResultFrame . pageText : SetText ( nil ) ;
for i = 1 , 5 do
buttons [ i ] : Hide ( ) ;
end
end
end
--------------------------------------------------------------
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 day = floor ( diff / 86400 ) ;
if day <= 0 then
return " Today "
elseif day == 1 then
return " Yesterday "
elseif day < 31 then
return day .. " days ago "
else
local month = floor ( day / 30.5 ) ;
if month <= 1 then
return month .. " month ago "
else
return month .. " months ago "
end
end
end
local function FormatRecentAchievementButton ( button , id , name , points , completed , month , day , year , description , flags , icon , rewardText , useRelativeDate )
local headerObject , numLines , textHeight ;
button.id = id ;
--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 flags == 131072 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 = 24 ;
shadowHeight = 6 ;
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 ) ;
local descriptionHeight = button.description : GetHeight ( ) ;
button.description : SetHeight ( descriptionHeight )
textHeight = floor ( button.background : GetHeight ( ) + 0.5 ) ;
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 flags == 131072 then --ACHIEVEMENT_FLAGS_ACCOUNT
button.accountWide = true ;
button.border : SetTexCoord ( 0.05078125 , 0.94921875 , 0.5 , 1 ) ;
button.bottom : SetTexCoord ( 0.05078125 , 0.94921875 , 0.985 , 1 ) ;
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
button.accountWide = nil ;
button.border : SetTexCoord ( 0.05078125 , 0.94921875 , 0 , 0.5 ) ;
button.bottom : SetTexCoord ( 0.05078125 , 0.94921875 , 0.485 , 0.5 ) ;
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
--button.date:SetText( FormatDate(day, month, year) );
if useRelativeDate then
button.date : SetText ( DateUtil : GetPastDays ( day , month , year ) ) ;
else
button.date : SetText ( FormatDate ( day , month , year ) ) ;
end
button.RewardFrame . reward : SetAlpha ( 1 ) ;
button.toAlpha = 1 ;
button : SetAlpha ( 0 ) ; --for flip animation
button : Show ( ) ;
end
local UpdateHeaderFrame ;
local function CreateSummaryButtons ( )
local MAX_SUMMARY_ACHIEVEMENTS = 5 ;
if not SummaryCards then
SummaryCards = { } ;
end
local button ;
for i = 1 , MAX_SUMMARY_ACHIEVEMENTS do
button = SummaryCards [ i ] ;
if not button then
button = CreateFrame ( " Button " , nil , SummaryFrame , " NarciAchievementCardLargeTemplate " ) ;
button : SetScript ( " OnClick " , InspectResult ) ;
button.header : SetWidth ( 274 ) ;
button.description : SetMaxLines ( 1 ) ;
tinsert ( SummaryCards , button ) ;
if i == 1 then
button : SetPoint ( " TOP " , SummaryFrame , " TOP " , - 9 , - 18 ) ;
else
button : SetPoint ( " TOP " , SummaryCards [ i - 1 ] , " BOTTOM " , 0 , - 4 ) ;
end
button : Hide ( ) ;
ReskinButton ( button ) ;
end
end
end
local function UpdateSummaryFrame ( breakLoop , noRenderWhileHidden )
if noRenderWhileHidden and not SummaryFrame : IsShown ( ) then return end ;
local button ;
local recentAchievements = { GetLatestCompletedAchievements ( isGuildView ) } ;
if ( # recentAchievements <= 5 ) and ( not breakLoop ) then
SummaryFrame : SetAlpha ( 0 ) ;
After ( 0.05 , function ( )
UpdateSummaryFrame ( true ) ;
end ) ;
return
end
local id , name , points , completed , month , day , year , description , flags , icon , rewardText ;
local useRelativeDate = true ;
for i = 1 , 5 do
button = SummaryCards [ i ] ;
id = recentAchievements [ i ] ;
if id then
id , name , points , completed , month , day , year , description , flags , icon , rewardText = DataProvider : GetAchievementInfo ( id ) ;
FormatRecentAchievementButton ( button , id , name , points , completed , month , day , year , description , flags , icon , rewardText , useRelativeDate ) ;
ReskinButton ( button ) ;
else
button : Hide ( ) ;
end
end
SummaryFrame : SetAlpha ( 1 ) ;
UpdateHeaderFrame ( isGuildView ) ;
animFlip : Play ( 2 ) ;
end
----------------------------------------------------------------------------------
local TabUtil = { } ;
function TabUtil : SaveView ( isGuild , saveOffset )
--print("currentCategory: ".. DataProvider.currentCategory)
local lastButton ;
if isGuild then
if saveOffset then
self.lastPlayerButton = DataProvider : GetCategoryButtonByID ( DataProvider.currentCategory ) ;
self.lastPlayerScrollValue = CategoryContainer.scrollBar : GetValue ( ) ;
end
lastButton = self.lastGuildButton ;
if lastButton then
AchievementContainer : Show ( ) ;
SummaryFrame : Hide ( ) ;
SummaryButton : Show ( ) ;
SubCategoryButton_OnClick ( lastButton ) ;
ToggleFeatOfStrenghtText ( lastButton ) ;
else
SummaryButton : Click ( ) ;
end
else
if saveOffset then
self.lastGuildButton = DataProvider : GetCategoryButtonByID ( DataProvider.currentCategory ) ;
self.lastGuildScrollValue = CategoryContainer.scrollBar : GetValue ( ) ;
end
lastButton = self.lastPlayerButton ;
if lastButton then
AchievementContainer : Show ( ) ;
SummaryFrame : Hide ( ) ;
SummaryButton : Show ( ) ;
SubCategoryButton_OnClick ( lastButton ) ;
ToggleFeatOfStrenghtText ( lastButton ) ;
else
SummaryButton : Click ( ) ;
end
end
AchievementContainer.scrollBar : SetValue ( 0 ) ;
end
function TabUtil : ToggleGuildView ( isGuild )
if ( isGuild ~= isGuildView ) or self.isDIY then
isGuildView = isGuild ;
CategoryContainer.ScrollChild . PlayerCategory : SetShown ( not isGuild ) ;
CategoryContainer.ScrollChild . GuildCategory : SetShown ( isGuild ) ;
DIYContainer : Hide ( ) ;
EditorContainer : Hide ( ) ;
CategoryContainer : Show ( ) ;
SummaryButton : Enable ( ) ;
self : SaveView ( isGuild , not self.isDIY ) ;
UpdateCategoryScrollRange ( ) ;
if isGuild then
CategoryContainer.scrollBar : SetValue ( self.lastGuildScrollValue or 0 ) ;
else
CategoryContainer.scrollBar : SetValue ( self.lastPlayerScrollValue or 0 ) ;
end
local noRenderWhileHidden = true ;
--UpdateSummaryFrame(false, noRenderWhileHidden);
MainFrame.HeaderFrame . points : SetText ( BreakUpLargeNumbers ( GetTotalAchievementPoints ( isGuild ) ) ) ;
self.isDIY = false ;
end
end
function TabUtil : ToggleDIY ( )
if self.isDIY then return end ;
self.isDIY = true ;
DIYContainer : Show ( ) ;
if not TabUtil.isDIYLoaded then
TabUtil.isDIYLoaded = true ;
DIYContainer : Refresh ( ) ;
DIYContainer.scrollBar : SetValue ( 0 ) ;
end
EditorContainer : Show ( ) ;
CategoryContainer : Hide ( ) ;
SummaryFrame : Hide ( ) ;
SummaryButton : Disable ( ) ;
AchievementContainer : Hide ( ) ;
end
--------------------------------------------------------------
local function FilterButton_OnClick ( self )
local state = not NarciAchievementOptions.IncompleteFirst ;
NarciAchievementOptions.IncompleteFirst = state ;
if state then
self.label : SetText ( L [ " Incomplete First " ] ) ;
SwitchToSortMethod ( 1 ) ;
else
self.label : SetText ( L [ " Earned First " ] ) ;
SwitchToSortMethod ( 2 ) ;
end
end
local function SummaryButton_OnClick ( self )
if DataProvider.currentCategory ~= 0 then
animExpand : CollapseAll ( ) ;
end
UpdateSummaryFrame ( ) ;
AchievementContainer : Hide ( ) ;
SummaryFrame : Show ( ) ;
SummaryButton : Hide ( ) ;
end
local function CreateTabButtons ( )
local tabNames = { ACHIEVEMENTS , ACHIEVEMENTS_GUILD_TAB , " 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 : ToggleGuildView ( false ) ;
DeselectRest ( self ) ;
self : Select ( ) ;
end ,
function ( self )
TabUtil : ToggleGuildView ( true ) ;
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
button : SetPoint ( " TOPRIGHT " , frame , " BOTTOMRIGHT " , - 23 , 0 ) ;
else
button : SetPoint ( " TOPLEFT " , buttons [ i - 1 ] , " TOPRIGHT " , 14 , 0 ) ;
end
button : SetScript ( " OnClick " , funcs [ i ] ) ;
end
TabButtons = buttons ;
end
----------------------------------------------------------------------------------
local function GetInspectedCardLink ( )
local achievementID = InspectionFrame.Card . id ;
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 ( ) 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 )
MainFrame = frame ;
--Category
CategoryContainer = frame.CategoryFrame ;
local isGuild = true ;
CreateCategoryButtons ( isGuild ) ;
isGuild = not isGuild ;
CreateCategoryButtons ( isGuild ) ;
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
local FilterButton = frame.FilterButton ;
if NarciAchievementOptions.IncompleteFirst then
SORT_FUNC = Slice_ReverselyUpdateAchievementCards ;
FilterButton.label : SetText ( L [ " Incomplete First " ] ) ;
else
SORT_FUNC = Slice_UpdateAchievementCards ;
FilterButton.label : SetText ( L [ " Earned First " ] ) ;
end
FilterButton : SetScript ( " OnClick " , FilterButton_OnClick ) ;
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 ) ;
ScrollCard : 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 ;
SummaryButton : SetScript ( " OnClick " , SummaryButton_OnClick ) ;
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
end
--SummaryFrame
SummaryFrame = frame.SummaryFrame ;
CreateSummaryButtons ( ) ;
UpdateSummaryFrame ( ) ;
--DIY Achievements
DIYContainer = frame.DIYContainer ;
EditorContainer = frame.EditorContainer ;
--Tabs
CreateTabButtons ( ) ;
NarciAchievement_SelectTheme ( NarciAchievementOptions.Theme or 1 ) ;
--
tinsert ( UISpecialFrames , frame : GetName ( ) ) ;
frame : Hide ( ) ;
frame : SetAlpha ( 1 ) ;
--Reclaim Temp
wipe ( CategoryStructure ) ;
CategoryStructure = nil ;
CreateCategoryButtons = nil ;
CreateAchievementButtons = nil ;
CreateSummaryButtons = nil ;
CreateTabButtons = nil ;
InitializeFrame = nil ;
end
-----------------------------------------
local FloatingCards = CreateFrame ( " Frame " , " NarciFloatingCardsContainer " ) ;
local positionFrame = CreateFrame ( " Frame " ) ;
FloatingCards.positionFrame = positionFrame ;
positionFrame.screenMidPoint = WorldFrame : GetWidth ( ) / 2 ;
positionFrame : Hide ( ) ;
positionFrame : SetScript ( " OnUpdate " , function ( self )
local cursorX , cursorY = GetCursorPosition ( ) ;
local uiScale = self.uiScale ;
cursorX , cursorY = cursorX / uiScale , cursorY / uiScale ;
local compensatedX = cursorX - self.offsetX ;
local midPoint = self.screenMidPoint / uiScale ;
if ( compensatedX > midPoint - 40 ) and ( compensatedX < midPoint + 40 ) then
compensatedX = midPoint ;
end
if self.object then
self.object : SetPoint ( " CENTER " , UIParent , " BOTTOMLEFT " , compensatedX , cursorY - self.offsetY ) ;
else
self : Hide ( ) ;
end
end ) ;
FloatingCards.cards = { } ;
local function MoveFloatingCard ( card )
positionFrame : Hide ( ) ;
local uiScale = card : GetScale ( ) ;
positionFrame.object = card ;
positionFrame.uiScale = uiScale ;
local cursorX , cursorY = GetCursorPosition ( ) ;
cursorX , cursorY = cursorX / uiScale , cursorY / uiScale ;
local x0 , y0 = card : GetCenter ( ) ;
positionFrame.offsetX = cursorX - x0 ;
positionFrame.offsetY = cursorY - y0 ;
positionFrame : Show ( ) ;
end
local function FloatingCard_OnDragStop ( self )
positionFrame : Hide ( ) ;
end
function FloatingCards : Acquire ( )
self : RegisterEvent ( " GLOBAL_MOUSE_UP " ) ;
local card ;
for i = 1 , # self.cards + 1 do
card = self.cards [ i ] ;
if card and ( not card : IsShown ( ) ) then
break
end
if not card then
card = CreateFrame ( " Button " , nil , self , " NarciAchievementFloatingCardTemplate " ) ;
card.index = i ;
card : SetFrameStrata ( " DIALOG " ) ;
card : SetFrameLevel ( i ) ;
card : SetScript ( " OnDragStart " , MoveFloatingCard ) ;
card : SetScript ( " OnDragStop " , FloatingCard_OnDragStop ) ;
tinsert ( self.cards , card ) ;
ReskinButton ( card ) ;
break
end
end
self.pendingCard = card ;
return card
end
function FloatingCards : PostCreate ( )
if self.parentCard then
UIFrameFadeIn ( self.parentCard , 0.5 , 0 , 1 ) ;
end
local pendingCard = self.pendingCard ;
if MainFrame : IsMouseOver ( ) then
if pendingCard then
pendingCard : Hide ( ) ;
pendingCard = nil ;
end
else
if pendingCard then
FloatingCard_OnDragStop ( pendingCard ) ;
end
end
end
function FloatingCards : OnEvent ( event , ... )
if event == " GLOBAL_MOUSE_UP " then
self : UnregisterEvent ( " GLOBAL_MOUSE_UP " ) ;
self : PostCreate ( ) ;
end
end
FloatingCards : SetScript ( " OnEvent " , function ( frame , event , ... )
frame : OnEvent ( event , ... ) ;
end ) ;
local function FormatFloatingCard ( card , id , name , points , completed , month , day , year , description , flags , icon , rewardText )
FormatRecentAchievementButton ( card , id , name , points , true , month , day , year , description , flags , icon , rewardText ) ;
local texOffset ;
local ModelScene = card.VFX ;
ModelScene : ClearAllPoints ( ) ;
if flags and flags == 131072 then
texOffset = 0.5 ;
ModelScene : SetPoint ( " CENTER " , card , " TOP " , 0 , - 158 ) ;
NarciAPI_SetupModelScene ( ModelScene , 1893721 , 20 ) ;
else
texOffset = 0 ;
ModelScene : SetPoint ( " CENTER " , card , " CENTER " , 0 , 0 ) ;
NarciAPI_SetupModelScene ( ModelScene , 2012607 , 8 ) ;
end
card.highlightTop : SetTexCoord ( 0.05078125 , 0.94921875 , 0 + texOffset , 0.5 + texOffset ) ;
card.highlightCenter : SetTexCoord ( 0.05078125 , 0.94921875 , 0 + texOffset , 0.40625 + texOffset ) ;
card.highlightBottom : SetTexCoord ( 0.05078125 , 0.94921875 , 0.40625 + texOffset , 0.5 + texOffset ) ;
end
--------------------------------------------------------------------
--Public
NarciAchivementFrameMixin = { } ;
function NarciAchivementFrameMixin : OnLoad ( )
ScrollCard.textReference = self.TextHeightRetriever ;
self : RegisterForDrag ( " LeftButton " ) ;
self : SetAttribute ( " nodeignore " , true ) ; --ConsolePort: Ignore this frame
end
function NarciAchivementFrameMixin : OnShow ( )
if self.pendingCategoryID then
SelectCategory ( self.pendingCategoryID ) ;
self.pendingCategoryID = nil ;
elseif self.pendingUpdate then
self.pendingUpdate = nil ;
UpdateSummaryFrame ( ) ;
end
end
function NarciAchivementFrameMixin : 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
UpdateAchievementCardsBySlice ( categoryID ) ;
end
end
end
function NarciAchivementFrameMixin : 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 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
function NarciAchievement_CreateFloatingCard ( self )
local id = self.id ;
if not id then return end ;
self.animPushed : Stop ( ) ;
self : Hide ( ) ;
FloatingCards.parentCard = self ;
local card = FloatingCards : Acquire ( ) ;
local uiScale = MainFrame : GetEffectiveScale ( ) ;
card : SetScale ( uiScale ) ;
card.uiScale = uiScale ;
local id , name , points , completed , month , day , year , description , flags , icon , rewardText = DataProvider : GetAchievementInfo ( id ) ;
FormatRecentAchievementButton ( card , id , name , points , true , month , day , year , description , flags , icon , rewardText ) ;
card : ClearAllPoints ( ) ;
card : SetAlpha ( 1 ) ;
positionFrame.object = card ;
positionFrame.uiScale = uiScale ;
local cursorX , cursorY = GetCursorPosition ( ) ;
cursorX , cursorY = cursorX / uiScale , cursorY / uiScale ;
local x0 , y0 = self : GetCenter ( ) ;
positionFrame.offsetX = cursorX - x0 ;
positionFrame.offsetY = cursorY - y0 ;
positionFrame : Show ( ) ;
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 \\ Art \\ Modules \\ Achievement \\ Flat \\ " ;
elseif index == 2 then
isDarkTheme = false ;
texturePrefix = " Interface \\ AddOns \\ Narcissus \\ Art \\ Modules \\ Achievement \\ Classic \\ " ;
else
isDarkTheme = true ;
texturePrefix = " Interface \\ AddOns \\ Narcissus \\ Art \\ Modules \\ Achievement \\ DarkWood \\ " ;
end
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 ) ;
FormatAchievementCard ( - 1 , id , name , points , completed , month , day , year , description , flags , icon , rewardText ) ;
end
if SummaryFrame : IsVisible ( ) then
UpdateSummaryFrame ( ) ;
else
local categoryID = DataProvider.currentCategory ;
if categoryID and categoryID ~= 0 then
UpdateAchievementCardsBySlice ( categoryID ) ;
end
end
--Search Results:
for i = 1 , # ResultButtons do
ResultButtons [ i ] . background : SetTexture ( texturePrefix .. " ResultButton " ) ;
ResultButtons [ i ] . mask : SetTexture ( texturePrefix .. " ResultButtonMask " ) ;
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 playerButtons = CategoryButtons.player . buttons ;
for i = 1 , # playerButtons do
if playerButtons [ i ] . isParentButton then
playerButtons [ i ] . background : SetTexture ( texturePrefix .. " CategoryButton " ) ;
else
playerButtons [ i ] . background : SetTexture ( texturePrefix .. " SubCategoryButton " ) ;
end
playerButtons [ i ] . fill : SetTexture ( texturePrefix .. " CategoryButtonBar " ) ;
playerButtons [ i ] . fillEnd : SetTexture ( texturePrefix .. " CategoryButtonBar " ) ;
end
local guildButtons = CategoryButtons.guild . buttons ;
for i = 1 , # guildButtons do
if guildButtons [ i ] . isParentButton then
guildButtons [ i ] . background : SetTexture ( texturePrefix .. " CategoryButton " ) ;
else
guildButtons [ i ] . background : SetTexture ( texturePrefix .. " SubCategoryButton " ) ;
end
guildButtons [ i ] . fill : SetTexture ( texturePrefix .. " CategoryButtonBar " ) ;
guildButtons [ i ] . fillEnd : SetTexture ( texturePrefix .. " CategoryButtonBar " ) ;
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 ) ;
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
local CloseButton = MainFrame.CloseButton ;
CloseButton.texture : SetTexture ( texturePrefix .. " CloseButton " ) ;
if index == 2 then
CloseButton : SetSize ( 39 , 26 ) ;
else
CloseButton : SetSize ( 36 , 26 ) ;
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
local resultButtonGap ;
if index == 3 then
resultButtonGap = - 1 ;
else
resultButtonGap = - 2
end
for i = 2 , # ResultButtons do
ResultButtons [ i ] : SetPoint ( " TOP " , ResultButtons [ i - 1 ] , " BOTTOM " , 0 , resultButtonGap ) ;
end
--AlertSystem
--Floating Cards
for i = 1 , # FloatingCards.cards do
ReskinButton ( FloatingCards.cards [ i ] ) ;
end
end
--------------------------------------------------------------------
local function UpdateTrackAchievements ( )
local changedAchievementID = DataProvider : GetTrackedAchievements ( ) ;
if not changedAchievementID then return end
local currentCategory = DataProvider.currentCategory ;
local categoryID = 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
local function RefreshInspection ( achievementID )
--Refresh inspection card
if ( InspectionFrame : IsShown ( ) ) and ( achievementID == InspectionFrame.Card . id ) then
InspectAchievement ( achievementID ) ;
end
end
-------------------------------------------------------------------------------------
--Redirect Blizzard Achievement to Narcissus Achievement Frame
local Original_OnBlockHeaderClick = ACHIEVEMENT_TRACKER_MODULE.OnBlockHeaderClick ;
local Original_OpenAchievementFrameToAchievement = OpenAchievementFrameToAchievement ;
local function OnBlockHeaderClick ( _ , block , mouseButton )
if ( IsModifiedClick ( " CHATLINK " ) and ChatEdit_GetActiveWindow ( ) ) then
local achievementLink = GetAchievementLink ( block.id ) ;
if ( achievementLink ) then
ChatEdit_InsertLink ( achievementLink ) ;
end
elseif ( mouseButton ~= " RightButton " ) then
if ( IsModifiedClick ( " QUESTWATCHTOGGLE " ) ) then
ToggleTracking ( block.id ) ;
else
local clickAgainToClose = true ;
MainFrame : LocateAchievement ( block.id , clickAgainToClose ) ;
end
else
ObjectiveTracker_ToggleDropDown ( block , AchievementObjectiveTracker_OnOpenDropDown ) ;
end
end
local RedirectFrame = { } ;
RedirectFrame.hasOverwritten = false ;
function RedirectFrame : RestoreFunctions ( )
if self.hasOverwritten then
self.hasOverwritten = false ;
OpenAchievementFrameToAchievement = Original_OpenAchievementFrameToAchievement ;
ACHIEVEMENT_TRACKER_MODULE.OnBlockHeaderClick = Original_OnBlockHeaderClick ;
end
end
function RedirectFrame : OverrideFunctions ( )
if not self.hasOverwritten then
self.hasOverwritten = true ;
function OpenAchievementFrameToAchievement ( achievementID )
MainFrame : LocateAchievement ( achievementID ) ;
end
ACHIEVEMENT_TRACKER_MODULE.OnBlockHeaderClick = OnBlockHeaderClick ;
end
end
local function OnAchivementEarned ( achievementID )
DataProvider : UpdateAchievementCache ( achievementID ) ;
RefreshInspection ( achievementID ) ;
local categoryID = 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 strsub = strsub ;
local strsplit = strsplit ;
local IS_TOOLTIP_HOOKED = false ;
local ENABLE_TOOLTIP = false ;
local tooltipButtons = { } ;
local function InsertTooltipButton ( tooltipFrame , buttonIndex , achievementID , completed , topLine )
--Called after adding new line
local line ;
if topLine then
line = 1 ;
else
line = tooltipFrame : NumLines ( ) ;
end
if not tooltipButtons [ buttonIndex ] then
tooltipButtons [ buttonIndex ] = CreateFrame ( " Button " , nil , nil , " NarciAchievementTooltipButtonTemplate " ) ;
end
local button = tooltipButtons [ buttonIndex ] ;
button : ClearAllPoints ( ) ;
button : SetParent ( tooltipFrame ) ;
button.achievementID = achievementID ;
button : SetPoint ( " TOPLEFT " , tooltipFrame : GetName ( ) .. " TextLeft " .. line , " TOPLEFT " , 0 , 2 ) ;
if topLine then
button : SetPoint ( " BOTTOMLEFT " , tooltipFrame : GetName ( ) .. " TextLeft " .. line , " BOTTOMLEFT " , 0 , - 2 ) ;
button : SetWidth ( tooltipFrame : GetWidth ( ) ) ;
button.closeFrame = true ;
else
button : SetPoint ( " BOTTOMRIGHT " , tooltipFrame : GetName ( ) .. " TextLeft " .. line , " BOTTOMRIGHT " , 0 , - 2 ) ;
button.closeFrame = false ;
end
if completed then
button.Highlight : SetVertexColor ( 0.251 , 0.753 , 0.251 ) ;
else
button.Highlight : SetVertexColor ( 1 , 0.82 , 0 ) ;
end
button : Show ( ) ;
if not tooltipFrame.insertedFrames then
tooltipFrame.insertedFrames = { } ;
end
tinsert ( tooltipFrame.insertedFrames , button ) ;
end
local function HookAchievementTooltip ( )
if IS_TOOLTIP_HOOKED then return end ;
IS_TOOLTIP_HOOKED = true ;
hooksecurefunc ( ItemRefTooltip , " SetHyperlink " , function ( self , link )
if not ENABLE_TOOLTIP then return end ;
if strsub ( link , 1 , 11 ) == " achievement " then
local _ , achievementID = strsplit ( " : " , link ) ;
achievementID = tonumber ( achievementID ) ;
local id , name , _ , completed = DataProvider : GetAchievementInfo ( achievementID ) ;
InsertTooltipButton ( self , 1 , achievementID , completed , true )
local parentAchievementID1 , parentAchievementID2 = GetParentAchievementID ( achievementID , true ) ;
if parentAchievementID1 then
self : AddLine ( " " ) ;
local id , name , _ , completed = DataProvider : GetAchievementInfo ( parentAchievementID1 ) ;
local colorString ;
if completed then
colorString = " |cff40c040 " ;
else
colorString = " |cFFFFD100 " ;
end
--self:AddDoubleLine("|cFF808080> |r"..colorString..name.."|r", id, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, true);
self : AddLine ( " |cFF808080> |r " .. colorString .. name .. " |r " , 0.5 , 0.5 , 0.5 , true ) ;
InsertTooltipButton ( self , 2 , parentAchievementID1 , completed ) ;
if parentAchievementID2 then
id , name , _ , completed = DataProvider : GetAchievementInfo ( parentAchievementID2 ) ;
if completed then
colorString = " |cff40c040 " ;
else
colorString = " |cFFFFD100 " ;
end
--self:AddDoubleLine("|cFF808080>> |r"..colorString..name.."|r", id, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, true);
self : AddLine ( " |cFF808080>> |r " .. colorString .. name .. " |r " , 0.5 , 0.5 , 0.5 , true ) ;
InsertTooltipButton ( self , 3 , parentAchievementID2 , completed ) ;
end
self : Show ( ) ;
end
end
end ) ;
end
NarciAchievementExtraTooltipMixin = { } ;
function NarciAchievementExtraTooltipMixin : OnLoad ( )
self : RegisterForDrag ( " LeftButton " ) ;
end
function NarciAchievementExtraTooltipMixin : OnDragStart ( )
local parent = self : GetParent ( ) ;
if parent and parent.OnDragStart then
parent : OnDragStart ( ) ;
end
end
function NarciAchievementExtraTooltipMixin : OnDragStop ( )
local parent = self : GetParent ( ) ;
if parent and parent.OnDragStop then
parent : OnDragStop ( ) ;
end
end
function NarciAchievementExtraTooltipMixin : OnClick ( button )
if self.achievementID then
Narci_AchievementFrame : LocateAchievement ( self.achievementID ) ;
if button == " RightButton " or self.closeFrame then
self : GetParent ( ) : Hide ( ) ;
end
end
end
-----------------------------------------------------------------------------
function NarciAchievement_RedirectPrimaryAchievementFrame ( )
if NarciAchievementOptions.UseAsDefault then
RedirectFrame : OverrideFunctions ( ) ;
HookAchievementTooltip ( )
ENABLE_TOOLTIP = true ;
NarciAchievementAlertSystem : Enable ( ) ;
else
RedirectFrame : RestoreFunctions ( ) ;
ENABLE_TOOLTIP = false ;
NarciAchievementAlertSystem : Disable ( ) ;
end
end
local initialize = CreateFrame ( " Frame " ) ;
initialize : RegisterEvent ( " PLAYER_ENTERING_WORLD " ) ;
initialize : SetScript ( " OnEvent " , function ( self , event , ... )
if event == " PLAYER_ENTERING_WORLD " then
self : UnregisterEvent ( event ) ;
DataProvider : GetTrackedAchievements ( ) ;
self : RegisterEvent ( " TRACKED_ACHIEVEMENT_LIST_CHANGED " ) ;
self : RegisterEvent ( " ADDON_LOADED " ) ;
After ( 0.7 , function ( )
NarciAchievement_RedirectPrimaryAchievementFrame ( ) ;
BuildCategoryStructure ( ) ;
local isGuild = true ;
BuildCategoryStructure ( isGuild ) ;
InitializeFrame ( Narci_AchievementFrame ) ;
self : RegisterEvent ( " ACHIEVEMENT_EARNED " ) ;
self : RegisterEvent ( " CRITERIA_EARNED " ) ;
end )
elseif event == " ADDON_LOADED " then
local name = ... ;
if name == " Blizzard_AchievementUI " then
self : UnregisterEvent ( event ) ;
NarciAchievement_RedirectPrimaryAchievementFrame ( ) ;
end
elseif 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 == " CRITERIA_EARNED " then
local achievementID , description = ... ;
RefreshInspection ( achievementID ) ;
elseif event == " TRACKED_ACHIEVEMENT_LIST_CHANGED " then
UpdateTrackAchievements ( ) ;
end
--print(event)
end )
--[[
Sound :
sound / spells / spell_ma_arcaneorb_impact_01.ogg
1401 sound / doodad / scroll_bookevaporate01.ogg
/ run AchievementAlertSystem : AddAlert ( 13994 , true )
--]]