diff ObjectiveFrame.lua @ 6:589de8ea05b9

- validate tracked objects' existence by use of those handler.Info tables we made - apply collision checking to action buttons when their corresponding entry has scrolled out
author Nenue
date Fri, 01 Apr 2016 01:30:42 -0400
parents e9b61fd5f607
children 5301c68f28d8
line wrap: on
line diff
--- a/ObjectiveFrame.lua	Thu Mar 31 15:58:08 2016 -0400
+++ b/ObjectiveFrame.lua	Fri Apr 01 01:30:42 2016 -0400
@@ -27,6 +27,7 @@
 local previousBlock
 local currentBlock
 --- todo: map these into config table when its sorted out
+local itemButtonSize, itemButtonSpacing =  36, 1
 local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]]
 local titleSize, textSize = 15, 15
 local titleOutline, textOutline = "OUTLINE", "OUTLINE"
@@ -46,7 +47,7 @@
   ObjectiveWrapperParent = '',
   WrapperStyle = {
     Header = {
-      Background = {Left = [[Objective-Header]], Right = [[Objective-Header]], Tile = [[Objective-Header]]},
+      Background = {Left = '', Right = '', Tile = ''},
       BackgroundCrop = {Left = {0, 0.4, 0,1}, Right={0.6,1,0,1}, Tile = {0.4,.6,0,1,}},
       BackgroundScale = {Left = 100, Right = 100},
       Font = {wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline}
@@ -54,18 +55,18 @@
   },
   ObjectiveHeaderStyle = {
     Normal = {
-      Gradient = {MinColor = {0,0,0,0.5}, MaxColor = {0,0,0,.25}},
+      Gradient = {MinColor = {.05,.15,0.5,0.7}, MaxColor = {.05,.15,0.5,.35}},
       Font = {headerFont, headerSize, headerOutline}, Spacing = headerSpacing,
     }
   },
   ObjectiveTrackerStyle = {
     Normal = {
       Title = {
-        Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, 0}},
+        Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, .19}},
         Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing,
       },
       Text = {
-        Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, 0}},
+        Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, .12}},
         Font = {textFont, textSize, textOutline}, Spacing = textSpacing,
       },
     },
@@ -146,7 +147,7 @@
   self:SetVerticalScroll(s)
   print(s, r, self:GetVerticalScroll())
 
-  mod.UpdateActionButtons()
+  mod.UpdateActionButtons('SCROLLING')
 end
 
 local WrapperCloseButton_OnClick = function(self)
@@ -205,52 +206,76 @@
   end
 
   --- xp bar
-  XPBar:Show()
-  XPBar.rested:SetTexture(2,.6,1,1)
-  XPBar.fg:SetTexture(.3,.1,.95,1)
-  XPBar.bg:SetTexture(0,0,0,.25)
-  XPBar:RegisterEvent('PLAYER_XP_UPDATE')
-  XPBar:RegisterEvent('PLAYER_LEVEL_UP')
-  XPBar:RegisterEvent('PLAYER_UPDATE_RESTING')
+  XPBar:SetWidth(wrapperWidth - Wrapper.close:GetWidth())
+  XPBar.bg:SetAllPoints(XPBar)
+  XPBar:RegisterEvent('DISABLE_XP_GAIN')
+  XPBar:RegisterEvent('ENABLE_XP_GAIN')
   XPBar:SetScript('OnEvent', mod.UpdateXP)
-  mod.UpdateXP(Wrapper.xpBar)
+
+  if not IsXPUserDisabled() then
+    mod.EnableXP(XPBar)
+  else
+    mod.DisableXP(XPBar)
+  end
+
+  mod.UpdateXP(XPBar)
 end
 
-mod.UpdateXP = function()
-  local XPBar = Wrapper.XPBar
-  local xp = UnitXP('player')
-  local xpmax = UnitXPMax('player')
-  local rest = GetXPExhaustion()
+mod.EnableXP = function(self)
+  self:RegisterEvent('PLAYER_XP_UPDATE')
+  self:RegisterEvent('PLAYER_LEVEL_UP')
+  self:RegisterEvent('PLAYER_UPDATE_RESTING')
+  self.bg:SetTexture(0,0,0,.25)
+  self:Show()
+end
 
