annotate ClassPlan.lua @ 113:03e4a8b93012 v7.3.0-2

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