annotate ClassPlan.lua @ 40:589c444d4837

WowAce/Curseforge migration push
author Nenue
date Sun, 25 Dec 2016 13:04:57 -0500
parents 26dfa661daa7
children 79e5e96e5f18
rev   line source
Nenue@40 1 local _, db = ...
Nenue@4 2 local wipe, tinsert, sort = table.wipe, tinsert, table.sort
Nenue@2 3 local pairs, ipairs = pairs, ipairs
Nenue@4 4 local floor, mod, time = floor, mod, time
Nenue@32 5 local max, min = math.max, math.min
Nenue@2 6 local GetTime = GetTime
Nenue@3 7 local GI_currentTime = time()
Nenue@32 8 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
Nenue@3 9
Nenue@32 10 local CP_REPLACE_LANDINGPAGE = true
Nenue@32 11 local CP_HEADER_SIZE = 24
Nenue@40 12 db.ClassPlanDefaultType = {
Nenue@40 13
Nenue@40 14 backgroundColor = {0, 0, 0, 0.5},
Nenue@40 15 textColor = {1,1,1,1}
Nenue@40 16 }
Nenue@40 17 db.ClassPlanTypes = setmetatable({}, {__index = db.ClassPlanDefaultType})
Nenue@40 18 db.ClassPlanTypes.inProgress = {
Nenue@40 19 backgroundColor = {0, 0, 0, 0.5},
Nenue@40 20 textColor = {1,1,1}
Nenue@40 21 }
Nenue@40 22 db.ClassPlanTypes.shipmentsReady = {
Nenue@40 23 backgroundColor = {1, 1, 0, 0.25 },
Nenue@40 24 textColor = {1, 1, 0}
Nenue@40 25 }
Nenue@40 26 db.ClassPlanTypes.complete = {
Nenue@40 27 backgroundColor = {0, 1, 0, 0.25 },
Nenue@40 28 textColor = {0, 1, 0}
Nenue@2 29 }
Nenue@2 30
Nenue@4 31 local GetTimeLeftString = function(timeLeft)
Nenue@4 32 local days = floor(timeLeft/(24*3600))
Nenue@4 33 local hours = floor(mod(timeLeft, (24*3600)) / 3600)
Nenue@4 34 local minutes = floor(mod(timeLeft, 3600) / 60)
Nenue@4 35 local seconds = mod(timeLeft, 60)
Nenue@4 36 if days >= 1 then
Nenue@6 37 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h') or '')
Nenue@4 38 else
Nenue@6 39 return ((hours > 0) and (hours .. 'h') or '') .. ((minutes > 0) and (' ' ..minutes .. ' min') or '')
Nenue@4 40 end
Nenue@4 41 end
Nenue@3 42
Nenue@32 43 ClassOrderPlanCore = {
Nenue@32 44 events = {},
Nenue@32 45 freeBlocks = {},
Nenue@35 46 characterButtons = {},
Nenue@32 47 blocks = {},
Nenue@32 48 sortedItems = {},
Nenue@32 49 timers = {},
Nenue@32 50 shipments = {},
Nenue@32 51 playerFirst = false,
Nenue@32 52 prototypes = {},
Nenue@40 53 Queued = {},
Nenue@40 54 Timers = {},
Nenue@40 55 ReportChunks = {},
Nenue@32 56 }
Nenue@40 57 ClassPlanHandlerBase = {
Nenue@32 58 numBlocks = 0,
Nenue@32 59 isStale = true,
Nenue@35 60 maxItems = 10
Nenue@32 61 }
Nenue@40 62 ClassPlanEntryBase = {}
Nenue@1 63
Nenue@32 64 local ClassPlan = ClassOrderPlanCore
Nenue@40 65 local Embed = function(object, ...)
Nenue@40 66 for i = 1, select('#', ...) do
Nenue@40 67 local src = select(i, ...)
Nenue@40 68 for k,v in pairs(src) do
Nenue@40 69 if not object[k] then
Nenue@40 70 object[k] = v
Nenue@40 71 end
Nenue@40 72 end
Nenue@40 73 end
Nenue@40 74 return object
Nenue@40 75 end
Nenue@5 76
Nenue@32 77 function ClassPlan:OnLoad ()
Nenue@3 78 self:RegisterEvent('PLAYER_LOGIN')
Nenue@3 79 self:RegisterEvent('ADDON_LOADED')
Nenue@3 80 self:RegisterEvent('PLAYER_REGEN_ENABLED')
Nenue@5 81 self:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@40 82 self:RegisterEvent('GARRISON_SHOW_LANDING_PAGE')
Nenue@32 83 self:RegisterForDrag('LeftButton')
Nenue@32 84 self:SetMovable(true)
Nenue@32 85 self:SetToplevel(true)
Nenue@32 86
Nenue@32 87 SLASH_CLASSPLAN1 = "/classplan"
Nenue@32 88 SLASH_CLASSPLAN2 = "/cp"
Nenue@32 89 SlashCmdList.CLASSPLAN = function(args)
Nenue@32 90 self:Toggle()
Nenue@32 91 end
Nenue@32 92
Nenue@40 93 local originalScript = GarrisonLandingPageMinimapButton:GetScript('OnClick')
Nenue@40 94 GarrisonLandingPageMinimapButton:SetScript("OnClick", function(minimap, button)
Nenue@40 95 if button == 'LeftButton' and (not IsShiftKeyDown()) then
Nenue@40 96 self:Toggle()
Nenue@40 97 else
Nenue@40 98 originalScript(minimap, button)
Nenue@40 99 end
Nenue@40 100 end)
Nenue@40 101 self.FadeOut:SetScript('OnFinished', function()
Nenue@40 102 self:Hide()
Nenue@40 103 self.data.IsShown = nil
Nenue@40 104 self.isAnimating = nil
Nenue@40 105 end)
Nenue@40 106 self.FadeIn:SetScript('OnPlay', function()
Nenue@40 107 self.isAnimating = true
Nenue@40 108 self:SetShown(true)
Nenue@40 109 end)
Nenue@40 110
Nenue@40 111 --hooksecurefunc(C_Garrison, 'RequestLandingPageShipmentInfo', function()
Nenue@40 112 -- WorldPlan:print("Requesting shipments data.")
Nenue@40 113 --end)
Nenue@40 114 C_Garrison.RequestLandingPageShipmentInfo();
Nenue@40 115 self.isStale = true
Nenue@4 116 end
Nenue@19 117
Nenue@40 118
Nenue@32 119 function ClassPlan:GetCurrentProfile()
Nenue@32 120 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {}
Nenue@32 121 local db = WorldPlanData.OrderHall
Nenue@32 122 self.data = db
Nenue@4 123
Nenue@32 124 local characters = db.characters or {}
Nenue@32 125 db.characters = characters
Nenue@4 126
Nenue@32 127 local name, realm = UnitName('player')
Nenue@32 128 realm = realm or GetRealmName()
Nenue@40 129
Nenue@32 130 local profileName = name .. '-' .. realm
Nenue@40 131 self.profile = characters[profileName] or {
Nenue@40 132 showItems = true
Nenue@40 133 }
Nenue@32 134 self.characters = characters
Nenue@32 135 characters[profileName] = self.profile
Nenue@32 136
Nenue@32 137 local classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
Nenue@32 138 local className = UnitClass('player')
Nenue@32 139 print('|cFFFFFF00Loaded:|r', classColor.hex, className, profileName)
Nenue@32 140 self.profile.classColor = classColor
Nenue@32 141 self.profile.className = className
Nenue@35 142 self.profile.characterName = name
Nenue@35 143 self.profile.characterRealm = realm
Nenue@40 144 -- flip it on
Nenue@40 145 self.profile.showItems = true
Nenue@40 146
Nenue@40 147 self.HeaderInset:SetHeight(CP_HEADER_SIZE)
Nenue@40 148 self.ClassStripe:SetColorTexture(classColor.r, classColor.g, classColor.b, 1)
Nenue@40 149 self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT')
Nenue@40 150
Nenue@32 151 return self.profile
Nenue@3 152 end
Nenue@3 153
Nenue@40 154 function ClassPlan:AddHandler(frame)
Nenue@40 155 print('|cFF00FF00'..frame:GetName()..' loaded')
Nenue@40 156 for i, event in ipairs(frame.events) do
Nenue@32 157 print('|cFF00FF00 event', event)
Nenue@40 158 frame:RegisterEvent(event)
Nenue@1 159 end
Nenue@40 160 frame.sortedItems = {}
Nenue@40 161 for index, listKey in ipairs(frame.listKey) do
Nenue@40 162 frame.profile = self.profile
Nenue@40 163 frame.data = self.data
Nenue@32 164 self.profile[listKey] = self.profile[listKey] or {}
Nenue@40 165 local listTitle = frame.listTitle[index]
Nenue@40 166 setmetatable(self.profile[listKey], { __tostring = function() return listTitle end })
Nenue@40 167 frame.sortedItems[listKey] = {}
Nenue@40 168
Nenue@32 169 end
Nenue@40 170 frame.owningFrame = self
Nenue@40 171 frame:SetList(1)
Nenue@3 172 end
Nenue@1 173
Nenue@32 174 function ClassPlan:OnEvent (event, arg)
Nenue@32 175 print(event, arg)
Nenue@5 176 if event == 'PLAYER_REGEN_DISABLED' then
Nenue@6 177 if self:IsVisible() then
Nenue@6 178 self.combatHide = true
Nenue@6 179 self:SetShown(false)
Nenue@6 180 end
Nenue@6 181
Nenue@5 182 elseif event == 'PLAYER_REGEN_ENABLED' then
Nenue@6 183 if self.combatHide == true then
Nenue@6 184 self.combatHide = nil
Nenue@6 185 self:SetShown(true)
Nenue@6 186 end
Nenue@32 187 elseif event == 'ADDON_LOADED' then
Nenue@32 188 if arg == 'Blizzard_GarrisonUI' then
Nenue@32 189 self:Reanchor()
Nenue@32 190 end
Nenue@3 191 elseif event == 'PLAYER_LOGIN' then
Nenue@3 192 if not self.initialized then
Nenue@4 193 self:Setup()
Nenue@1 194 end
Nenue@40 195 elseif event == 'GARRISON_SHOW_LANDING_PAGE' then
Nenue@40 196 self:RefreshData()
Nenue@2 197 end
Nenue@2 198 end
Nenue@2 199
Nenue@32 200 function ClassPlan:Setup()
Nenue@32 201 if IsLoggedIn() then
Nenue@32 202 print('|cFFFFFF00'..self:GetName()..':Setup()|r')
Nenue@32 203
Nenue@32 204 self:GetCurrentProfile()
Nenue@32 205 for _, handler in ipairs(self.Handlers) do
Nenue@40 206 self:AddHandler(handler)
Nenue@40 207 handler.initialized = true
Nenue@32 208 end
Nenue@32 209 self.initialized = true
Nenue@32 210 self:SetShown(self.data.IsShown)
Nenue@40 211
Nenue@40 212
Nenue@32 213 end
Nenue@3 214 end
Nenue@3 215
Nenue@4 216
Nenue@32 217 --- Update space
Nenue@4 218
Nenue@40 219 local max = math.max
Nenue@40 220 function ClassPlan:RefreshData()
Nenue@40 221 local detailsFailed
Nenue@40 222 for index, handler in pairs(self.Handlers) do
Nenue@40 223 print(' |cFF00FF00'..handler:GetName()..' data update|r')
Nenue@40 224 handler:RefreshData()
Nenue@40 225 end
Nenue@40 226 if detailsFailed then
Nenue@40 227 db.print('Unable to obtain player details. Trying again later.')
Nenue@40 228 else
Nenue@40 229 self.requestingData = nil
Nenue@40 230 end
Nenue@40 231 end
Nenue@35 232
Nenue@40 233 function ClassPlan:Update()
Nenue@40 234 print('|cFF00FFFF'..self:GetName()..'Refresh()|r')
Nenue@3 235
Nenue@40 236 self.currentHeight = 0
Nenue@40 237 for index, handler in ipairs(self.Handlers) do
Nenue@40 238 local itemsHeight = handler:UpdateItems()
Nenue@40 239 if itemsHeight then
Nenue@40 240 self.currentHeight = max(itemsHeight, self.currentHeight)
Nenue@40 241 end
Nenue@40 242 end
Nenue@23 243
Nenue@40 244 local index = 1
Nenue@40 245 for key, info in pairs(self.data.characters) do
Nenue@40 246 print('cbutton', key)
Nenue@40 247 if self.data[key] then
Nenue@40 248 print('|cFFFF4400remove legacy value', key)
Nenue@40 249 self.data[key] = nil
Nenue@23 250 end
Nenue@23 251
Nenue@35 252
Nenue@40 253 local button = self.characterButtons[index]
Nenue@40 254 if not button then
Nenue@40 255 button = CreateFrame('Button', nil, self, 'ClassOrderPlanCharacterButton')
Nenue@40 256 button:SetID(index)
Nenue@40 257 self.characterButtons[index] = button
Nenue@40 258
Nenue@40 259 if not self.lastButton then
Nenue@40 260 button:SetPoint('TOPLEFT', self.HeaderInset, 'TOPLEFT', 0, 0)
Nenue@40 261 else
Nenue@40 262 button:SetPoint('TOPLEFT', self.lastButton, 'TOPRIGHT', 2, 0)
Nenue@35 263 end
Nenue@40 264 self.lastButton = button
Nenue@40 265 end
Nenue@40 266 if not info.characterName then
Nenue@40 267 info.characterName, info.characterRealm = key:match("%(.+)%-(.+)^")
Nenue@35 268 end
Nenue@35 269
Nenue@40 270 print(info.characterName)
Nenue@35 271
Nenue@40 272 button:SetSize(CP_HEADER_SIZE, CP_HEADER_SIZE)
Nenue@40 273 button.profileKey = key
Nenue@40 274 button.className = info.className
Nenue@40 275 button.classColor = info.classColor
Nenue@40 276 button.characterName = info.characterName
Nenue@40 277 button.characterRealm = info.characterRealm
Nenue@40 278 button.showItems = info.showItems
Nenue@40 279 button.isMine = (info == self.profile)
Nenue@40 280 button:Update()
Nenue@40 281 button:Show()
Nenue@40 282 index = index + 1
Nenue@3 283 end
Nenue@3 284
Nenue@40 285 self.HeaderInset:SetHeight(CP_HEADER_SIZE)
Nenue@40 286 self.HeaderInset:ClearAllPoints()
Nenue@40 287 self.HeaderInset:SetPoint('TOPLEFT' ,self, 'TOPLEFT')
Nenue@40 288 self.HeaderInset:SetPoint('RIGHT' ,self, 'RIGHT')
Nenue@40 289 self.ClassStripe:ClearAllPoints()
Nenue@40 290 self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT', 0, 0)
Nenue@40 291 self.ClassStripe:SetPoint('RIGHT')
Nenue@40 292 self:Reanchor()
Nenue@40 293 self.isStale = nil
Nenue@40 294 end
Nenue@40 295
Nenue@3 296
Nenue@32 297 function ClassPlan:Toggle()
Nenue@5 298 if self:IsShown() then
Nenue@40 299 self.FadeOut:Play()
Nenue@3 300 else
Nenue@40 301 self.data.IsShown = true
Nenue@40 302 self.FadeIn:Play()
Nenue@3 303 end
Nenue@3 304 end
Nenue@3 305
Nenue@40 306
Nenue@32 307 function ClassPlan:OnUpdate()
Nenue@40 308 if self.requestingData then
Nenue@40 309 self:RefreshData()
Nenue@40 310 elseif self.isStale then
Nenue@40 311 -- shouldn't happen, usually
Nenue@32 312 self:Update()
Nenue@18 313 end
Nenue@40 314 if #self.ReportChunks >= 1 then
Nenue@40 315 db.print(table.concat(self.ReportChunks, ', '))
Nenue@40 316 wipe(self.ReportChunks)
Nenue@40 317 end
Nenue@40 318
Nenue@3 319 end
Nenue@3 320
Nenue@32 321 function ClassPlan:OnShow()
Nenue@23 322 print('|cFF00FFFFShow()')
Nenue@40 323 self.isStale = true
Nenue@32 324 self:Reanchor()
Nenue@3 325 end
Nenue@3 326
Nenue@32 327 function ClassPlan:OnHide()
Nenue@32 328 print('|cFF00FFFFHide()')
Nenue@3 329 end
Nenue@3 330
Nenue@32 331 function ClassPlan:Reanchor()
Nenue@40 332 if not (self.data.positionX and self.data.positionY) then
Nenue@40 333 self.data.positionX = 0
Nenue@40 334 self.data.positionY = -148
Nenue@40 335 end
Nenue@32 336 self:ClearAllPoints()
Nenue@40 337 self:SetPoint('TOP', self.data.positionX, self.data.positionY)
Nenue@40 338 self.currentHeight = 0
Nenue@32 339 for index, frame in ipairs(self.Handlers) do
Nenue@32 340 frame:Reanchor()
Nenue@35 341 local ListTab = frame.ListTab
Nenue@35 342 if ListTab then
Nenue@35 343 ListTab:ClearAllPoints()
Nenue@40 344 ListTab:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0)
Nenue@40 345 ListTab:SetPoint('BOTTOMRIGHT', frame, 'TOPRIGHT', 0, -CP_HEADER_SIZE)
Nenue@35 346 ListTab.Label:SetText(frame.listTitle[frame.currentListIndex])
Nenue@35 347 ListTab:Show()
Nenue@35 348 print(ListTab:GetSize())
Nenue@35 349 end
Nenue@40 350 self.currentHeight = max(self.currentHeight, frame.currentHeight or 0)
Nenue@40 351 end
Nenue@40 352 self:SetHeight(self.currentHeight + self.HeaderInset:GetHeight() + self.ClassStripe:GetHeight())
Nenue@35 353
Nenue@2 354 end
Nenue@2 355
Nenue@32 356 function ClassPlan:OnDragStart()
Nenue@32 357 self:StartMoving()
Nenue@32 358 end
Nenue@32 359 function ClassPlan:OnDragStop()
Nenue@32 360 self:StopMovingOrSizing()
Nenue@32 361 local x,y = self:GetCenter()
Nenue@32 362 if x and y then
Nenue@32 363 x = (x - GetScreenWidth()/2)
Nenue@32 364 y = (y - GetScreenHeight()/2) * -1
Nenue@32 365 self.data.positionX, self.data.positionY = x,y
Nenue@32 366 print('saving positions:', x, y)
Nenue@32 367 end
Nenue@32 368 end
Nenue@32 369
Nenue@40 370 function ClassPlanHandlerBase:ScheduleUpdate(expires)
Nenue@40 371 -- value will occasionally lag so check here
Nenue@40 372 local duration = expires - time()
Nenue@40 373 self.Timers = self.Timers or {}
Nenue@40 374 if (duration > 0) and (not self.Timers[expires]) then
Nenue@40 375 print(' adding timer at', expires, 'c', duration)
Nenue@40 376 self.Timers[expires] = true
Nenue@40 377 C_Timer.After(duration, function()
Nenue@40 378 self.isStale = true
Nenue@40 379 self:UpdateItems()
Nenue@40 380 self.Timers[expires] = nil
Nenue@40 381 end)
Nenue@40 382 end
Nenue@40 383 end
Nenue@40 384
Nenue@40 385 function ClassPlanHandlerBase:SetList(index)
Nenue@40 386 local prevIndex = self.currentListIndex
Nenue@32 387 if not index then
Nenue@32 388 if self.currentListIndex == #self.listKey then
Nenue@32 389 index = 1
Nenue@32 390 else
Nenue@32 391 index = self.currentListIndex + 1
Nenue@32 392 end
Nenue@32 393 end
Nenue@32 394
Nenue@40 395 print('|cFF0088FF'..self:GetName()..'|r:SetList()', index, self.listKey[index])
Nenue@32 396 self.currentListIndex = index
Nenue@32 397 self.activeKey = self.listKey[index]
Nenue@32 398 self.activeTitle = self.listTitle[index]
Nenue@32 399
Nenue@40 400 self.ListTab.Label:SetText(self.listTitle[index])
Nenue@32 401 self.isStale = true
Nenue@40 402
Nenue@40 403 if self.OnSetList then
Nenue@40 404 self:OnSetList(self.currentListIndex, prevIndex)
Nenue@40 405 end
Nenue@32 406 end
Nenue@32 407
Nenue@40 408 function ClassPlanHandlerBase:OnMouseWheel(delta)
Nenue@35 409 self.scrollOffset = (self.scrollOffset or 0) - ((delta > 0) and 1 or -1)
Nenue@35 410 self:UpdateItems()
Nenue@35 411 end
Nenue@35 412
Nenue@40 413 function ClassPlanHandlerBase:RefreshData()
Nenue@40 414 print('|cFF0088FF'..self:GetName()..':RefreshData()')
Nenue@40 415 local activeKey = self.activeKey
Nenue@40 416 local detailsFailed
Nenue@40 417 self.truncatedItems = 0
Nenue@40 418 self.currentTime = time()
Nenue@40 419 if self:GetParent().profile then
Nenue@40 420 self:GetPlayerData()
Nenue@40 421 else
Nenue@40 422 detailsFailed = true
Nenue@40 423 end
Nenue@40 424 for _, listKey in ipairs(self.listKey) do
Nenue@40 425 local sortedItems = self.sortedItems[listKey]
Nenue@40 426 wipe(sortedItems)
Nenue@40 427 for key, profile in pairs(self.data.characters) do
Nenue@40 428 local isMine = (profile == self.profile)
Nenue@40 429 print(key, listKey, isMine, profile.showItems)
Nenue@40 430 local profileList = profile[listKey]
Nenue@40 431 if profileList and #profileList >= 1 then
Nenue@40 432 local classColor = profile.classColor or RAID_CLASS_COLORS['HUNTER']
Nenue@40 433 if profile.showItems then
Nenue@40 434 for index, data in ipairs(profileList) do
Nenue@40 435 data.classColor = classColor
Nenue@40 436 data.profileKey = key
Nenue@40 437 data.isMine = isMine
Nenue@40 438 if self.OnGetItem then
Nenue@40 439 self:OnGetItem(data)
Nenue@40 440 end
Nenue@40 441 tinsert(sortedItems, data)
Nenue@40 442 end
Nenue@40 443 else
Nenue@40 444 self.truncatedItems = self.truncatedItems + 1
Nenue@40 445 end
Nenue@40 446 end
Nenue@40 447 end
Nenue@40 448
Nenue@40 449 if self.SortHandler then
Nenue@40 450 sort(sortedItems, self.SortHandler)
Nenue@40 451 end
Nenue@40 452 end
Nenue@40 453
Nenue@40 454 for k,v in pairs(self.sortedItems) do
Nenue@40 455 print(' ', k)
Nenue@40 456 end
Nenue@40 457
Nenue@32 458 self.isStale = true
Nenue@32 459 end
Nenue@32 460
Nenue@40 461 function ClassPlanHandlerBase:OnEvent(event, id)
Nenue@40 462 if (event == 'GARRISON_MISSION_LIST_UPDATE') then
Nenue@40 463 if (id == LE_FOLLOWER_TYPE_GARRISON_7_0) then
Nenue@40 464 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id)
Nenue@40 465 self:RefreshData()
Nenue@40 466 end
Nenue@6 467 else
Nenue@40 468 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id)
Nenue@32 469 end
Nenue@32 470 end
Nenue@32 471
Nenue@40 472 function ClassPlanHandlerBase:OnUpdate()
Nenue@40 473 if self.isStale then
Nenue@40 474 print('|cFF00FF00'..self:GetName()..':OnUpdate()|r')
Nenue@40 475
Nenue@40 476 self:UpdateItems()
Nenue@40 477 end
Nenue@40 478 end
Nenue@32 479
Nenue@32 480 -- Stuff set on every list item
Nenue@40 481 function ClassPlanHandlerBase:SetOwnerData (self, data)
Nenue@32 482 local name, realm = string.match(data.profileKey, "(.+)%-(.+)")
Nenue@32 483 local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r'
Nenue@32 484 self.Owner:SetText(ownerText)
Nenue@32 485 self.Name:SetText(self.name)
Nenue@32 486 self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
Nenue@32 487 end
Nenue@32 488
Nenue@40 489 function ClassPlanHandlerBase:Acquire(id)
Nenue@35 490 end
Nenue@40 491 function ClassPlanHandlerBase:FreeBlock (block)
Nenue@35 492 end
Nenue@35 493
Nenue@40 494 function ClassPlanHandlerBase:UpdateItems()
Nenue@40 495 print('|cFF0088FF '..self:GetName()..':UpdateItems()|r', self.activeKey)
Nenue@35 496 self.MoreItemsUp:Hide()
Nenue@35 497 self.MoreItemsDown:Hide()
Nenue@40 498 local sortedItems = self.sortedItems[self.activeKey]
Nenue@35 499 local scrollOffset = self.scrollOffset or 0
Nenue@35 500 local numItems = #sortedItems
Nenue@35 501 if (not sortedItems[scrollOffset+1]) or (numItems <= self.maxItems) then
Nenue@35 502 scrollOffset = 0
Nenue@35 503 elseif (numItems > self.maxItems) and (scrollOffset > (numItems - self.maxItems)) then
Nenue@35 504 scrollOffset = (numItems - self.maxItems)
Nenue@35 505 end
Nenue@35 506
Nenue@40 507 self.ListTab.Count:SetText(numItems)
Nenue@32 508 self.blocks = self.blocks or {}
Nenue@32 509 local blocks = self.blocks
Nenue@32 510 local lastProfile
Nenue@40 511 local totalHeight = (self.ListTab:GetHeight() or 0)
Nenue@32 512 self.lastBlock = nil
Nenue@32 513 self.numActive = 0
Nenue@35 514 for i = 1, self.maxItems do
Nenue@35 515 local index = scrollOffset + i
Nenue@35 516 local data = sortedItems[index]
Nenue@35 517 if not data then
Nenue@40 518 print('|cFFFF4400end of data')
Nenue@35 519 break
Nenue@35 520 end
Nenue@35 521
Nenue@32 522 local block = blocks[i]
Nenue@32 523 if not block then
Nenue@40 524 block = CreateFrame('Button', self:GetName()..'ListItem'..i , self, self.templateName)
Nenue@32 525 block.listType = self.activeKey
Nenue@40 526
Nenue@40 527 block.doAnimation = true
Nenue@40 528
Nenue@32 529 block.handler = self
Nenue@32 530 self.numBlocks = self.numBlocks + 1
Nenue@32 531 blocks[i] = block
Nenue@32 532 end
Nenue@35 533 block:SetID(index)
Nenue@32 534 self.numActive = self.numActive + 1
Nenue@32 535
Nenue@32 536 if self.lastBlock then
Nenue@32 537 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
Nenue@40 538 --print('--', index, data.isComplete, data.missionEndTime, data.name)
Nenue@32 539 else
Nenue@40 540 block:SetPoint('TOPLEFT', self.ListTab, 'BOTTOMLEFT', 0, 0)
Nenue@40 541 --print('--top')
Nenue@32 542 end
Nenue@32 543 self.lastBlock = block
Nenue@32 544
Nenue@32 545 totalHeight = totalHeight + block:GetHeight()
Nenue@32 546 block.lastProfile = lastProfile
Nenue@32 547 -- blot out arbitrary flags
Nenue@32 548 block.offerEndTime = nil
Nenue@32 549 block.missionEndTime = nil
Nenue@32 550 block.creationTime = nil
Nenue@32 551 block.duration = nil
Nenue@32 552 block.throttle = 5
Nenue@32 553
Nenue@32 554 for k,v in pairs(data) do
Nenue@32 555 if type(block[k]) ~= 'function' then
Nenue@32 556 block[k] = v
Nenue@32 557 end
Nenue@32 558 end
Nenue@32 559
Nenue@32 560 block:Update()
Nenue@32 561 self:SetOwnerData(block, data)
Nenue@32 562
Nenue@32 563 block:Show()
Nenue@32 564 lastProfile = data.profileKey
Nenue@6 565 end
Nenue@6 566
Nenue@35 567 if self.numActive < numItems then
Nenue@35 568 if scrollOffset < (numItems - self.maxItems) then
Nenue@35 569 self.MoreItemsDown:Show()
Nenue@35 570 end
Nenue@35 571 if scrollOffset > 0 then
Nenue@35 572 self.MoreItemsUp:Show()
Nenue@35 573 end
Nenue@35 574 end
Nenue@35 575
Nenue@35 576 for i = self.numActive + 1, self.numBlocks do
Nenue@32 577 if blocks[i] then
Nenue@32 578 blocks[i]:Hide()
Nenue@32 579 end
Nenue@32 580 end
Nenue@32 581
Nenue@40 582 self:Reanchor()
Nenue@40 583 if totalHeight ~= self.currentHeight then
Nenue@40 584 self.currentHeight = totalHeight
Nenue@40 585 self:SetHeight(self.currentHeight)
Nenue@40 586 self:GetParent():Reanchor()
Nenue@40 587 end
Nenue@40 588
Nenue@40 589
Nenue@35 590 self.scrollOffset = scrollOffset
Nenue@40 591 self.isStale = nil
Nenue@32 592 return totalHeight
Nenue@32 593 end
Nenue@32 594
Nenue@40 595 function ClassPlanEntryBase:OnAnimFinished()
Nenue@40 596 end
Nenue@40 597 function ClassPlanEntryBase:OnShow()
Nenue@32 598
Nenue@40 599 print('|cFF44FF00'..self:GetName()..':OnShow()')
Nenue@40 600 if self.doAnimation then
Nenue@40 601 self.doAnimation = nil
Nenue@40 602 if not ClassOrderPlan.isAnimating then
Nenue@40 603 self.NewBlockFade:Play()
Nenue@32 604 end
Nenue@32 605 end
Nenue@32 606 end
Nenue@35 607
Nenue@40 608 function ClassPlanEntryBase:SetTimeLeft(expires, duration)
Nenue@35 609 self.ProgressBG:Hide()
Nenue@35 610 self.ProgressBar:Hide()
Nenue@35 611 if not expires then
Nenue@35 612 return
Nenue@32 613 end
Nenue@32 614
Nenue@35 615 -- calculate here since time isn't available
Nenue@40 616 local timeLeft = expires - time()
Nenue@35 617 if timeLeft < 0 then
Nenue@35 618 -- handle being complete
Nenue@40 619 if self.shipmentsReady and (self.shipmentsReady < self.shipmentsTotal) then
Nenue@40 620 self.TimeLeft:SetText('Ready')
Nenue@40 621 else
Nenue@40 622 self.TimeLeft:SetText('Complete!')
Nenue@40 623 end
Nenue@35 624 else
Nenue@35 625 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
Nenue@35 626 end
Nenue@32 627
Nenue@35 628 if (timeLeft > 0) and duration then
Nenue@35 629 local progress = (duration - timeLeft) / duration
Nenue@35 630 local r = ((progress >= .5) and (progress/2)) or 1
Nenue@35 631 local g = ((progress <= .5) and (progress*2)) or 1
Nenue@35 632 self.ProgressBG:Show()
Nenue@35 633 self.ProgressBar:Show()
Nenue@35 634 self.ProgressBG:SetColorTexture(r,g,0,0.25)
Nenue@35 635 self.ProgressBar:SetColorTexture(r,g,0,0.5)
Nenue@40 636 self.ProgressBar:SetWidth(self.ProgressBG:GetWidth() * progress)
Nenue@35 637 end
Nenue@32 638 end
Nenue@32 639
Nenue@32 640
Nenue@40 641
Nenue@40 642 ClassPlanHeaderMixin = {}
Nenue@40 643 function ClassPlanHeaderMixin:OnLoad()
Nenue@40 644 self:EnableMouse((#self:GetParent().listKey > 1))
Nenue@40 645 self:RegisterForClicks('AnyUp')
Nenue@32 646 end
Nenue@40 647 function ClassPlanHeaderMixin:OnClick ()
Nenue@40 648 local frame = self:GetParent()
Nenue@40 649 frame:SetList()
Nenue@40 650 if frame.OnHeaderClick then
Nenue@40 651 frame.OnHeaderClick(frame)
Nenue@32 652 end
Nenue@32 653 end
Nenue@32 654
Nenue@40 655 ClassPlanCharacterButtonMixin = {
Nenue@40 656 }
Nenue@40 657 function ClassPlanCharacterButtonMixin:Update ()
Nenue@40 658 --print(CLASS_ICON_TCOORDS[self.className:upper()])
Nenue@40 659 if self.className and CLASS_ICON_TCOORDS[self.className:upper()] then
Nenue@40 660 self.Icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[self.className:upper()]))
Nenue@32 661 end
Nenue@40 662 self.Icon:SetDesaturated((not self.showItems))
Nenue@40 663 self.SelectGlow:SetShown(self.isMine)
Nenue@32 664 end
Nenue@32 665
Nenue@40 666 function ClassPlanCharacterButtonMixin:OnEnter()
Nenue@40 667 if not self.profileKey then
Nenue@18 668 return
Nenue@18 669 end
Nenue@2 670
Nenue@40 671 GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
Nenue@40 672 local info = ClassOrderPlan.data.characters[self.profileKey]
Nenue@40 673 GameTooltip:AddLine(self.characterName, self.classColor.r, self.classColor.g, self.classColor.b)
Nenue@40 674 local numItems = 0
Nenue@40 675 if info.missions then
Nenue@40 676 GameTooltip:AddLine(#info.missions .. ' mission'..((#info.missions == 1) and '' or 's')..' in progress')
Nenue@2 677 end
Nenue@40 678 if info.shipments then
Nenue@40 679 GameTooltip:AddLine(#info.shipments .. ' work order' .. ((#info.shipments == 1) and '' or 's'))
Nenue@40 680 end
Nenue@40 681 if info.available then
Nenue@40 682 GameTooltip:AddLine(#info.available .. ' mission'..((#info.available == 1) and '' or 's')..' available')
Nenue@40 683 end
Nenue@40 684 GameTooltip:Show()
Nenue@2 685 end
Nenue@2 686
Nenue@40 687 function ClassPlanCharacterButtonMixin:OnLeave()
Nenue@2 688 if GameTooltip:IsOwned(self) then
Nenue@2 689 GameTooltip:Hide()
Nenue@2 690 end
Nenue@2 691 end
Nenue@2 692
Nenue@40 693 function ClassPlanCharacterButtonMixin:OnClick(button, down)
Nenue@40 694 print('OnClick', self.profileKey)
Nenue@40 695 local clist = ClassOrderPlan.data.characters
Nenue@40 696
Nenue@3 697 if button == 'RightButton' then
Nenue@40 698 for _, profile in pairs(clist) do
Nenue@40 699 profile.showItems = true
Nenue@40 700 end
Nenue@40 701 else
Nenue@40 702 if clist[self.profileKey].showItems then
Nenue@40 703 clist[self.profileKey].showItems = nil
Nenue@40 704 else
Nenue@40 705 clist[self.profileKey].showItems = true
Nenue@40 706 end
Nenue@3 707 end
Nenue@40 708 for i, handler in ipairs(ClassOrderPlan.Handlers) do
Nenue@40 709 handler.isStale = true
Nenue@40 710 end
Nenue@40 711
Nenue@40 712 ClassOrderPlan:RefreshData()
Nenue@40 713 ClassOrderPlan:Update()
Nenue@40 714 print(clist[self.profileKey].showItems)
Nenue@32 715 end