-  XPBar.bg:SetAllPoints(XPBar)
-  XPBar.fg:SetWidth((xp/xpmax) * XPBar:GetWidth())
+mod.DisableXP = function(self)
+  self:UnregisterEvent('PLAYER_XP_UPDATE')
+  self:UnregisterEvent('PLAYER_LEVEL_UP')
+  self:UnregisterEvent('PLAYER_UPDATE_RESTING')
+  self.bg:SetTexture(0.5,0.5,0.5,0.5)
+  self:Hide()
+end
 
-  if IsResting() then
-    XPBar.bg:SetTexture(.2,.8,.2,.5)
-  else
-    XPBar.bg:SetTexture(0,0,0,.25)
+mod.UpdateXP = function(self, event)
+  if event == 'DISABLE_XP_GAIN' then
+    mod.DisableXP(self)
+  elseif event == 'ENABLE_XP_GAIN' then
+    mod.EnableXP(self)
   end
 
-  if rest then
-    XPBar.rested:ClearAllPoints()
-    if xp == 0 then
-      XPBar.rested:SetPoint('TOPLEFT', XPBar, 'TOPLEFT', 0, 0)
+  if not IsXPUserDisabled() then
+
+    local xp = UnitXP('player')
+    local xpmax = UnitXPMax('player')
+    local rest = GetXPExhaustion()
+    self.fg:SetWidth((xp/xpmax) * self:GetWidth())
+    if rest then
+      self.rested:ClearAllPoints()
+      if xp == 0 then
+        self.rested:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
+      else
+        self.rested:SetPoint('TOPLEFT', self.fg, 'TOPRIGHT', 0, 0)
+      end
+
+      if (xp + rest) > xpmax then
+        self.rested:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, 0)
+      else
+        self.rested:SetWidth((rest/xpmax) * self:GetWidth())
+      end
+      self.rested:SetPoint('BOTTOM', self, 'BOTTOM')
+      self.rested:Show()
     else
-      XPBar.rested:SetPoint('TOPLEFT', XPBar.fg, 'TOPRIGHT', 0, 0)
+      self.rested:Hide()
     end
 
-    if (xp + rest) > xpmax then
-      XPBar.rested:SetPoint('BOTTOMRIGHT', XPBar, 'BOTTOMRIGHT', 0, 0)
+    if IsResting() then
+      self.bg:SetTexture(.2,.8,.2,.5)
     else
-      XPBar.rested:SetWidth((rest/xpmax) * XPBar:GetWidth())
+      self.bg:SetTexture(0,0,0,.25)
     end
-    XPBar.rested:SetPoint('BOTTOM', XPBar, 'BOTTOM')
-    XPBar.rested:Show()
-  else
-    XPBar.rested:Hide()
+    self.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or ''))
   end
-
-  XPBar.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or ''))
 end
 
 mod.UpdateReputation = function(self)
@@ -415,6 +440,11 @@
     --info.itemButton = nil
   end
 
+  if Devian and Devian.InWorkspace() then
+    t.debugText:Show()
+    t.debugText:SetText(tostring(blockIndex) .. '\n' .. tostring(info.itemButton and info.itemButton:GetName()))
+  end
+
   --- metrics are calculated in SetStyle
   t:SetStyle(style)
   t:Show()
@@ -598,69 +628,109 @@
   Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight)
 
   -- update action buttons
+  print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(),
+    '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(),
+    '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(),
+    '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5)
+  )
+  mod.UpdateActionButtons('FULL_UPDATE')
 
