Get an Epic Experience with Premium

NinjaPanel

Data Broker Login to Add Favorites
  • 0 Likes
  • World of Warcraft
  • 60 Monthly Downloads
  • Supports: 4.3.4
  • 8,480 Total Downloads
  • Updated 10/05/2012
  • Created 06/28/2010
  • 31 Favorites
  • Project Site
  • Comments
  • Release Type: Release
  • License: All Rights Reserved
  • Newest File: v50001-1.0.0
or
Support development! **
Donate

About NinjaPanel

What is NinjaPanel?

NinjaPanel is a simple, easy-to-configure display for LDB data objects. If you're not familiar with LDB, it's a simple standard that addon authors can use to provide information to other addons without needing to write any code specifically for them. This is helping to break the fubar/titan stronghold by providing a standard flexible enough to let any addon display the information.

Okay, so what does it do?

NinjaPanel will display any LDB plugins you have installed. Currently it displays all of them, although options are forthcoming to disable the display for certain plugins. It also can provide you quick access to addon options and other configurations via "launchers", simple icons that sit on the panel. Most addons that provide minimap icons (which we all hate) also provide launchers. All plugins can be dragged around the panel to re-order them, so they're displayed exactly as you'd like them to be.

Where are the options?

There aren't currently many configuration options for this addon other than the ability to enable or disable specific plugins, but I wanted to get a release out to get some feedback from the community. You can expect the following options to be implemented at some point:

  • Display the panel on the top, bottom, left or right of the screen
  • Change the height/width of the panel
  • Customize data objects to hide the icon, text, etc.

So where do I get plugins?

You may be surprised at how many addons already provide some sort of LDB data object, but if you're looking for new ones to try out you can check the category listings at your favorite addon site:

How did you manage to get TomTom Crazy Arrow in the panel

NinjaPanel introduces support for icon colors and coordinates using the following fields in the LDB data object:

iconR - The red component value of the color
iconG - The green component value of the color
iconB - The blue component value of the color
iconCoords - A table containing the texCoords to be set on the icon

I will soon expand iconCoords to support the 8-value version, as well as iconRotate to support arbitrary rotations using the new API.

These features are used in the latest version of TomTom to allow you to display the crazy arrow in NinjaPanel.

Anything else?

Please feed free to leave any suggestions or feedback! I'm interested to see what the community would like to see in a panel addon that I can easily provide.

Thanks for using my addons!

Donations:
Some people have asked, so here is a way to send me donations:

https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif

tag v50001-1.0.0
4e8ed7d88783045c7449eb6b0c941c9fb0baf847
James Whitehead II <jnwhiteh@gmail.com>
2012-10-05 10:07:28 +0200

Tagging v50001-1.0.0

--------------------

James Whitehead II:
    - Update LibJostle

Addon Packs Containing This...

