Thread Tools Display Modes
10-23-08, 11:24 PM   #1
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
Statframelib:MAking it libstub

I posted in the request forum but i will post here too, desperate...

I have been looking at the statframelib http://www.wowace.com/projects/statframelib/ and i kinda would to use it in a mod me and some people are working on, problem is we're using ace3 and this lib is ace2. So i kinda would like it to use Libstub of some sort, I have been trying to do it myself but i think i am doing more harm then good (Lua newbie style)

I will post what i have hacked at(only bits and piaces) and maybe someone can tell me what i need to do.

Code:
local MAJOR_VERSION = "StatFrameLib-1.0"
local MINOR_VERSION = 90000 + tonumber(("$Revision: 40 $"):match("(%d+)"))

local StatFrameLib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)


--not sure what how to handle the below
--[[local StatFrameLib = AceOO.Mixin {
   "AddStatFrame",
   "RemoveStatFrame",
   "RemoveAllStatFrames",
   "StatFrameReport",
   "IsShowingStatFrame",
   "RepaintStatFrame",
   "RepaintAllStatFrames",
   "StatBoxSet",
   "StatBoxSetWithoutShow",
}]]--

-- local declarations
local frame_index_from_name, frame_label_from_name, frame_name_from_index
local paintLeftStatFrame, paintRightStatFrame, repaintTooltips
local setupLeftStatFrame, setupRightStatFrame
local default_mouseovers, slurpDefaultEventHooks, setDefaultEventHooks
local UpdatePaperdollStatsHook, activate

local StatFrameLeft, StatFrameRight
local stat_frame_left_default_hooks,stat_frame_right_default_hooks
local setBlizEventHooks

-- indexes => frame_name
-- names => labels
local frame_indexes,frame_names
--#NODOC local
function frame_index_from_name(name)
   return "STATFRAME_"..string.upper(name)
end
--#NODOC local
function frame_label_from_name(name)
   return frame_labels[self][name]
end
--#NODOC local
function frame_name_from_index(index)
   return frame_name[self][index]
end


--[[-------------------------------------------
  Public methods
--]]

--[[-------------------------------------------
-- Notes:
--         * Adds a stat frame to the dropdown list.
--         * Should be added on enable, not on load - frames will be dropped on suspend
--         * You MUST have a method for painting the frame. This will be a method
--           on your object named Paint[frame name]. So if you called AddStatFrame("Peter")
--           then it would be :PaintPeter. See the example.
--         * You MAY have a method for setting up custom mouseovers and such for the lines.
--           This method will be called SetupFrame[frame name] like the above. See the example.
--         * If you just want tooltips, create methods like Paint[frame name]Line1Tooltip.
--           GameTooltip anchor will be set up for you, just go ahead and write to it.
--           This will not work if you do a custom SetupFrame. See the example for more.
-- Arguments:
--         string - name of the frame to add. This is the programmatic name, not the label.
--         string - label for the frame.
--]]
function StatFrameLib:AddStatFrame(frame_name,frame_label)
   local frame_index = frame_index_from_name(frame_name)

   for _,v in ipairs(PLAYERSTAT_DROPDOWN_OPTIONS) do
      if v == frame_index then
         error(string.format("Attempted to doubly add stat frame %s",frame_name))
      end
   end

   tinsert(PLAYERSTAT_DROPDOWN_OPTIONS,frame_index)
   _G[frame_index] = frame_label

   frame_names[self][frame_name] = frame_label
   frame_indexes[self][frame_index] = frame_name

   local paint_method = self["Paint"..frame_name]
   if not paint_method then
      error(self.format("Cannot add stat frame %s: paint method %s does not exist!",frame_name,paint_method))
   end
end