-
-  print('scroll size:', Scroll:GetSize())
-  print('scroller size:',Scroller:GetSize())
-  print('wrapper size:', Wrapper:GetSize())
-  print('scroll range :', floor(Scroller:GetVerticalScrollRange()+.5))
-
-
-  mod.UpdateActionButtons()
+  QuestPOIUpdateIcons()
 end
 
 --- Queue any active item buttons for update for that frame
-mod.UpdateActionButtons = function()
+mod.UpdateActionButtons = function(updateReason)
+  Scroller.snap_upper = 0
+  Scroller.snap_lower = 0
+  local print = B.print('ItemButton')
+  if updateReason then
+    print = B.print('IB_'..updateReason)
+  end
+
   local previousItem
   for questID, itemButton in pairs(usedButtons) do
-    local questIndex = mod.Quest.Info[questID].questLogIndex
+    local info= mod.Quest.Info[questID]
+
     print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName())
     local block = mod.Quest.QuestBlock[questID]
     if block then
         -- Dispatch the probe
-      if IsQuestWatched(questIndex) then
-
+      if IsQuestWatched(info.questLogIndex) then
+        itemButton.previousItem = previousItem
         print('  |cFFFFFF00probing', block:GetName())
         block:SetScript('OnUpdate', function()
           if block:GetBottom() and not InCombatLockdown() then
             print('  '..block:GetName()..' |cFF00FF00probe hit!')
-            mod.UpdateBlockAction(block, itemButton, previousItem)
+            mod.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope
             block:SetScript('OnUpdate', nil)
           end
         end)
+        previousItem = itemButton
       else
         print('hidden block or unwatched quest')
+        itemButton.previousItem = nil
         itemButton:Hide()
       end
     else
       print('  |cFFFF0088missing block data', itemButton:GetName())
+      itemButton.previousItem = nil
+      itemButton:Hide()
     end
   end
 end
 
-mod.UpdateBlockAction = function (block, itemButton, previousItem)
+mod.UpdateBlockAction = function (block, itemButton)
   print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()')
   if itemButton.questID ~= block.info.questID then
     print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID)
-
+    -- something happened between this and last frame, go back and set new probes
     return mod.UpdateActionButtons()
   end
 
-  if block:GetBottom() < Scroller:GetBottom() then
-    print('** ',block:GetName() ,'|cFFFFFF00bottom not fully visible')
+  local previousItem = itemButton.previousItem
+  local upper_bound = Scroller:GetTop() + Scroller.snap_upper
+  local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize
+  local point, anchor, relative
+
+  if block:GetBottom() < lower_bound then
+    print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5))
     if previousItem then
+      print('adjusting', previousItem:GetName())
       previousItem:ClearAllPoints()
-      previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, 4)
+      previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing)
     end
     itemButton:ClearAllPoints()
-    itemButton:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', Wrapper:GetLeft(), Wrapper:GetBottom())
+    itemButton.x = Wrapper:GetLeft() -4
+    itemButton.y = Wrapper:GetBottom()
+    point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT'
+    Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing
+
+  elseif block:GetTop() > upper_bound then
+    print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5))
+    itemButton:ClearAllPoints()
+    if previousItem then
+      print('latch onto another piece')
+      point, anchor, relative ='TOP', previousItem, 'BOTTOM'
+      itemButton.x = 0
+      itemButton.y = -itemButtonSpacing
+    else
+      print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop())
+      point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT'
+      itemButton.x = Scroller:GetLeft() -4
+      itemButton.y = Scroller:GetTop()
+    end
     itemButton:Show()
+    Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing)
   else
-    print('** ',block:GetName() ,'|cFF00FF00visible positions')
+    print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5))
     itemButton:ClearAllPoints()
-    itemButton:SetPoint('TOPRIGHT', UIParent, 'BOTTOMLEFT', block:GetLeft(), block:GetTop())
-    itemButton:Show()
+    itemButton.x = block:GetLeft() - itemButtonSpacing
+    itemButton.y = block:GetTop()
+    point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT'
   end
+
+  itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y)
+  itemButton:Show()
 end
 
 mod.UpdateItemButtonCooldown = function(button)