Comments

  • #8

    Updated with a new version of jostle.

  • #9

    Thank you, thank you, thank you, thank you, thank you, thank you

  • #5

    5.0.4 fix for ninjapanel

    Libjostle-3.0 causing hangs for druids.

    code: replace current libjostle-3.0 with this one:

    code:

    --[[ Name: LibJostle-3.0 Revision: $Rev: 55 $ Author(s): ckknight (ckknight@gmail.com) Website: http://ckknight.wowinterface.com/ Documentation: http://www.wowace.com/addons/libjostle-3-0/ SVN: svn://svn.wowace.com/wow/libjostle-3-0/mainline/trunk Description: A library to handle rearrangement of blizzards frames when bars are added to the sides of the screen. License: LGPL v2.1 --]]

    local MAJOR_VERSION = "LibJostle-3.0" local MINOR_VERSION = tonumber(("$Revision: 55 $"):match("(%d+)")) + 90000

    if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end

    local oldLib = LibStub:GetLibrary(MAJOR_VERSION, true) local Jostle = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) if not Jostle then  return end

    local blizzardFrames = {  'PlayerFrame',  'TargetFrame',  'MinimapCluster',  'PartyMemberFrame1',  'TicketStatusFrame',  'WorldStateAlwaysUpFrame',  'MainMenuBar',  'MultiBarRight',  'CT_PlayerFrame_Drag',  'CT_TargetFrame_Drag',  'Gypsy_PlayerFrameCapsule',  'Gypsy_TargetFrameCapsule',  'ConsolidatedBuffs',  'BuffFrame',  'DEFAULT_CHAT_FRAME',  'ChatFrame2',  'GroupLootFrame1',  'TutorialFrameParent',  'FramerateLabel',  'DurabilityFrame',  'CastingBarFrame', } local blizzardFramesData = {}

    local _G = _G

    Jostle.hooks = oldLib and oldLib.hooks or {} Jostle.topFrames = oldLib and oldLib.topFrames or {} Jostle.bottomFrames = oldLib and oldLib.bottomFrames or {} Jostle.topAdjust = oldLib and oldLib.topAdjust Jostle.bottomAdjust = oldLib and oldLib.bottomAdjust if Jostle.topAdjust == nil then  Jostle.topAdjust = true end if Jostle.bottomAdjust == nil then  Jostle.bottomAdjust = true end

    if not Jostle.hooks.WorldMapFrame_Hide then  Jostle.hooks.WorldMapFrame_Hide = true  hooksecurefunc(WorldMapFrame, "Hide", function()   if Jostle.WorldMapFrame_Hide then    Jostle:WorldMapFrame_Hide()   end  end) end

    if not Jostle.hooks.TicketStatusFrame_OnEvent then  Jostle.hooks.TicketStatusFrame_OnEvent = true  hooksecurefunc("TicketStatusFrame_OnEvent", function()   if Jostle.TicketStatusFrame_OnEvent then    Jostle:TicketStatusFrame_OnEvent()   end  end) end

    if not Jostle.hooks.FCF_UpdateDockPosition then  Jostle.hooks.FCF_UpdateDockPosition = true  hooksecurefunc("FCF_UpdateDockPosition", function()   if Jostle.FCF_UpdateDockPosition then    Jostle:FCF_UpdateDockPosition()   end  end) end   if FCF_UpdateCombatLogPosition and not Jostle.hooks.FCF_UpdateCombatLogPosition then  Jostle.hooks.FCF_UpdateCombatLogPosition = true  hooksecurefunc("FCF_UpdateCombatLogPosition", function()   if Jostle.FCF_UpdateCombatLogPosition then    Jostle:FCF_UpdateCombatLogPosition()   end  end) end

    if not Jostle.hooks.UIParent_ManageFramePositions then  Jostle.hooks.UIParent_ManageFramePositions = true  hooksecurefunc("UIParent_ManageFramePositions", function()   if Jostle.UIParent_ManageFramePositions then    Jostle:UIParent_ManageFramePositions()   end  end) end

    if not Jostle.hooks.PlayerFrame_SequenceFinished then  Jostle.hooks.PlayerFrame_SequenceFinished = true  hooksecurefunc("PlayerFrame_SequenceFinished", function()   if Jostle.PlayerFrame_SequenceFinished then    Jostle:PlayerFrame_SequenceFinished()   end  end) end

    Jostle.frame = oldLib and oldLib.frame or CreateFrame("Frame") local JostleFrame = Jostle.frame local start = GetTime() local nextTime = 0 local fullyInitted = false JostleFrame:SetScript("OnUpdate", function(this, elapsed)  local now = GetTime()  if now - start >= 3 then   fullyInitted = true   for k,v in pairs(blizzardFramesData) do    blizzardFramesData[k] = nil   end   this:SetScript("OnUpdate", function(this, elapsed)    if GetTime() >= nextTime then     Jostle:Refresh()     this:Hide()    end   end)  end end) function JostleFrame:Schedule(time)  time = time or 0  nextTime = GetTime() + time  self:Show() end JostleFrame:UnregisterAllEvents() JostleFrame:SetScript("OnEvent", function(this, event, ...)  return Jostle[event](Jostle, ...) end) JostleFrame:RegisterEvent("PLAYER_AURAS_CHANGED") JostleFrame:RegisterEvent("PLAYER_REGEN_DISABLED") JostleFrame:RegisterEvent("PLAYER_REGEN_ENABLED") JostleFrame:RegisterEvent("PLAYER_CONTROL_GAINED")

    function Jostle:PLAYER_AURAS_CHANGED()  JostleFrame:Schedule() end

    function Jostle:WorldMapFrame_Hide()  JostleFrame:Schedule() end

    function Jostle:TicketStatusFrame_OnEvent()  self:Refresh(TicketStatusFrame, ConsolidatedBuffs) end

    function Jostle:FCF_UpdateDockPosition()  self:Refresh(DEFAULT_CHAT_FRAME) end

    function Jostle:FCF_UpdateCombatLogPosition()  self:Refresh(ChatFrame2) end

    function Jostle:UIParent_ManageFramePositions()  self:Refresh(GroupLootFrame1, TutorialFrameParent, FramerateLabel, DurabilityFrame) end

    function Jostle:PlayerFrame_SequenceFinished()  self:Refresh(PlayerFrame) end

    function Jostle:GetScreenTop()  local bottom = GetScreenHeight()  for _,frame in ipairs(self.topFrames) do   if frame.IsShown and frame:IsShown() and frame.GetBottom and frame:GetBottom() and frame:GetBottom() < bottom then    bottom = frame:GetBottom()   end  end  return bottom end

    function Jostle:GetScreenBottom()  local top = 0  for _,frame in ipairs(self.bottomFrames) do   if frame.IsShown and frame:IsShown() and frame.GetTop and frame:GetTop() and frame:GetTop() > top then    top = frame:GetTop()   end  end  return top end

    function Jostle:RegisterTop(frame)  for k,f in ipairs(self.bottomFrames) do   if f == frame then    table.remove(self.bottomFrames, k)    break   end  end  for _,f in ipairs(self.topFrames) do   if f == frame then    return   end  end  table.insert(self.topFrames, frame)  JostleFrame:Schedule()  return true end

    function Jostle:RegisterBottom(frame)  for k,f in ipairs(self.topFrames) do   if f == frame then    table.remove(self.topFrames, k)    break   end  end  for _,f in ipairs(self.bottomFrames) do   if f == frame then    return   end  end  table.insert(self.bottomFrames, frame)  JostleFrame:Schedule()  return true end

    function Jostle:Unregister(frame)  for k,f in ipairs(self.topFrames) do   if f == frame then    table.remove(self.topFrames, k)    JostleFrame:Schedule()    return true   end  end  for k,f in ipairs(self.bottomFrames) do   if f == frame then    table.remove(self.bottomFrames, k)    JostleFrame:Schedule()    return true   end  end end

    function Jostle:IsTopAdjusting()  return self.topAdjust end

    function Jostle:EnableTopAdjusting()  if not self.topAdjust then   self.topAdjust = not self.topAdjust   JostleFrame:Schedule()  end end

    function Jostle:DisableTopAdjusting()  if self.topAdjust then   self.topAdjust = not self.topAdjust   JostleFrame:Schedule()  end end

    function Jostle:IsBottomAdjusting()  return self.bottomAdjust end

    function Jostle:EnableBottomAdjusting()  if not self.bottomAdjust then   self.bottomAdjust = not self.bottomAdjust   JostleFrame:Schedule()  end end

    function Jostle:DisableBottomAdjusting()  if self.bottomAdjust then   self.bottomAdjust = not self.bottomAdjust   JostleFrame:Schedule()  end end

    local tmp = {} local queue = {} local inCombat = false function Jostle:ProcessQueue()  if not inCombat and HasFullControl() then   for k in pairs(queue) do    self:Refresh(k)    queue[k] = nil   end  end end function Jostle:PLAYER_CONTROL_GAINED()  self:ProcessQueue() end

    function Jostle:PLAYER_REGEN_ENABLED()  inCombat = false  self:ProcessQueue() end

    function Jostle:PLAYER_REGEN_DISABLED()  inCombat = true end

    local function isClose(alpha, bravo)  return math.abs(alpha - bravo) < 0.1 end

    function Jostle:Refresh(...)  if not fullyInitted then   return  end    local screenHeight = GetScreenHeight()  local topOffset = self:IsTopAdjusting() and self:GetScreenTop() or screenHeight  local bottomOffset = self:IsBottomAdjusting() and self:GetScreenBottom() or 0  if topOffset ~= screenHeight or bottomOffset ~= 0 then   JostleFrame:Schedule(10)  end    local frames  if select('#', ...) >= 1 then   for k in pairs(tmp) do    tmp[k] = nil   end   for i = 1, select('#', ...) do    tmp[i] = select(i, ...)   end   frames = tmp  else   frames = blizzardFrames  end

     if inCombat or not HasFullControl() and not UnitHasVehicleUI("player") then   for _,frame in ipairs(frames) do    if type(frame) == "string" then     frame = _G[frame]    end    if frame then     queue[frame] = true    end   end   return  end    local screenHeight = GetScreenHeight()  for _,frame in ipairs(frames) do   if type(frame) == "string" then    frame = _G[frame]   end

      local framescale = frame and frame.GetScale and frame:GetScale() or 1

      if frame and not blizzardFramesData[frame] and frame.GetTop and frame:GetCenter() and select(2, frame:GetCenter()) then    if select(2, frame:GetCenter()) <= screenHeight / 2 or frame == MultiBarRight then     blizzardFramesData[frame] = {y = frame:GetBottom(), top = false}    else     blizzardFramesData[frame] = {y = frame:GetTop() - screenHeight / framescale, top = true}    end    if frame == MinimapCluster then     blizzardFramesData[frame].lastX = GetScreenWidth() - MinimapCluster:GetWidth()     blizzardFramesData[frame].lastY = GetScreenHeight()     blizzardFramesData[frame].lastScale = 1    end   end  end    for _,frame in ipairs(frames) do   if type(frame) == "string" then    frame = _G[frame]   end

      local framescale = frame and frame.GetScale and frame:GetScale() or 1

      if ((frame and frame.IsUserPlaced and not frame:IsUserPlaced()) or ((frame == DEFAULT_CHAT_FRAME or frame == ChatFrame2) and SIMPLE_CHAT == "1") or frame == FramerateLabel) and (frame ~= ChatFrame2 or SIMPLE_CHAT == "1") then    local frameData = blizzardFramesData[frame]    if (select(2, frame:GetPoint(1)) ~= UIParent and select(2, frame:GetPoint(1)) ~= WorldFrame) then     -- do nothing    elseif frame == PlayerFrame and (CT_PlayerFrame_Drag or Gypsy_PlayerFrameCapsule) then     -- do nothing    elseif frame == TargetFrame and (CT_TargetFrame_Drag or Gypsy_TargetFrameCapsule) then     -- do nothing    elseif frame == PartyMemberFrame1 and (CT_MovableParty1_Drag or Gypsy_PartyFrameCapsule) then     -- do nothing    elseif frame == MainMenuBar and Gypsy_HotBarCapsule then     -- do nothing    elseif frame == MinimapCluster and select(3, frame:GetPoint(1)) ~= "TOPRIGHT" then     -- do nothing    elseif frame == DurabilityFrame and DurabilityFrame:IsShown() and (DurabilityFrame:GetLeft() > GetScreenWidth() or DurabilityFrame:GetRight() < 0 or DurabilityFrame:GetBottom() > GetScreenHeight() or DurabilityFrame:GetTop() < 0) then     DurabilityFrame:Hide()    elseif frame == FramerateLabel and ((frameData.lastX and not isClose(frameData.lastX, frame:GetLeft())) or not isClose(WorldFrame:GetHeight() * WorldFrame:GetScale(), UIParent:GetHeight() * UIParent:GetScale()))  then     -- do nothing    elseif frame == PlayerFrame or frame == MainMenuBar or frame == ConsolidatedBuffs or frame == CastingBarFrame or frame == TutorialFrameParent or frame == FramerateLabel or frame == DurabilityFrame or frame == WatchFrame or not (frameData.lastScale and frame.GetScale and frameData.lastScale == frame:GetScale()) or not (frameData.lastX and frameData.lastY and (not isClose(frameData.lastX, frame:GetLeft()) or not isClose(frameData.lastY, frame:GetTop()))) then     local anchor     local anchorAlt     local width, height = GetScreenWidth(), GetScreenHeight()     local x

        if frame:GetRight() and frame:GetLeft() then      local anchorFrame = UIParent      if frame == MainMenuBar or frame == GroupLootFrame1 or frame == FramerateLabel then       x = 0       anchor = ""      elseif frame:GetRight() / framescale <= width / 2 then       x = frame:GetLeft() / framescale       anchor = "LEFT"      else       x = frame:GetRight() - width / framescale       anchor = "RIGHT"      end      local y = blizzardFramesData[frame].y      local offset = 0      if blizzardFramesData[frame].top then       anchor = "TOP" .. anchor       offset = ( topOffset - height ) / framescale      else       anchor = "BOTTOM" .. anchor       offset = bottomOffset / framescale      end      if frame == MinimapCluster and not MinimapBorderTop:IsShown() then       offset = offset + MinimapBorderTop:GetHeight() * 3/5      elseif frame == ConsolidatedBuffs and TicketStatusFrame:IsShown() then       offset = offset - TicketStatusFrame:GetHeight() * TicketStatusFrame:GetScale()      elseif frame == DEFAULT_CHAT_FRAME then       y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 32       if ShapeshiftBarFrame and (PetActionBarFrame:IsShown() or ShapeshiftBarFrame:IsShown()) then        offset = offset + ShapeshiftBarFrame:GetHeight() * ShapeshiftBarFrame:GetScale()       end       if MultiBarBottomLeft:IsShown() then        offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale() - 21       end      elseif frame == ChatFrame2 then       y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 32       if MultiBarBottomRight:IsShown() then        offset = offset + MultiBarBottomRight:GetHeight() * MultiBarBottomRight:GetScale() - 21       end      elseif frame == CastingBarFrame then       y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 17       if ShapeshiftBarFrame and (PetActionBarFrame:IsShown() or ShapeshiftBarFrame:IsShown()) then        offset = offset + ShapeshiftBarFrame:GetHeight() * ShapeshiftBarFrame:GetScale()       end       if MultiBarBottomLeft:IsShown() or MultiBarBottomRight:IsShown() then        offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale()       end      elseif frame == GroupLootFrame1 or frame == TutorialFrameParent or frame == FramerateLabel then       if MultiBarBottomLeft:IsShown() or MultiBarBottomRight:IsShown() then        offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale()       end      elseif frame == DurabilityFrame or frame == WatchFrame then       anchorFrame = MinimapCluster       x = 0       y = 0       offset = 0       if frame == WatchFrame and DurabilityFrame:IsShown() then        y = y - DurabilityFrame:GetHeight() * DurabilityFrame:GetScale()       end       if frame == DurabilityFrame then        x = -20       end       anchor = "TOPRIGHT"       anchorAlt = "BOTTOMRIGHT"       if MultiBarRight:IsShown() then        x = x - MultiBarRight:GetWidth() * MultiBarRight:GetScale()        if MultiBarLeft:IsShown() then         x = x - MultiBarLeft:GetWidth() * MultiBarLeft:GetScale()        end       end      end      if frame == FramerateLabel then       anchorFrame = WorldFrame      end      frame:ClearAllPoints()      frame:SetPoint(anchor, anchorFrame, anchorAlt or anchor, x, y + offset)      blizzardFramesData[frame].lastX = frame:GetLeft()      blizzardFramesData[frame].lastY = frame:GetTop()      blizzardFramesData[frame].lastScale = framescale     end    end   end  end end

    local function compat()  local Jostle20 = {}  function Jostle20:RegisterTop(...)   Jostle:RegisterTop(...)  end  function Jostle20:RegisterBottom(...)   Jostle:RegisterBottom(...)  end  function Jostle20:GetScreenTop(...)   Jostle:GetScreenTop(...)  end  function Jostle20:GetScreenBottom(...)   Jostle:GetScreenBottom(...)  end  function Jostle20:Unregister(...)   Jostle:Unregister(...)  end  function Jostle20:IsTopAdjusting(...)   Jostle:IsTopAdjusting(...)  end  function Jostle20:EnableTopAdjusting(...)   Jostle:EnableTopAdjusting(...)  end  function Jostle20:DisableTopAdjusting(...)   Jostle:DisableTopAdjusting(...)  end  function Jostle20:IsBottomAdjusting(...)   Jostle:IsBottomAdjusting(...)  end  function Jostle20:EnableBottomAdjusting(...)   Jostle:EnableBottomAdjusting(...)  end  function Jostle20:DisableBottomAdjusting(...)   Jostle:DisableBottomAdjusting(...)  end  function Jostle20:Refresh(...)   Jostle:Refresh(...)  end  local function activate(self, oldLib)   Jostle20 = self   if oldLib and oldLib.topFrames and oldLib.bottomFrames then    for i,v in ipairs(oldLib.topFrames) do     Jostle:RegisterTop(v)    end    for i,v in ipairs(oldLib.bottomFrames) do     Jostle:RegisterBottom(v)    end   end  end  local function external(self, instance, major)   if major == "AceEvent-2.0" then    instance:embed(self)

       self:UnregisterAllEvents()    self:CancelAllScheduledEvents()   end  end  AceLibrary:Register(Jostle20, "Jostle-2.0", MINOR_VERSION*1000, activate, external)  Jostle20 = AceLibrary("Jostle-2.0") end if AceLibrary then  compat() elseif Rock then  function Jostle:OnLibraryLoad(major, version)   if major == "AceLibrary" then    compat()   end  end end

     

    Tnx to autor of guild-xp-bar for fix.

  • #6

    Could you upload that, as a "fan fix" file or the whole thing - as a "fan update"?
    You give thanks to someone else at the bottom so, if there is a working update of this addon somewhere, could you please link to it?
    Thanks.

  • #7

    No he can't. I'll do something to get a workign version up, but fan updates of my addons are not allowed.

    This is not a 'fix' this is a hack. That's why I haven't done an official release yet.

  • #2
    I would use this as my Fubar replacement starting now but you really need to to make the bar at least resizable so it can be shortened and moved. Taking up the entire top line of the screen for a few addon buttons is major overkill. Maybe you could have three set bar configs: the current one, and a half length bar that can be positioned on the left side or the right side of the screen. Otherwise, I really like it!
  • #3
    I would like to add some more positioning options in the future, but I dont' anticipate having an opportunity to do this anytime soon. You can do the things you would like to do with other broker displays such as Bazooka, so I'd suggest using one of them.
  • #4
    Thanks, I'll try bazooka.
  • #1
    I like it.
  • To post a comment, please login or register a new account.
Login to Curse

Don't have an account? Create One.

Get an epic experience with Curse Premium
  • Faster addon downloads
  • Premium-Only Beta Giveaways
  • Ad-Free Curse experience
  • Premium Curse Client
  • and many More Features
  • Learn More »

Infinite Crisis NA

Get Your Preferred Access Code!