--[[-------------------------------------------
-- Arguments:
--         string - programmatic name of the frame to remove
-- Notes:
--         * Not necessary to call this method on disable - will automatically be called.
--]]
function StatFrameLib:RemoveStatFrame(frame_name)
   local frame_index = frame_index_from_name(frame_name)
   local removed = false
   for k,v in ipairs(PLAYERSTAT_DROPDOWN_OPTIONS) do
      if v == frame_index then
         removed = true
         tremove(PLAYERSTAT_DROPDOWN_OPTIONS,k)
      end
   end
   if not removed then
      error("Attempted to remove non-existant StatFrame %s",frame_name);
   end

   -- cleanup after ourselves
   if GetCVar("playerStatLeftDropdown") == frame_index then
      SetCVar("playerStatLeftDropdown", "PLAYERSTAT_BASE_STATS")
   end
   if GetCVar("playerStatRightDropdown") == frame_index then
      local _,class = UnitClass("player")
      if "MAGE" == class or "PRIEST" == class or "WARLOCK" == class or "DRUID" == class then
         SetCVar("playerStatRightDropdown", "PLAYERSTAT_SPELL_COMBAT")
      elseif "HUNTER" == class then
         SetCVar("playerStatRightDropdown", "PLAYERSTAT_RANGED_COMBAT")
      else
         SetCVar("playerStatRightDropdown", "PLAYERSTAT_MELEE_COMBAT")
      end
   end
   UIDropDownMenu_SetSelectedValue(PlayerStatFrameLeftDropDown, GetCVar("playerStatLeftDropdown"))
   UIDropDownMenu_SetSelectedValue(PlayerStatFrameRightDropDown, GetCVar("playerStatRightDropdown"))
   PaperDollFrame_UpdateStats()

   frame_names[self][frame_name] = nil
   frame_indexes[self][frame_index] = nil
end

--[[-------------------------------------------
-- Notes:
--         * Removes all of your stat frames
--]]
function StatFrameLib:RemoveAllStatFrames()
   DEFAULT_CHAT_FRAME:AddMessage("removing all frames")
   for frame_name,_ in pairs(frame_names[self]) do
      self:RemoveStatFrame(frame_name)
   end
end

--[[-------------------------------------------
-- Notes:
--         * Lets you know if your stat frame is being displayed
-- Arguments:
--         string - name of the frame you're querying
--]]
function StatFrameLib:IsShowingStatFrame(frame_name)
   local index = frame_index_from_name(frame_name)
   if not index then
      error("Frame %s does not exist", frame_name)
   end

   if GetCVar("playerStatRightDropdown") == index or
      GetCVar("playerStatLeftDropdown")  == index then
      return true
   else
      return false
   end
end

--[[-------------------------------------------
-- Notes:
--          * Method you call to actually set the label and text for lines in the StatBox
--          * labels and values will be coerced to strings, so don't worry too much about them
--          * Will automatically show the line. Use the variant call if you don't want to do that.
--          * See the example for how this is used
-- Arguments:
--         object - the line you're drawing to
--         string - the label
--         string or number - the value
--         boolean - if the VALUE is a number show it as a percentage
--]]
function StatFrameLib:StatBoxSet(statbox, label, value, percentage)
   if type(value) ~= "number" then
      value = tostring(value)
   end
   PaperDollFrame_SetLabelAndText(statbox, tostring(label), value, percentage)
   statbox:Show()
end

--[[-------------------------------------------
-- Notes:
--         * Same call as StatBoxSet, but does not automatically show the line
-- Arguments:
--         object - the line you're drawing to
--         string - the label
--         string or number - the value
--         boolean - if the VALUE is a number show it as a percentage
--]]
function StatFrameLib:StatBoxSetWithoutShow(statbox,label,value,percentage)
   if type(value) ~= "number" then
      value = tostring(value)
   end
   PaperDollFrame_SetLabelAndText(statbox,tostring(label),value,percentage)
end

--[[-------------------------------------------
-- Notes:
--         * Orders a repaint of your stat frame
-- Arguments:
--         string - the programmatic name of the frame
--]]
function StatFrameLib:RepaintStatFrame(frame_name)
   local index = frame_index_from_name(frame_name)
   local painter = self["Paint"..frame_name]
   if not index then
      error("Stat frame %s does not exist",frame_name)
   end
   if GetCVar("playerStatRightDropdown") == index then
      paintRightStatFrame(painter, self)
      repaintTooltips("PlayerStatFrameRight", StatFrameRight)
   end
   if GetCVar("playerStatLeftDropdown") == index then
      paintLeftStatFrame(painter, self)
      repaintTooltips("PlayerStatFrameLeft", StatFrameLeft)
   end
end

--[[-------------------------------------------
-- Notes:
--         * Repaints all of your stat frames
--]]
-- TankPoints:RepaintStatFrame("TankPoints")
function StatFrameLib:RepaintAllStatFrames()
   for frame_name, _ in pairs(frame_names[self]) do
      self:RepaintStatFrame(frame_name)
   end
end
--[[-------------------------------------------
  Private Methods
--]]

StatFrameLeft = {
   _G["PlayerStatFrameLeft1"],
   _G["PlayerStatFrameLeft2"],
   _G["PlayerStatFrameLeft3"],
   _G["PlayerStatFrameLeft4"],
   _G["PlayerStatFrameLeft5"],
   _G["PlayerStatFrameLeft6"]
}
StatFrameRight = {
   _G["PlayerStatFrameRight1"],
   _G["PlayerStatFrameRight2"],
   _G["PlayerStatFrameRight3"],
   _G["PlayerStatFrameRight4"],
   _G["PlayerStatFrameRight5"],
   _G["PlayerStatFrameRight6"]
}

--#NODOC local
function paintLeftStatFrame(painter,obj)
   for _,line in ipairs(StatFrameLeft) do
      line:Hide()
   end
   painter(obj,StatFrameLeft[1],StatFrameLeft[2],StatFrameLeft[3],
               StatFrameLeft[4],StatFrameLeft[5],StatFrameLeft[6])
end
--#NODOC local
function paintRightStatFrame(painter, obj)
   for _, line in ipairs(StatFrameRight) do
      line:Hide()
   end
   painter(obj,StatFrameRight[1],StatFrameRight[2],StatFrameRight[3],
               StatFrameRight[4],StatFrameRight[5],StatFrameRight[6])
end
--#NODOC local
function repaintTooltips(frame,framelist)
   for _,line in ipairs(framelist) do
      if GameTooltip:IsOwned(line) then
         line:GetScript("OnEnter")(frame)
      end
   end
end
--#NODOC local
function setupLeftStatFrame(frame_setup,obj,frame_name)
   frame_setup(obj,StatFrameLeft[1],StatFrameLeft[2],StatFrameLeft[3],
                   StatFrameLeft[4],StatFrameLeft[5],StatFrameLeft[6],
                frame_name)
end
--#NODOC local
function setupRightStatFrame(frame_setup,obj,frame_name)
   frame_setup(obj,StatFrameRight[1],StatFrameRight[2],StatFrameRight[3],
                   StatFrameRight[4],StatFrameRight[5],StatFrameRight[6],
                frame_name)
end
--#NODOC local
function default_mouseovers(obj,line1,line2,line3,line4,line5,line6,frame_name)
   local painter = function(line)
                      local p = obj["Paint"..frame_name.."Line"..tostring(line).."Tooltip"]
                      if p then
                         return function(frame,_)
                                   GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
                                   p(obj)
                                   GameTooltip:Show()
                                end
                      else
                         return nil
                      end
                   end
   line1:SetScript("OnEnter",painter(1))
   line2:SetScript("OnEnter",painter(2))
   line3:SetScript("OnEnter",painter(3))
   line4:SetScript("OnEnter",painter(4))
   line5:SetScript("OnEnter",painter(5))
   line6:SetScript("OnEnter",painter(6))
end

--#NODOC local
function slurpDefaultEventHooks()
   local events = {"OnEnter","OnLeave","OnMouseUp","OnMouseDown"}
   stat_frame_left_default_hooks = {}
   for _, line in ipairs(StatFrameLeft) do
      local line_hooks = {}
      for _, event in ipairs(events) do
         line_hooks[event] = line:GetScript(event)
      end
      tinsert(stat_frame_left_default_hooks,line_hooks)
   end
   stat_frame_right_default_hooks = {}
   for _, line in ipairs(StatFrameRight) do
      local line_hooks = {}
      for _, event in ipairs(events) do
         line_hooks[event] = line:GetScript(event)
      end
      tinsert(stat_frame_right_default_hooks,line_hooks)
   end
end
--#NODOC local
-- this sets things back to Bliz-ish
function setDefaultEventHooks(frame,defaults,index)
   for i,line in ipairs(frame) do
      for event,func in pairs(defaults[i]) do
         line:SetScript(event,func)
      end
   end
   setBlizEventHooks(frame,index)
end

--#NODOC local
-- this is a copy of what PaperDollFrame.lua:function UpdatePaperdollStats
-- using ONLY the SetScript commands
function setBlizEventHooks(frame, index)
   local stat1,stat2,stat3,stat4,stat5,stat6 = unpack(frame)

   -- reset any OnEnter scripts that may have been changed
   stat1:SetScript("OnEnter", PaperDollStatTooltip);
   stat2:SetScript("OnEnter", PaperDollStatTooltip);
   stat4:SetScript("OnEnter", PaperDollStatTooltip);

   if ( index == "PLAYERSTAT_BASE_STATS" ) then
   elseif ( index == "PLAYERSTAT_MELEE_COMBAT" ) then
      stat1:SetScript("OnEnter", CharacterDamageFrame_OnEnter);
   elseif ( index == "PLAYERSTAT_RANGED_COMBAT" ) then
      stat1:SetScript("OnEnter", CharacterRangedDamageFrame_OnEnter);
   elseif ( index == "PLAYERSTAT_SPELL_COMBAT" ) then
      stat1:SetScript("OnEnter", CharacterSpellBonusDamage_OnEnter);
      stat4:SetScript("OnEnter", CharacterSpellCritChance_OnEnter);
   elseif ( index == "PLAYERSTAT_DEFENSES" ) then
   end
end

--#NODOC local
function UpdatePaperdollStatsHook(frame, index)
   local custom_paint = false
   for obj, frames in pairs(frame_indexes) do
      for frame_index,frame_name in pairs(frames) do
         if index == frame_index then
            custom_paint = true
            if "PlayerStatFrameLeft" == frame then
               frame_setup = obj["SetupFrame"..frame_name]
               if frame_setup then
                  setupLeftStatFrame(frame_setup,obj)
               else
                  setupLeftStatFrame(default_mouseovers,obj,frame_name)
               end
               paintLeftStatFrame(obj["Paint"..frame_name],obj)
            elseif "PlayerStatFrameRight" == frame then
               frame_setup = obj["SetupFrame"..frame_name]
               if frame_setup then
                  setupRightStatFrame(frame_setup,obj)
               else
                  setupRightStatFrame(default_mouseovers,obj,frame_name)
               end
               paintRightStatFrame(obj["Paint"..frame_name],obj)
            else
               error("Unknown frame to paint: %s",frame)
            end
         end
      end
   end
   if not custom_paint then
      if "PlayerStatFrameLeft" == frame then
         setDefaultEventHooks(StatFrameLeft,stat_frame_left_default_hooks,index)
      elseif "PlayerStatFrameRight" == frame then
         setDefaultEventHooks(StatFrameRight,stat_frame_right_default_hooks,index)
      end -- we don't know what to do with it so just leave it alone
   end
end

--[[--------------------------------------------
  Load/unload and debug help
--]]

--#NODOC
function StatFrameLib:StatFrameReport()
   self:Print("List of stat frames added:")
   if not next(frame_names[self]) then
      self:Print("No stat frames have been added")
   end

   for index,name in pairs(frame_indexes[self]) do
      self:Print(string.format('"%s" - "%s" (index: %s)', name, frame_names[self][name], index))
   end
end

--#NODOC
function StatFrameLib:OnInstanceInit(object)
   -- make sure AceHook is initialized before us
   -- it should be safe to call this multiple times
   --AceHook:OnInstanceInit(object)--Commented out-AB

   if not frame_names[object] then
      frame_names[object] = {}
   end
   if not frame_indexes[object] then
      frame_indexes[object] = {}
   end

   object:SecureHook("UpdatePaperdollStats",UpdatePaperdollStatsHook)
end

--#NODOC
function StatFrameLib:OnEmbedDisable(object)
   -- OnEmbedDisable needs to be in the StatFrameLib table, but it isn't
   -- called in relation to the table. Odd, but there you are.
   object:RemoveAllStatFrames()
end

-------------------------------
--#NODOC local
function activate(self, oldLib, oldDeactivate)
   StatFrameLib = self

   self.frame_names = oldLib and oldLib.frame_names or {}
   self.frame_indexes = oldLib and oldLib.frame_indexes or {}

   frame_names = self.frame_names
   frame_indexes = self.frame_indexes

   slurpDefaultEventHooks()
   self:activate(oldLib, oldDeactivate)
   if oldDeactivate then
      oldDeactivate(oldLib)
   end
end

--Not even sure i need this but...
AceLibrary:Register(StatFrameLib, MAJOR_VERSION, MINOR_VERSION, activate)
  Reply With Quote
10-24-08, 12:35 PM   #2
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
Been digging at it myself, It finally hit me where it wants Ace2 hook to use Ace3 hook, just not sure how to do it right.

Also this error with the Hacked up code i got now:Interface\FrameXML\PaperDollFrame.lua:1527: attempt to index local 'statFrame' (a nil value)
(tail call): ?
Interface\FrameXML\PaperDollFrame.lua:1527: in function `PaperDollFrame_SetLabelAndText'
...atFrameLib-2.0\StatFrameLib-2.0\StatFrameLib-2.0.lua:230: in function `StatBoxSet'
Interface\AddOns\StatFrameLib-2.0\test.lua:16: in function `PaintOverNine'
Interface\AddOns\StatFrameLib-2.0\test.lua:7: in function <Interface\AddOns\StatFrameLib-2.0\test.lua:5>
(tail call): ?

confoozing me

Last edited by Aurorablade : 10-24-08 at 12:42 PM. Reason: added error
  Reply With Quote
10-24-08, 01:18 PM   #3
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
I don't get where the 'desperation' comes from.

The statframelib library is maintained and the author has chosen to use Ace2 which is functioning just fine.

There's a few libraries (dewdrop, tablet and more) with no Ace3 equivalent and addons using a mix of Ace2/3 libraries are commonplace.

Either use the library as is (if it suits you) or make your own?

I have a feeling you just have some misconceptions about what using Ace2 entails.

You can mix and match libraries from the two "frameworks" without problems whatsoever to gain functionality that you need.
  Reply With Quote
10-24-08, 01:38 PM   #4
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
Well to me it just seems inefficient, I know the addon is maintained. I mean i am sorry for sounding newbish. But i really wasn't sure if mixing them like that wasn't taboo.
What is the proper way to put an ace2 lib in a ace3 addon then?
The same as setting it up like a normal addon or just give them diffrent name spaces?


EDit:

Okay so basically using acelib is alot like Libstub to access the lib only instead of using Libstub("lib") in the addon i use AceLibrary("Lib"), Correct?

I feel really stupid for not realizing this earlier......

Last edited by Aurorablade : 10-25-08 at 03:19 AM. Reason: Elbaorating....
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Statframelib:MAking it libstub


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off