Quantcast
WoWInterface: SVN - SoopUI - Path Comparison - / Rev 7 and / Rev 6

WoWInterface SVN SoopUI

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 6
    Reverse comparison

Rev 7 → Rev 6

trunk/SoopUI 3.0 beta 1/SoopUI/Core/Driver.lua New file
0,0 → 1,19
----------------------------------
-- Communication between all parts of SoopUI
----------------------------------
 
-- Includes
local addon, driver = ...
driver[1] = {} -- S, functions, constants
driver[2] = {} -- C, config
driver[3] = {} -- Soop, database, post config load
 
SoopUI = driver -- Allow other addons to use Driver
 
--[[
This should be at the top of every file inside of the SoopUI AddOn:
local S, C, Soop = unpack(select(2, ...))
-----------------------------------------------------------------------
This is how another addon imports the SoopUI driver:
local S, C, Soop = unpack(SoopUI)
]]
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Core/Config.lua New file
0,0 → 1,31
----------------------------------------------------------------------------
-- This loads new user defaults every time a new user is detected
----------------------------------------------------------------------------
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function C - config Soop - Database
 
--Convert default database
for group,options in pairs(Soop) do
if not C[group] then C[group] = {} end
for option, value in pairs(options) do
C[group][option] = value
end
end
 
if IsAddOnLoaded("SoopUI_Config") then
local SoopUIConfig = LibStub("AceAddon-3.0"):GetAddon("SoopUIConfig")
SoopUIConfig:Load()
 
--Load settings from SoopUIConfig database
for group, options in pairs(SoopUIConfig.db.profile) do
if C[group] then
for option, value in pairs(options) do
C[group][option] = value
end
end
end
 
S.SavePath = SoopUIConfig.db.profile
end
 
 
 
trunk/SoopUI 3.0 beta 1/SoopUI/Core/Defaults.lua New file
0,0 → 1,201
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
-- CVars
local function SetDefaultCVars()
-- Graphics
if GetCVar("gxMultisample") ~= "1" then
SetCVar("gxMultisample", 1)
RestartGx()
end
-- Sound
SetCVar("Sound_EnableErrorSpeech", 0)
-- Nameplates
SetCVar("bloatTest", 0)
SetCVar("bloatnameplates", 0)
SetCVar("bloatthreat", 0)
-- Screenshots
SetCVar("screenshotFormat", "jpg") -- JPG format
SetCVar("screenshotQuality", "10") -- Highest quality
-- Help
SetCVar("showGameTips", 0) -- Turn off Loading Screen Tips
SetCVar("showTutorials", 0) -- Turn off Tutorials
SetCVar("UberTooltips", 1) -- Turn on Enhanced Tooltips
SetCVar("scriptErrors", 1) -- Turn on Display Lua Errors
-- Controls
SetCVar("deselectOnClick", 1) -- Turn off Sticky Targeting (inverted)
-- Combat
SetCVar("displaySpellActivationOverlays", 1) -- Turn on Spell Alerts
SetCVar("spellActivationOverlayOpacity", 0.75) -- Spell Alert Opacity
-- Display
SetCVar("emphasizeMySpellEffects", 0) -- Turn off Emphasize My Spell Effects
SetCVar("SpellTooltip_DisplayAvgValues", 0) -- Turn off Display Points As Average
-- Social
SetCVar("chatBubbles", 0) -- Turn off Chat Bubbles
SetCVar("chatBubblesParty", 0) -- Turn off Party Chat Bubbles
SetCVar("chatStyle", "classic") -- Chat Style = "Classic"
SetCVar("conversationMode", "inline") -- Conversation Mode = "In-line"
-- Quests
SetCVar("autoQuestWatch", 1) -- Auto Track Quests
SetCVar("mapQuestDifficulty", 1) -- Color Quests by Difficulty on World Map
-- Names
SetCVar("UnitNameNPC", 1) -- Turn on NPC Names
SetCVar("UnitNamePlayerPVPTitle", 0) -- Turn off PvP Player Titles
SetCVar("UnitNameEnemyGuardianName", 1) -- Turn on Enemy Pet Names
SetCVar("UnitNameEnemyTotemName", 1) -- Turn on Enemy Totem Names
SetCVar("nameplateMotion", 1) -- Stacking Nameplates
-- Camera
SetCVar("cameraYawSmoothSpeed", 210)
SetCVar("cameraView", 1) -- Camera Stlye
SetCVar("cameraDistanceMax", 50) -- Camera Max Distance
SetCVar("cameraDistanceMaxFactor", 3) -- Camera Follow Speed
-- Quality of Life
SetCVar("guildShowOffline", 0) -- Hide Offline Guild Members
SetCVar("profanityFilter", 0) -- Turn off Profanity Filter
end
--------------------------------------------------------------
-- SoopUI Media Options
--------------------------------------------------------------
Soop ["media"] = {
["font"] = "Express",
["fontSize"] = 14,
["fontxSmall"] = 10,
["fontSmall"] = 12,
["fontMedium"] = 14,
["fontLarge"] = 16,
["fontHuge"] = 20,
}
 
--------------------------------------------------------------
-- General Options
--------------------------------------------------------------
Soop ["general"] = {
["color"] = { r = 1, g = 1, b = 1},
["classcolor"] = true,
["autogreed"] = true,
["Interrupts"] = true,
}
 
---------------------
-- Datatext Options
---------------------
Soop ["datatext"] = {
["enable"] = true,
["border"] = "border",
["background"] = "Blizzard Dialog Background",
["top"] = false, -- if = true then panel on top of screen, if = false panel below mainmenubar
["fontsize"] = 11, -- font size for panels.
["system"] = 5, -- show total memory and others systems info (FPS/MS) on panel.
["wowtime"] = 3, -- show time on panel.
["guild"] = 2, -- show number on guildmate connected on panel.
["dur"] = 8, -- show your equipment durability on panel.
["friends"] = 1, -- show number of friends connected.
 
["spec"] = 6, -- show your current spec on panel.
["zone"] = 0, -- show your current zone on panel.
["coords"] = 0, -- show your current coords on panel.
["pro"] = 0, -- shows your professions and tradeskills
["stat1"] = 0, -- Stat Based on your Role (Avoidance-Tank, AP-Melee, SP/HP-Caster)
["stat2"] = 0, -- Stat Based on your Role (Armor-Tank, Crit-Melee, Crit-Caster)
["calltoarms"] = 0, -- Show Current Call to Arms.
 
-- Color Datatext
["colors"] = {
["color"] = { r = 0, g = 0, b = 1}, -- datatext color if classcolor = false
},
 
["battleground"] = true, -- enable 3 stats in battleground only that replace stat1,stat2,stat3.
 
 
 
-- Clock Settings
["time24"] = false, -- set time to 24h format.
["localtime"] = true, -- set time to local time instead of server time.
 
-- FPS Settings
["fps"] = {
["enable"] = true, -- enable the FPS on the System Tooltip
-- ONLY ONE OF THESE CAN BE TRUE
["home"] = false, -- Only Show Home Latency
["world"] = false, -- Only Show World Latency
["both"] = true, -- Show both Home and World Latency
},
 
 
}
 
--------------------------------------------------------------
-- Merchant Options
-- Merchant provides the auto-sell and repair functions
--------------------------------------------------------------
 
Soop ["merchant"] = {
["enable"] = true, -- enable merchant module.
["sellMisc"] = true, -- allows the user to add specific items to sell at merchant (please see the local filter in merchant.lua)
["autoSellGrey"] = true, -- Allow grey items to be sold
["autoRepair"] = true, -- Should we auto-repair?
}
 
--------------------------------------------------------------
-- Minimap Options
--------------------------------------------------------------
Soop ["minimap"] = {
["enable"] = true,
["border"] = "fer09",
["gameclock"] = true,
["farm"] = false,
["farmscale"] = 3,
["zoneText"] = true,
["instanceDifficulty"] = false,
}
 
--------------------------------------------------------------
-- Quest Options (Autocomplete/Turn in)
--------------------------------------------------------------
Soop["quest"] = {
["enable"] = true, -- enable quest module.
["autocomplete"] = false, -- enable the autoaccept quest and autocomplete quest if no reward.
}
 
-------------------
-- Tooltip Options
-------------------
Soop["tooltip"] = {
["enable"] = true, -- Move the tooltip up so its not overlapping the MainMenubar
["fontSize"] = 14,
["fontOutline"] = true,
["disableFade"] = false, -- Can cause errors or a buggy tooltip!
["border"] = "Blizzard Tooltip",
["background"] = "Black",
["statusbar"] = "Blizzard",
["reactionBorderColor"] = true,
["itemqualityBorderColor"] = true,
 
["showPlayerTitles"] = true,
["showPVPIcons"] = false, -- Show pvp icons instead of just a prefix
["abbrevRealmNames"] = false,
["showMouseoverTarget"] = true,
["showOnMouseover"] = false,
["showUnitRole"] = true,
["showItemLevel"] = true,
["showSpecializationIcon"] = false,
 
 
["showItemLevel"] = true,
 
["healthbar"] = {
["showHealthValue"] = true,
["showOutline"] = false,
["healthFormat"] = '$cur / $max', -- Possible: $cur, $max, $deficit, $perc, $smartperc, $smartcolorperc, $colorperc
["healthFullFormat"] = '$cur', -- if the tooltip unit has 100% hp
["textPos"] = "CENTER", -- Possible "TOP" "BOTTOM" "CENTER"
["reactionColoring"] = false,
["customColorapply"] = false,
["custom"] = {
["apply"] = false,
["color"] = { r = 1, g = 1, b = 0},
},
["fontSize"] = 14,
},
}
 
 
trunk/SoopUI 3.0 beta 1/SoopUI/Core/Core.lua New file
0,0 → 1,265
local S, C, Soop = unpack(select(2, ...)) -- Import driver || S = Functions || C = Config || Soop = Database
 
local L = setmetatable({}, { __index = function(t,k)
local v = tostring(k)
rawset(t, k, v)
return v
end })
 
--------------------------------------------------------------
-- Constants
-- m = scaling by resolution
--------------------------------------------------------------
local m = 768/string.match(GetCVar("gxResolution"), "%d+x(%d+)")/min(2, max(.64, 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)")));
 
S.scale = function(v) return m * floor(v/m+.5) end;
S.dummy = function() return end
S.toc = select(4, GetBuildInfo())
S.myname, _ = UnitName("player")
S.myrealm = GetRealmName()
_, S.myclass = UnitClass("player")
S.version = "3.0.0 Alpha 1"
S.patch = GetBuildInfo()
S.level = UnitLevel("player")
S.locale = GetLocale()
--- Resolution scaling
S.resolution = GetCurrentResolution()
S.getscreenresolution = select(S.resolution, GetScreenResolutions())
S.getscreenheight = tonumber(string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
S.getscreenwidth = tonumber(string.match(({GetScreenResolutions()})[GetCurrentResolution()], "(%d+)x+%d"))
-- Class coloring
S.ccolor = RAID_CLASS_COLORS[select(2, UnitClass("player"))]
-- Screen areas defined
S.regions ={['TOPLEFT'] = L['TOPLEFT'], ['TOP'] = L['TOP'], ['TOPRIGHT'] = L['TOPRIGHT'], ['LEFT'] = L['LEFT'], ['CENTER'] = L['CENTER'], ['RIGHT'] = L['RIGHT'], ['BOTTOMLEFT'] = L['BOTTOMLEFT'], ['BOTTOM'] = L['BOTTOM'], ['BOTTOMRIGHT'] = L['BOTTOMRIGHT']}
S.border = {['Blizzard'] = L['Blizzard'], ['SoopUI'] = L['SoopUI']}
S.mapshape = {['SQUARE'] = L['SQUARE'], ['ROUND'] = L['ROUND']}
 
 
 
--[[ Class Role Key
 
-- DEATHKNIGHT = [1] = "Tank", [2] = "Melee", [3] = "Melee"
-- DRUID = [1] = "Caster", [2] = "Melee", [3] = "Tank", [4] = "Caster"
-- HUNTER = "Melee"
-- MAGE = "Caster"
-- MONK = [1] = "Tank", [2] = "Caster", [3] = "Melee"
-- PALADIN = [1] = "Caster", [2] = "Tank", [3] = "Melee"
-- PRIEST = "Caster"
-- ROGUE = "Melee"
-- SHAMAN = [1] = "Caster", [2] = "Melee", [3] = "Caster"
-- WARRIOR = [1] = "Melee", [2] = "Melee", [3] = "Tank"
-- WARLOCK = "Caster"
--]]
 
 
--------------------------------------------------------------
-- Check player roles
--------------------------------------------------------------
local RoleUpdater = CreateFrame("Frame")
local function CheckRole(self, event, unit)
local tree = GetSpecialization()
local resilience
local resilperc = GetCombatRatingBonus(COMBAT_RATING_RESILIENCE_PLAYER_DAMAGE_TAKEN)
if resilperc > GetDodgeChance() and resilperc > GetParryChance() then
resilience = true
else
resilience = false
end
if ((S.myclass == "PALADIN" and tree == 2) or
(S.myclass == "WARRIOR" and tree == 3) or
(S.myclass == "DEATHKNIGHT" and tree == 1) or
(S.myclass == "MONK" and tree == 1)) and
resilience == false or
(S.myclass == "DRUID" and tree == 2 and GetBonusBarOffset() == 3) then
S.Role = "Tank"
else
local playerint = select(2, UnitStat("player", 4))
local playeragi = select(2, UnitStat("player", 2))
local base, posBuff, negBuff = UnitAttackPower("player");
local playerap = base + posBuff + negBuff;
 
if (((playerap > playerint) or (playeragi > playerint)) and not (S.myclass == "DRUID" and tree ~= 1 and tree ~= 3 and tree ~= 4) or (S.myclass == "SHAMAN" and tree ~= 1 and tree ~= 3) or (S.myclass == "MONK" and tree ~= 1 and tree ~= 2) or (S.myclass == "PALADIN" and tree ~= 1 and tree ~= 3) or S.myclass == "ROGUE" or S.myclass == "HUNTER") then
S.Role = "Melee"
else
S.Role = "Caster"
end
end
end
RoleUpdater:RegisterEvent("PLAYER_ENTERING_WORLD")
RoleUpdater:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
RoleUpdater:RegisterEvent("PLAYER_TALENT_UPDATE")
RoleUpdater:RegisterEvent("CHARACTER_POINTS_CHANGED")
RoleUpdater:RegisterEvent("UNIT_INVENTORY_CHANGED")
RoleUpdater:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
RoleUpdater:SetScript("OnEvent", CheckRole)
CheckRole()
 
S.SetFontString = function(parent, fontName, fontHeight, fontStyle)
local fs = parent:CreateFontString(nil, 'OVERLAY')
fs:SetFont(fontName, fontHeight, fontStyle)
fs:SetJustifyH('LEFT')
fs:SetShadowColor(0, 0, 0)
fs:SetShadowOffset(1.25, -1.25)
return fs
end
 
--------------------------------------------------------------
-- Message on Login
--------------------------------------------------------------
local EventFrame = CreateFrame("Frame")
EventFrame:RegisterEvent("PLAYER_LOGIN")
EventFrame:SetScript("OnEvent", function(self,event,...)
if type(SoopDBPerCharacter) ~= "number" then -- Saved variable SoopDBPerCharacter =
SoopDBPerCharacter = 1
ChatFrame1:AddMessage("This appears to be the first time you've loaded |cff00B4FFSoopUI|r . You must install before you begin playing. Thanks for choosing |cff00B4FFSoopUI v"..S.version..'|r.')
else
if SoopDBPerCharacter == 1 then
ChatFrame1:AddMessage('Welcome back '.. UnitName("Player")..". You're using |cff00B4FFSoopUI v"..S.version..'|r.')
else
ChatFrame1:AddMessage('Welcome back '.. UnitName("Player")..". You're using |cff00B4FFSoopUI v"..S.version..'|r.')
end
SoopDBPerCharacter = SoopDBPerCharacter + 1
end
end)
 
--------------------------------------------------------------
-- RBG to hex conversion
--------------------------------------------------------------
function S.RGBToHex(r, g, b)
r = r <= 1 and r >= 0 and r or 0
g = g <= 1 and g >= 0 and g or 0
b = b <= 1 and b >= 0 and b or 0
return string.format("|cff%02x%02x%02x", r*255, g*255, b*255)
end
 
--------------------------------------------------------------
-- Hex to RBG conversion
--------------------------------------------------------------
function S.HexToRGB(hex)
local rhex, ghex, bhex = string.sub(hex, 1, 2), string.sub(hex, 3, 4), string.sub(hex, 5, 6)
return tonumber(rhex, 16), tonumber(ghex, 16), tonumber(bhex, 16)
end
 
function S.ShortValue(v)
if v >= 1e6 then
return ("%.1fm"):format(v / 1e6):gsub("%.?0+([km])$", "%1")
elseif v >= 1e3 or v <= -1e3 then
return ("%.1fk"):format(v / 1e3):gsub("%.?0+([km])$", "%1")
else
return v
end
end
 
S.SetUpAnimGroup = function(self)
self.anim = self:CreateAnimationGroup("Pulse")
self.anim.fadein = self.anim:CreateAnimation("ALPHA", "FadeIn")
self.anim.fadein:SetChange(1)
self.anim.fadein:SetOrder(2)
 
self.anim.fadeout = self.anim:CreateAnimation("ALPHA", "FadeOut")
self.anim.fadeout:SetChange(-1)
self.anim.fadeout:SetOrder(1)
end
 
S.Flash = function(self, duration)
if not self.anim then
S.SetUpAnimGroup(self)
end
 
self.anim.fadein:SetDuration(duration)
self.anim.fadeout:SetDuration(duration)
self.anim:SetLooping("REPEAT")
self.anim:Play()
end
 
S.StopFlash = function(self)
if self.anim then
self.anim:Finish()
end
end
 
INTERFACE_ACTION_BLOCKED = ''
 
 
--------------------------------------------------------------
-- Slash Command functionality
--------------------------------------------------------------
 
SlashCmdList['RELOADUI'] = function()
ReloadUI()
end
SLASH_RELOADUI1 = '/rl'
 
SLASH_FRAME1 = "/frame" -- Identifies frames for you
SlashCmdList["FRAME"] = function(arg)
if arg ~= "" then
arg = _G[arg]
else
arg = GetMouseFocus()
end
if arg ~= nil and arg:GetName() ~= nil then
local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint()
ChatFrame1:AddMessage("|cffCC0000----------------------------")
ChatFrame1:AddMessage("Name: |cffFFD100"..arg:GetName())
if arg:GetParent() and arg:GetParent():GetName() then
ChatFrame1:AddMessage("Parent: |cffFFD100"..arg:GetParent():GetName())
end
 
ChatFrame1:AddMessage("Width: |cffFFD100"..format("%.2f",arg:GetWidth()))
ChatFrame1:AddMessage("Height: |cffFFD100"..format("%.2f",arg:GetHeight()))
ChatFrame1:AddMessage("Strata: |cffFFD100"..arg:GetFrameStrata())
ChatFrame1:AddMessage("Level: |cffFFD100"..arg:GetFrameLevel())
 
if xOfs then
ChatFrame1:AddMessage("X: |cffFFD100"..format("%.2f",xOfs))
end
if yOfs then
ChatFrame1:AddMessage("Y: |cffFFD100"..format("%.2f",yOfs))
end
if relativeTo and relativeTo:GetName() then
ChatFrame1:AddMessage("Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint)
end
ChatFrame1:AddMessage("|cffCC0000----------------------------")
elseif arg == nil then
ChatFrame1:AddMessage("Invalid frame name")
else
ChatFrame1:AddMessage("Could not find frame info")
end
end
 
 
 
 
 
--------------------------------------------------------------
-- Hides UI Errors
--------------------------------------------------------------
UIErrorsFrame:UnregisterEvent('UI_ERROR_MESSAGE')
UIErrorsFrame:SetTimeVisible(1)
UIErrorsFrame:SetFadeDuration(0.75)
 
local ignoreList = {
[ERR_SPELL_COOLDOWN] = true,
[ERR_ABILITY_COOLDOWN] = true,
 
[OUT_OF_ENERGY] = true,
 
[SPELL_FAILED_NO_COMBO_POINTS] = true,
 
[SPELL_FAILED_MOVING] = true,
[ERR_NO_ATTACK_TARGET] = true,
[SPELL_FAILED_SPELL_IN_PROGRESS] = true,
 
[ERR_NO_ATTACK_TARGET] = true,
[ERR_INVALID_ATTACK_TARGET] = true,
[SPELL_FAILED_BAD_TARGETS] = true,
}
 
local event = CreateFrame('Frame')
event:SetScript('OnEvent', function(self, event, error)
if (not ignoreList[error]) then
UIErrorsFrame:AddMessage(error, 1, .1, .1)
end
end)
 
event:RegisterEvent('UI_ERROR_MESSAGE')
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Minimap/sMinimap.lua New file
0,0 → 1,421
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function; C - Config; Soop - Database
 
 
--------------------------------------------------------------
-- Minimap
-- Inspired by nMinimap
--------------------------------------------------------------
 
if C['minimap'].enable ~= true then return end
 
-- Square Minimap
Minimap:ClearAllPoints()
 
-- Set Minimap to Square
function GetMinimapShape()
return 'SQUARE'
end
 
-- Set Minimap Position
if C['datatext'].top ~= true then
Minimap:SetPoint('TOPRIGHT', UIParent, -16, -16)
else
Minimap:SetPoint('TOPRIGHT', UIParent, -16, -16)
end
 
 
--------------------------------------------------------------
-- Minimap Border Frame Set
--------------------------------------------------------------
 
local Minimapbg = CreateFrame("Frame", nil, Minimap)
Minimapbg:SetPoint("TOPLEFT", -4, 4);
Minimapbg:SetPoint("BOTTOMRIGHT", 4, -4);
Minimapbg:SetBackdrop({
edgeFile = C['minimap'].border,
tile = true, tileSize = 16, edgeSize = 18,
})
 
if C['general'].classcolor ~= true then
Minimapbg:SetBackdropBorderColor(C['general'].color.r,C['general'].color.g,C['general'].color.b)
else
Minimapbg:SetBackdropBorderColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
MinimapCluster:RegisterEvent("PLAYER_REGEN_ENABLED")
MinimapCluster:RegisterEvent("PLAYER_REGEN_DISABLED")
MinimapCluster:HookScript("OnEvent", function(self, event)
if event == "PLAYER_REGEN_ENABLED" then
MinimapCluster:Show()
elseif event == "PLAYER_REGEN_DISABLED" then
MinimapCluster:Hide()
end
end)
 
 
Minimap:SetMaskTexture('Interface\\ChatFrame\\ChatFrameBackground')
 
--------------------------------------------------------------
-- Minimap Mail Notify
--------------------------------------------------------------
MiniMapMailFrame:SetSize(14, 14)
MiniMapMailFrame:ClearAllPoints()
MiniMapMailFrame:SetPoint('BOTTOMRIGHT', Minimap, -4, 5)
 
MiniMapMailBorder:SetTexture(nil)
MiniMapMailIcon:SetTexture(nil)
 
hooksecurefunc(MiniMapMailFrame, 'Show', function()
MiniMapMailBorder:SetTexture(nil)
MiniMapMailIcon:SetTexture(nil)
end)
 
MiniMapMailFrame.Text = MiniMapMailFrame:CreateFontString(nil, 'OVERLAY')
MiniMapMailFrame.Text:SetFont(C['media'].font, C['media'].fontLarge, 'OUTLINE')
MiniMapMailFrame.Text:SetPoint('BOTTOMRIGHT', MiniMapMailFrame)
MiniMapMailFrame.Text:SetTextColor(1, 0, 1)
MiniMapMailFrame.Text:SetText('Mail')
 
--------------------------------------------------------------
-- Dungeon Finder
--------------------------------------------------------------
QueueStatusMinimapButton:ClearAllPoints()
QueueStatusMinimapButton:SetPoint('TOPLEFT', Minimap, 6, -6) --- Icon position
QueueStatusMinimapButton:SetSize(14, 14)
QueueStatusMinimapButton:SetHighlightTexture(nil)
QueueStatusMinimapButtonBorder:SetTexture()
 
 
--------------------------------------------------------------
-- Minimap Hide Useless Shit
--------------------------------------------------------------
MinimapZoomIn:Hide()
MinimapZoomIn:UnregisterAllEvents()
MinimapZoomOut:Hide()
MinimapZoomOut:UnregisterAllEvents()
 
MiniMapWorldMapButton:Hide()
MiniMapWorldMapButton:UnregisterAllEvents()
 
MinimapNorthTag:SetAlpha(0)
 
MinimapBorder:Hide()
MinimapBorderTop:Hide()
 
MinimapZoneText:Hide()
MinimapZoneTextButton:Hide()
MinimapZoneTextButton:UnregisterAllEvents()
 
MiniMapTracking:UnregisterAllEvents()
MiniMapTracking:Hide()
 
DurabilityFrame:Hide()
DurabilityFrame:UnregisterAllEvents()
 
--------------------------------------------------------------
-- Minimap Farm Mode
--------------------------------------------------------------
if C['minimap'].farm == true then
 
MinimapCluster:SetScale(C['minimap'].farmscale)
MinimapCluster:EnableMouse(false)
else
MinimapCluster:SetScale(.8)
MinimapCluster:EnableMouse(false)
end
 
 
 
--------------------------------------------------------------
-- Minimap Zoom on Scroll
--------------------------------------------------------------
Minimap:EnableMouseWheel(true)
Minimap:SetScript('OnMouseWheel', function(self, delta)
if (delta > 0) then
_G.MinimapZoomIn:Click()
elseif delta < 0 then
_G.MinimapZoomOut:Click()
end
end)
 
--------------------------------------------------------------
-- Minimap Tracking
--------------------------------------------------------------
Minimap:SetScript('OnMouseUp', function(self, button)
if (button == 'RightButton') then
ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, self, - (Minimap:GetWidth() * 0.7), -3)
else
Minimap_OnClick(self)
end
end)
 
--------------------------------------------------------------
-- Minimap Bliz Ticket Frame
--------------------------------------------------------------
TicketStatusFrame:ClearAllPoints()
TicketStatusFrame:SetPoint('BOTTOMRIGHT', UIParent, -25, -33)
TicketStatusFrameButton:HookScript('OnShow', function(self)
self:SetBackdrop({
bgFile = C['minimap'].background,
edgeFile = C['minimap'].border,
insets = {left = 3, right = 3, top = 3, bottom = 3}
})
end)
 
local function GetZoneColor()
local zoneType = GetZonePVPInfo()
if (zoneType == 'sanctuary') then
return 0.4, 0.8, 0.94
elseif (zoneType == 'arena') then
return 1, 0.1, 0.1
elseif (zoneType == 'friendly') then
return 0.1, 1, 0.1
elseif (zoneType == 'hostile') then
return 1, 0.1, 0.1
elseif (zoneType == 'contested') then
return 1, 0.8, 0
else
return 1, 1, 1
end
end
 
--------------------------------------------------------------
-- Minimap Mouseover Zone Text
--------------------------------------------------------------
 
if (C['minimap'].zoneText) then
local MainZone = Minimap:CreateFontString(nil, 'OVERLAY')
MainZone:SetFont(C['media'].font, C['media'].fontLarge, 'THINOUTLINE')
MainZone:SetPoint('TOP', Minimap, 0, -22)
MainZone:SetTextColor(1, 1, 1)
MainZone:SetAlpha(0)
MainZone:SetSize(130, 32)
MainZone:SetJustifyV('BOTTOM')
 
local SubZone = Minimap:CreateFontString(nil, 'OVERLAY')
SubZone:SetFont(C['media'].font, C['media'].fontSmall, 'THINOUTLINE')
SubZone:SetPoint('TOP', MainZone, 'BOTTOM', 0, -1)
SubZone:SetTextColor(1, 1, 1)
SubZone:SetAlpha(0)
SubZone:SetSize(130, 26)
SubZone:SetJustifyV('TOP')
 
Minimap:HookScript('OnEnter', function()
if (not IsShiftKeyDown()) then
SubZone:SetTextColor(GetZoneColor())
SubZone:SetText(GetSubZoneText())
securecall('UIFrameFadeIn', SubZone, 0.15, SubZone:GetAlpha(), 1)
 
MainZone:SetTextColor(GetZoneColor())
MainZone:SetText(GetRealZoneText())
securecall('UIFrameFadeIn', MainZone, 0.15, MainZone:GetAlpha(), 1)
end
end)
 
Minimap:HookScript('OnLeave', function()
securecall('UIFrameFadeOut', SubZone, 0.15, SubZone:GetAlpha(), 0)
securecall('UIFrameFadeOut', MainZone, 0.15, MainZone:GetAlpha(), 0)
end)
end
 
--------------------------------------------------------------
-- Minimap Mouseover Dungeon Diff
--------------------------------------------------------------
 
local isGuildGroup = isGuildGroup
 
local function HideDifficultyFrame()
GuildInstanceDifficulty:EnableMouse(false)
GuildInstanceDifficulty:SetAlpha(0)
 
MiniMapInstanceDifficulty:EnableMouse(false)
MiniMapInstanceDifficulty:SetAlpha(0)
end
 
function GetDifficultyText()
local inInstance, instancetype = IsInInstance()
local _, _, difficultyIndex, _, maxPlayers, playerDifficulty, isDynamic = GetInstanceInfo()
 
local guildStyle
local heroStyle = '|cffff00ffH|r'
 
if (isGuildGroup or GuildInstanceDifficulty:IsShown()) then
guildStyle = '|cffffff00G|r'
else
guildStyle = ''
end
 
if (inInstance and instancetype == 'raid') then
if (isDynamic) then
if (difficultyIndex == 4 or difficultyIndex == 3) then
if (playerDifficulty == 0) then
return maxPlayers..guildStyle..heroStyle
end
end
 
if (difficultyIndex == 2) then
return maxPlayers..guildStyle
end
 
if (difficultyIndex == 1) then
if (playerDifficulty == 0) then
return maxPlayers..guildStyle
end
 
if (playerDifficulty == 1) then
return maxPlayers..guildStyle..heroStyle
end
end
end
 
if (not isDynamic) then
if (difficultyIndex == 1 or difficultyIndex == 2) then
return maxPlayers..guildStyle
end
 
if (difficultyIndex == 3 or difficultyIndex == 4) then
return maxPlayers..guildStyle..heroStyle
end
end
end
 
if (inInstance and instancetype == 'party') then
if (difficultyIndex == 2)then
return maxPlayers..guildStyle..heroStyle
elseif (difficultyIndex == 1)then
return maxPlayers..guildStyle
end
end
 
if (not inInstance) then
return ''
end
end
 
 
--------------------------------------------------------------
-- Minimap frame
--------------------------------------------------------------
local f = Minimap
f.InstanceText = f:CreateFontString(nil, 'OVERLAY')
f.InstanceText:SetFont(C['media'].font, C['media'].fontLarge, 'OUTLINE')
f.InstanceText:SetPoint('TOP', Minimap, 0, -3.5)
f.InstanceText:SetTextColor(1, 1, 1)
f.InstanceText:Show()
 
 
hooksecurefunc(GuildInstanceDifficulty, 'Show', function()
isGuildGroup = true
HideDifficultyFrame()
end)
 
hooksecurefunc(GuildInstanceDifficulty, 'Hide', function()
isGuildGroup = false
end)
 
hooksecurefunc(MiniMapInstanceDifficulty, 'Show', function()
HideDifficultyFrame()
end)
 
GuildInstanceDifficulty:HookScript('OnEvent', function(self)
if (self:IsShown()) then
isGuildGroup = true
else
isGuildGroup = false
end
 
Minimap.InstanceText:SetText(GetDifficultyText())
end)
 
MiniMapInstanceDifficulty:HookScript('OnEvent', function(self)
Minimap.InstanceText:SetText(GetDifficultyText())
end)
 
if (C['minimap'].instanceDifficulty) then
Minimap.InstanceText:SetAlpha(0)
 
Minimap:HookScript('OnEnter', function(self)
securecall('UIFrameFadeIn', self.InstanceText, 0.235, 0, 1)
end)
 
Minimap:HookScript('OnLeave', function(self)
securecall('UIFrameFadeOut', self.InstanceText, 0.235, 1, 0)
end)
end
 
--------------------------------------------------------------
-- Calendar
--------------------------------------------------------------
if (not IsAddOnLoaded('Blizzard_TimeManager')) then
LoadAddOn('Blizzard_TimeManager')
end
 
for i = 1, select('#', GameTimeFrame:GetRegions()) do
local texture = select(i, GameTimeFrame:GetRegions())
if (texture and texture:GetObjectType() == 'Texture') then
texture:SetTexture(nil)
end
end
 
GameTimeFrame:SetSize(14, 14)
GameTimeFrame:SetHitRectInsets(0, 0, 0, 0)
GameTimeFrame:ClearAllPoints()
GameTimeFrame:SetPoint('TOPRIGHT', Minimap, -3.5, -3.5)
 
GameTimeFrame:GetFontString():SetFont(C['media'].font, C['media'].fontLarge, 'OUTLINE')
GameTimeFrame:GetFontString():SetShadowOffset(0, 0)
GameTimeFrame:GetFontString():SetPoint('TOPRIGHT', GameTimeFrame)
 
for _, texture in pairs({
GameTimeCalendarEventAlarmTexture,
GameTimeCalendarInvitesTexture,
GameTimeCalendarInvitesGlow,
TimeManagerAlarmFiredTexture,
}) do
texture:SetTexture(nil)
 
 
if (texture:IsShown()) then
GameTimeFrame:GetFontString():SetTextColor(1, 0, 1)
else
GameTimeFrame:GetFontString():SetTextColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
 
hooksecurefunc(texture, 'Show', function()
GameTimeFrame:GetFontString():SetTextColor(1, 0, 1)
end)
 
hooksecurefunc(texture, 'Hide', function()
GameTimeFrame:GetFontString():SetTextColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end)
end
 
--------------------------------------------------------------
-- Minimap Clock
--------------------------------------------------------------
TimeManagerClockTicker:SetFont(C['media'].font, C['media'].fontLarge, 'OUTLINE')
TimeManagerClockTicker:SetShadowOffset(0, 0)
TimeManagerClockTicker:SetTextColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
TimeManagerClockTicker:SetPoint('TOPRIGHT', TimeManagerClockButton, 0, 0)
 
TimeManagerClockButton:GetRegions():Hide()
TimeManagerClockButton:ClearAllPoints()
TimeManagerClockButton:SetWidth(40)
TimeManagerClockButton:SetHeight(18)
TimeManagerClockButton:SetPoint('BOTTOM', Minimap, 0, 2)
 
TimeManagerAlarmFiredTexture:SetTexture(nil)
 
hooksecurefunc(TimeManagerAlarmFiredTexture, 'Show', function()
TimeManagerClockTicker:SetTextColor(1, 0, 1)
end)
 
hooksecurefunc(TimeManagerAlarmFiredTexture, 'Hide', function()
TimeManagerClockTicker:SetTextColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end)
 
if C['minimap'].gameclock == true then
TimeManagerClockButton:Show()
else
TimeManagerClockButton:Hide()
end
 
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Tooltip/Tooltip.lua New file
0,0 → 1,853
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function; C - config; Soop - Database
 
if C['tooltip'].enable ~= true then return end
 
 
 
local _G = _G
local select = select
 
local format = string.format
 
local UnitName = UnitName
local UnitLevel = UnitLevel
local UnitExists = UnitExists
local UnitIsDead = UnitIsDead
local UnitIsGhost = UnitIsGhost
local UnitFactionGroup = UnitFactionGroup
local UnitCreatureType = UnitCreatureType
local GetQuestDifficultyColor = GetQuestDifficultyColor
 
local tankIcon = '|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:13:13:0:0:64:64:0:19:22:41|t'
local healIcon = '|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:13:13:0:0:64:64:20:39:1:20|t'
local damagerIcon = '|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:13:13:0:0:64:64:20:39:22:41|t'
 
local symbiosis = {
gain = {
['DEATHKNIGHT'] = { ['DK_BLOOD'] = 113072, ['DK_FROST'] = 113516, ['DK_UNHOLY'] = 113516, },
['HUNTER'] = { ['HUNTER_BM'] = 113073, ['HUNTER_MM'] = 113073, ['HUNTER_SV'] = 113073, },
['MAGE'] = { ['MAGE_ARCANE'] = 113074, ['MAGE_FIRE'] = 113074, ['MAGE_FROST'] = 113074, },
['MONK'] = { ['MONK_BREW'] = 113306, ['MONK_MIST'] = 127361, ['MONK_WIND'] = 113275, },
['PALADIN'] = { ['PALADIN_HOLY'] = 113269, ['PALADIN_PROT'] = 122287, ['PALADIN_RET'] = 113075, },
['PRIEST'] = { ['PRIEST_DISC'] = 113506, ['PRIEST_HOLY'] = 113506, ['PRIEST_SHADOW'] = 113277, },
['ROGUE'] = { ['ROGUE_ASS'] = 113613, ['ROGUE_COMBAT'] = 113613, ['ROGUE_SUB'] = 113613, },
['SHAMAN'] = { ['SHAMAN_ELE'] = 113286, ['SHAMAN_ENHANCE'] = 113286, ['SHAMAN_RESTO'] = 113289, },
['WARLOCK'] = { ['WARLOCK_AFFLICTION'] = 113295, ['WARLOCK_DEMO'] = 113295, ['WARLOCK_DESTRO'] = 113295, },
['WARRIOR'] = { ['WARRIOR_ARMS'] = 122294, ['WARRIOR_FURY'] = 122294, ['WARRIOR_PROT'] = 122286, },
},
grant = {
['DEATHKNIGHT'] = { ['DRUID_BALANCE'] = 110570, ['DRUID_FERAL'] = 122282, ['DRUID_GUARDIAN'] = 122285, ['DRUID_RESTO'] = 110575, },
['HUNTER'] = { ['DRUID_BALANCE'] = 110588, ['DRUID_FERAL'] = 110597, ['DRUID_GUARDIAN'] = 110600, ['DRUID_RESTO'] = 19263, },
['MAGE'] = { ['DRUID_BALANCE'] = 110621, ['DRUID_FERAL'] = 110693, ['DRUID_GUARDIAN'] = 110694, ['DRUID_RESTO'] = 110696, },
['MONK'] = { ['DRUID_BALANCE'] = 126458, ['DRUID_FERAL'] = 128844, ['DRUID_GUARDIAN'] = 126453, ['DRUID_RESTO'] = 126456, },
['PALADIN'] = { ['DRUID_BALANCE'] = 110698, ['DRUID_FERAL'] = 110700, ['DRUID_GUARDIAN'] = 110701, ['DRUID_RESTO'] = 122288, },
['PRIEST'] = { ['DRUID_BALANCE'] = 110707, ['DRUID_FERAL'] = 110715, ['DRUID_GUARDIAN'] = 110717, ['DRUID_RESTO'] = 110718, },
['ROGUE'] = { ['DRUID_BALANCE'] = 110788, ['DRUID_FERAL'] = 110730, ['DRUID_GUARDIAN'] = 122289, ['DRUID_RESTO'] = 110791, },
['SHAMAN'] = { ['DRUID_BALANCE'] = 110802, ['DRUID_FERAL'] = 110807, ['DRUID_GUARDIAN'] = 110803, ['DRUID_RESTO'] = 110806, },
['WARLOCK'] = { ['DRUID_BALANCE'] = 122291, ['DRUID_FERAL'] = 110810, ['DRUID_GUARDIAN'] = 122290, ['DRUID_RESTO'] = 112970, },
['WARRIOR'] = { ['DRUID_BALANCE'] = 122292, ['DRUID_FERAL'] = 112997, ['DRUID_GUARDIAN'] = 113002, ['DRUID_RESTO'] = 113004, },
}
}
 
CUSTOM_FACTION_BAR_COLORS = {
[1] = {r = 1, g = 0, b = 0},
[2] = {r = 1, g = 0, b = 0},
[3] = {r = 1, g = 1, b = 0},
[4] = {r = 1, g = 1, b = 0},
[5] = {r = 0, g = 1, b = 0},
[6] = {r = 0, g = 1, b = 0},
[7] = {r = 0, g = 1, b = 0},
[8] = {r = 0, g = 1, b = 0},
}
 
function GameTooltip_UnitColor(unit)
local r, g, b
 
if (UnitIsDead(unit) or UnitIsGhost(unit) or UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit)) then
r = 0.5
g = 0.5
b = 0.5
elseif (UnitIsPlayer(unit)) then
if (UnitIsFriend(unit, 'player')) then
local _, class = UnitClass(unit)
r = RAID_CLASS_COLORS[class].r
g = RAID_CLASS_COLORS[class].g
b = RAID_CLASS_COLORS[class].b
elseif (not UnitIsFriend(unit, 'player')) then
r = 1
g = 0
b = 0
end
elseif (UnitPlayerControlled(unit)) then
if (UnitCanAttack(unit, 'player')) then
if (not UnitCanAttack('player', unit)) then
r = 157/255
g = 197/255
b = 255/255
else
r = 1
g = 0
b = 0
end
elseif (UnitCanAttack('player', unit)) then
r = 1
g = 1
b = 0
elseif (UnitIsPVP(unit)) then
r = 0
g = 1
b = 0
else
r = 157/255
g = 197/255
b = 255/255
end
else
local reaction = UnitReaction(unit, 'player')
 
if (reaction) then
r = CUSTOM_FACTION_BAR_COLORS[reaction].r
g = CUSTOM_FACTION_BAR_COLORS[reaction].g
b = CUSTOM_FACTION_BAR_COLORS[reaction].b
else
r = 157/255
g = 197/255
b = 255/255
end
end
 
return r, g, b
end
 
UnitSelectionColor = GameTooltip_UnitColor
 
-- Some tooltip changes
 
if (C['tooltip'].fontOutline) then
GameTooltipHeaderText:SetFont(C['media'].font, (C['tooltip'].fontSize + 2), 'THINOUTLINE')
GameTooltipHeaderText:SetShadowOffset(0, 0)
 
GameTooltipText:SetFont(C['media'].font, (C['tooltip'].fontSize), 'THINOUTLINE')
GameTooltipText:SetShadowOffset(0, 0)
 
GameTooltipTextSmall:SetFont(C['media'].font, (C['tooltip'].fontSize), 'THINOUTLINE')
GameTooltipTextSmall:SetShadowOffset(0, 0)
else
GameTooltipHeaderText:SetFont(C['media'].font, (C['tooltip'].fontSize + 2))
GameTooltipText:SetFont(C['media'].font, (C['tooltip'].fontSize))
GameTooltipTextSmall:SetFont(C['media'].font, (C['tooltip'].fontSize))
end
 
GameTooltipStatusBar:SetHeight(7)
GameTooltipStatusBar:SetBackdrop({bgFile = 'Interface\\Buttons\\WHITE8x8'})
GameTooltipStatusBar:SetBackdropColor(0, 1, 0, 0.3)
 
local function ApplyTooltipStyle(self)
local bgsize, bsize
if (self == ConsolidatedBuffsTooltip) then
bgsize = 1
bsize = 8
elseif (self == FriendsTooltip) then
FriendsTooltip:SetScale(1.1)
 
bgsize = 1
bsize = 9
else
bgsize = 3
bsize = 12
end
 
self:SetBackdrop({
bgFile = C["tooltip"].background, -- 'Interface\\Tooltips\\UI-Tooltip-Background',
edgeFile = C["tooltip"].border,
tile = true, tileSize = 16, edgeSize = 18,
 
insets = {
left = bgsize, right = bgsize, top = bgsize, bottom = bgsize
}
})
 
self:HookScript('OnShow', function(self)
self:SetBackdropColor(0, 0, 0, 0.7)
end)
 
if (IsAddOnLoaded('!Beautycase')) then
self:CreateBeautyBorder(bsize)
end
end
 
for _, tooltip in pairs({
GameTooltip,
ItemRefTooltip,
 
ShoppingTooltip1,
ShoppingTooltip2,
ShoppingTooltip3,
 
WorldMapTooltip,
 
 
 
ConsolidatedBuffsTooltip,
 
ChatMenu,
EmoteMenu,
LanguageMenu,
VoiceMacroMenu,
 
FriendsTooltip,
}) do
ApplyTooltipStyle(tooltip)
end
 
-- Itemquaility border, we use our beautycase functions
 
if (C['tooltip'].itemqualityBorderColor) then
for _, tooltip in pairs({
GameTooltip,
ItemRefTooltip,
 
ShoppingTooltip1,
ShoppingTooltip2,
ShoppingTooltip3,
}) do
 
tooltip:HookScript('OnTooltipSetItem', function(self)
local name, item = self:GetItem()
if (item) then
local quality = select(3, GetItemInfo(item))
if (quality) then
local r, g, b = GetItemQualityColor(quality)
--self:SetBeautyBorderTexture('white')
self:SetBackdropBorderColor(r, g, b)
end
end
end)
 
tooltip:HookScript('OnTooltipCleared', function(self)
--self:SetBeautyBorderTexture('default')
self:SetBackdropBorderColor(1, 1, 1)
end)
 
end
end
 
-- Itemlvl (by Gsuz) - http://www.tukui.org/forums/topic.php?id=10151
 
local function GetItemLevel(unit)
local total, item = 0, 0
for i, v in pairs({
'Head',
'Neck',
'Shoulder',
'Back',
'Chest',
'Wrist',
'Hands',
'Waist',
'Legs',
'Feet',
'Finger0',
'Finger1',
'Trinket0',
'Trinket1',
'MainHand',
'SecondaryHand',
}) do
local slot = GetInventoryItemLink(unit, GetInventorySlotInfo(v..'Slot'))
if (slot ~= nil) then
item = item + 1
total = total + select(4, GetItemInfo(slot))
end
end
 
if (item > 0) then
return floor(total / item)
end
 
return 0
end
 
-- Make sure we get a correct unit
 
local function GetRealUnit(self)
if (GetMouseFocus() and not GetMouseFocus():GetAttribute('unit') and GetMouseFocus() ~= WorldFrame) then
return select(2, self:GetUnit())
elseif (GetMouseFocus() and GetMouseFocus():GetAttribute('unit')) then
return GetMouseFocus():GetAttribute('unit')
elseif (select(2, self:GetUnit())) then
return select(2, self:GetUnit())
else
return 'mouseover'
end
end
 
local function GetFormattedUnitType(unit)
local creaturetype = UnitCreatureType(unit)
if (creaturetype) then
return creaturetype
else
return ''
end
end
 
local function GetFormattedUnitClassification(unit)
local class = UnitClassification(unit)
if (class == 'worldboss') then
return '|cffFF0000'..BOSS..'|r '
elseif (class == 'rareelite') then
return '|cffFF66CCRare|r |cffFFFF00'..ELITE..'|r '
elseif (class == 'rare') then
return '|cffFF66CCRare|r '
elseif (class == 'elite') then
return '|cffFFFF00'..ELITE..'|r '
else
return ''
end
end
 
local function GetFormattedUnitLevel(unit)
local diff = GetQuestDifficultyColor(UnitLevel(unit))
if (UnitLevel(unit) == -1) then
return '|cffff0000??|r '
elseif (UnitLevel(unit) == 0) then
return '? '
else
return format('|cff%02x%02x%02x%s|r ', diff.r*255, diff.g*255, diff.b*255, UnitLevel(unit))
end
end
 
local function GetFormattedUnitClass(unit)
local color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
if (color) then
return format(' |cff%02x%02x%02x%s|r', color.r*255, color.g*255, color.b*255, UnitClass(unit))
end
end
 
local function GetFormattedUnitString(unit, specIcon)
if (UnitIsPlayer(unit)) then
return GetFormattedUnitLevel(unit)..UnitRace(unit)..GetFormattedUnitClass(unit)..(C['tooltip'].showSpecializationIcon and specIcon or '')
else
return GetFormattedUnitLevel(unit)..GetFormattedUnitClassification(unit)..GetFormattedUnitType(unit)
end
end
 
local function GetUnitRoleString(unit)
local role = UnitGroupRolesAssigned(unit)
local roleList = nil
 
if (role == 'TANK') then
roleList = ' '..tankIcon..' '..TANK
elseif (role == 'HEALER') then
roleList = ' '..healIcon..' '..HEALER
elseif (role == 'DAMAGER') then
roleList = ' '..damagerIcon..' '..DAMAGER
end
 
return roleList
end
 
-- Healthbar coloring funtion
 
local function SetHealthBarColor(unit)
local r, g, b
if (C['tooltip'].healthbar.custom.apply and not C['tooltip'].healthbar.reactionColoring) then
r, g, b = C['tooltip'].healthbar.custom.color.r, C['tooltip'].healthbar.custom.color.g, C['tooltip'].healthbar.custom.color.b
elseif (C['tooltip'].healthbar.reactionColoring and unit) then
r, g, b = UnitSelectionColor(unit)
else
r, g, b = 0, 1, 0
end
 
GameTooltipStatusBar:SetStatusBarColor(r, g, b)
GameTooltipStatusBar:SetBackdropColor(r, g, b, 0.3)
end
 
local function GetUnitRaidIcon(unit)
local index = GetRaidTargetIndex(unit)
 
if (index) then
if (UnitIsPVP(unit) and C['tooltip'].showPVPIcons) then
return ICON_LIST[index]..'11|t'
else
return ICON_LIST[index]..'11|t '
end
else
return ''
end
end
 
local function GetUnitPVPIcon(unit)
local factionGroup = UnitFactionGroup(unit)
 
if (UnitIsPVPFreeForAll(unit)) then
if (C['tooltip'].showPVPIcons) then
return '|TInterface\\AddOns\\nTooltip\\media\\UI-PVP-FFA:12|t'
else
return '|cffFF0000# |r'
end
elseif (factionGroup and UnitIsPVP(unit)) then
if (C['tooltip'].showPVPIcons) then
return '|TInterface\\AddOns\\nTooltip\\media\\UI-PVP-'..factionGroup..':12|t'
else
return '|cff00FF00# |r'
end
else
return ''
end
end
 
local function AddMouseoverTarget(self, unit)
local unitTargetName = UnitName(unit..'target')
local unitTargetClassColor = RAID_CLASS_COLORS[select(2, UnitClass(unit..'target'))] or { r = 1, g = 0, b = 1 }
local unitTargetReactionColor = {
r = select(1, UnitSelectionColor(unit..'target')),
g = select(2, UnitSelectionColor(unit..'target')),
b = select(3, UnitSelectionColor(unit..'target'))
}
 
if (UnitExists(unit..'target')) then
if (UnitName('player') == unitTargetName) then
self:AddLine(format('|cffFFFF00Target|r: '..GetUnitRaidIcon(unit..'target')..'|cffff00ff%s|r', string.upper("** YOU **")), 1, 1, 1)
else
if (UnitIsPlayer(unit..'target')) then
self:AddLine(format('|cffFFFF00Target|r: '..GetUnitRaidIcon(unit..'target')..'|cff%02x%02x%02x%s|r', unitTargetClassColor.r*255, unitTargetClassColor.g*255, unitTargetClassColor.b*255, unitTargetName:sub(1, 40)), 1, 1, 1)
else
self:AddLine(format('|cffFFFF00Target|r: '..GetUnitRaidIcon(unit..'target')..'|cff%02x%02x%02x%s|r', unitTargetReactionColor.r*255, unitTargetReactionColor.g*255, unitTargetReactionColor.b*255, unitTargetName:sub(1, 40)), 1, 1, 1)
end
end
end
end
 
GameTooltip.inspectCache = {}
 
GameTooltip:HookScript('OnTooltipSetUnit', function(self, ...)
local unit = GetRealUnit(self)
 
if (UnitExists(unit) and UnitName(unit) ~= UNKNOWN) then
 
local ilvl = 0
local specIcon = ''
local lastUpdate = 30
for index, _ in pairs(self.inspectCache) do
local inspectCache = self.inspectCache[index]
if (inspectCache.GUID == UnitGUID(unit)) then
ilvl = inspectCache.itemLevel or 0
specIcon = inspectCache.specIcon or ''
lastUpdate = inspectCache.lastUpdate and math.abs(inspectCache.lastUpdate - math.floor(GetTime())) or 30
end
end
 
-- Fetch inspect information (ilvl and spec)
 
if (unit and CanInspect(unit)) then
if (not self.inspectRefresh and lastUpdate >= 30 and not self.blockInspectRequests) then
if (not self.blockInspectRequests) then
self.inspectRequestSent = true
NotifyInspect(unit)
end
end
end
 
self.inspectRefresh = false
 
local name, realm = UnitName(unit)
 
-- Hide player titles
 
if (C['tooltip'].showPlayerTitles) then
if (UnitPVPName(unit)) then
name = UnitPVPName(unit)
end
end
 
GameTooltipTextLeft1:SetText(name)
 
-- Color guildnames
 
if (GetGuildInfo(unit)) then
if (GetGuildInfo(unit) == GetGuildInfo('player') and IsInGuild('player')) then
GameTooltipTextLeft2:SetText('|cffFF66CC'..GameTooltipTextLeft2:GetText()..'|r')
end
end
 
-- Tooltip level text
 
for i = 2, GameTooltip:NumLines() do
if (_G['GameTooltipTextLeft'..i]:GetText():find('^'..TOOLTIP_UNIT_LEVEL:gsub('%%s', '.+'))) then
_G['GameTooltipTextLeft'..i]:SetText(GetFormattedUnitString(unit, specIcon))
end
end
 
-- Role text
 
if (C['tooltip'].showUnitRole) then
self:AddLine(GetUnitRoleString(unit), 1, 1, 1)
end
 
-- Mouse over target with raidicon support
 
if (C['tooltip'].showMouseoverTarget) then
AddMouseoverTarget(self, unit)
end
 
-- Pvp flag prefix
 
for i = 3, GameTooltip:NumLines() do
if (_G['GameTooltipTextLeft'..i]:GetText():find(PVP_ENABLED)) then
_G['GameTooltipTextLeft'..i]:SetText(nil)
GameTooltipTextLeft1:SetText(GetUnitPVPIcon(unit)..GameTooltipTextLeft1:GetText())
end
end
 
-- Raid icon, want to see the raidicon on the left
 
GameTooltipTextLeft1:SetText(GetUnitRaidIcon(unit)..GameTooltipTextLeft1:GetText())
 
-- Afk and dnd prefix
 
if (UnitIsAFK(unit)) then
self:AppendText('|cff00ff00 <AFK>|r')
elseif (UnitIsDND(unit)) then
self:AppendText('|cff00ff00 <DND>|r')
end
 
-- Player realm names
 
if (realm and realm ~= '') then
if (C['tooltip'].abbrevRealmNames) then
self:AppendText(' (*)')
else
self:AppendText(' - '..realm)
end
end
 
-- Move the healthbar inside the tooltip
 
self:AddLine(' ')
GameTooltipStatusBar:ClearAllPoints()
GameTooltipStatusBar:SetPoint('LEFT', self:GetName()..'TextLeft'..self:NumLines(), 1, -3)
GameTooltipStatusBar:SetPoint('RIGHT', self, -10, 0)
 
-- Border coloring
 
if (C['tooltip'].reactionBorderColor) then
local r, g, b = UnitSelectionColor(unit)
 
--self:SetBeautyBorderTexture('white')
self:SetBackdropBorderColor(r, g, b)
end
 
-- Dead or ghost recoloring
 
if (UnitIsDead(unit) or UnitIsGhost(unit)) then
GameTooltipStatusBar:SetBackdropColor(0.5, 0.5, 0.5, 0.3)
else
if (not C['tooltip'].healthbar.custom.apply and not C['tooltip'].healthbar.reactionColoring) then
GameTooltipStatusBar:SetBackdropColor(27/255, 243/255, 27/255, 0.3)
else
SetHealthBarColor(unit)
end
end
 
-- Custom healthbar coloring
 
if (C['tooltip'].healthbar.reactionColoring or C['tooltip'].healthbar.custom.apply) then
GameTooltipStatusBar:HookScript('OnValueChanged', function()
SetHealthBarColor(unit)
end)
end
 
-- Show player item lvl
 
if (C['tooltip'].showItemLevel and ilvl > 1) then
GameTooltip:AddLine(STAT_AVERAGE_ITEM_LEVEL .. ': ' .. '|cffFFFFFF'..ilvl..'|r')
end
 
-- Symbiosis
 
if (UnitIsPlayer(unit) and not UnitIsEnemy(unit, 'player')) then
local hasSymbiosisBuff = false
for i = 1, 40 do
if select(11, UnitAura(unit, i, 'HELPFUL')) == 110309 then
hasSymbiosisBuff = true
break
end
end
 
local _, playerClass = UnitClass('player')
local _, unitClass = UnitClass(unit)
local spec = SPEC_CORE_ABILITY_TEXT[GetSpecializationInfo(GetSpecialization() or 1)]
local spellID = (playerClass == 'DRUID' and unitClass ~= 'DRUID') and symbiosis.grant[unitClass][spec] or (playerClass ~= 'DRUID' and unitClass == 'DRUID') and symbiosis.grant[playerClass][spec]
local name, _, icon = GetSpellInfo(spellID)
 
if (hasSymbiosisBuff) then
GameTooltip:AddLine(' ')
GameTooltip:AddLine('|cff3eea23'..GetSpellInfo(110309)..' already buffed|r')
end
 
if (icon) then
GameTooltip:AddLine(' ')
GameTooltip:AddDoubleLine('|T'..icon..':16:16:0:0:64:64:4:60:4:60|t '..name, '|cff3eea23'..GetSpellInfo(110309)..'|r')
end
end
end
end)
 
GameTooltip:HookScript('OnTooltipCleared', function(self)
GameTooltipStatusBar:ClearAllPoints()
GameTooltipStatusBar:SetPoint('BOTTOMLEFT', self, 'TOPLEFT', 0.5, 3)
GameTooltipStatusBar:SetPoint('BOTTOMRIGHT', self, 'TOPRIGHT', -1, 3)
GameTooltipStatusBar:SetBackdropColor(0, 1, 0, 0.3)
 
if (C['tooltip'].reactionBorderColor and self.beautyBorder) then
self:SetBeautyBorderTexture('default')
self:SetBeautyBorderColor(1, 1, 1)
end
end)
 
 
GameTooltip:RegisterEvent('INSPECT_READY')
GameTooltip:SetScript('OnEvent', function(self, event, GUID)
if (not self:IsShown()) then
return
end
 
local _, unit = self:GetUnit()
 
if (not unit) then
return
end
 
if (self.blockInspectRequests) then
self.inspectRequestSent = false
end
 
if (UnitGUID(unit) ~= GUID or not self.inspectRequestSent) then
if (not self.blockInspectRequests) then
ClearInspectPlayer()
end
return
end
 
local _, _, _, icon = GetSpecializationInfoByID(GetInspectSpecialization(unit))
local ilvl = GetItemLevel(unit)
local now = GetTime()
 
local matchFound
for index, _ in pairs(self.inspectCache) do
local inspectCache = self.inspectCache[index]
if (inspectCache.GUID == GUID) then
inspectCache.itemLevel = ilvl
inspectCache.specIcon = icon and ' |T'..icon..':0|t' or ''
inspectCache.lastUpdate = math.floor(now)
matchFound = true
end
end
 
if not matchFound then
local GUIDInfo = {
['GUID'] = GUID,
['itemLevel'] = ilvl,
['specIcon'] = icon and ' |T'..icon..':0|t' or '',
['lastUpdate'] = math.floor(now)
}
table.insert(self.inspectCache, GUIDInfo)
end
 
if (#self.inspectCache > 30) then
table.remove(self.inspectCache, 1)
end
 
self.inspectRefresh = true
GameTooltip:SetUnit('mouseover')
 
if (not self.blockInspectRequests) then
ClearInspectPlayer()
end
self.inspectRequestSent = false
end)
 
local f = CreateFrame('Frame')
f:RegisterEvent('ADDON_LOADED')
f:SetScript('OnEvent', function(self, event)
if IsAddOnLoaded('Blizzard_InspectUI') then
hooksecurefunc('InspectFrame_Show', function(unit)
GameTooltip.blockInspectRequests = true
end)
 
InspectFrame:HookScript('OnHide', function()
GameTooltip.blockInspectRequests = false
end)
 
self:UnregisterEvent('ADDON_LOADED')
end
end)
GameTooltip:RegisterEvent('INSPECT_READY')
 
if (not C['tooltip'].healthbar.showHealthValue) then
return
else
 
local select = select
local tonumber = tonumber
 
local modf = math.modf
local gsub = string.gsub
local format = string.format
 
local bar = GameTooltipStatusBar
bar.Text = bar:CreateFontString(nil, 'OVERLAY')
bar.Text:SetPoint('CENTER', bar, C['tooltip'].healthbar.textPos, 0, 1)
 
if (C['tooltip'].healthbar.showOutline) then
bar.Text:SetFont(C['media'].font, C['media'].fontSize, 'THINOUTLINE')
bar.Text:SetShadowOffset(0, 0)
else
bar.Text:SetFont(C['media'].font, C['media'].fontSize)
bar.Text:SetShadowOffset(1, -1)
end
 
local function ColorGradient(perc, ...)
if (perc >= 1) then
local r, g, b = select(select('#', ...) - 2, ...)
return r, g, b
elseif (perc <= 0) then
local r, g, b = ...
return r, g, b
end
 
local num = select('#', ...) / 3
 
local segment, relperc = modf(perc*(num-1))
local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...)
 
return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
end
 
local function FormatValue(value)
if (value >= 1e6) then
return tonumber(format('%.1f', value/1e6))..'m'
elseif (value >= 1e3) then
return tonumber(format('%.1f', value/1e3))..'k'
else
return value
end
end
 
local function DeficitValue(value)
if (value == 0) then
return ''
else
return '-'..FormatValue(value)
end
end
 
local function GetHealthTag(text, cur, max)
local perc = format('%d', (cur/max)*100)
 
if (max == 1) then
return perc
end
 
local r, g, b = ColorGradient(cur/max, 1, 0, 0, 1, 1, 0, 0, 1, 0)
text = gsub(text, '$cur', format('%s', FormatValue(cur)))
text = gsub(text, '$max', format('%s', FormatValue(max)))
text = gsub(text, '$deficit', format('%s', DeficitValue(max-cur)))
text = gsub(text, '$perc', format('%d', perc)..'%%')
text = gsub(text, '$smartperc', format('%d', perc))
text = gsub(text, '$smartcolorperc', format('|cff%02x%02x%02x%d|r', r*255, g*255, b*255, perc))
text = gsub(text, '$colorperc', format('|cff%02x%02x%02x%d', r*255, g*255, b*255, perc)..'%%|r')
 
return text
end
 
GameTooltipStatusBar:HookScript('OnValueChanged', function(self, value)
if (self.Text) then
self.Text:SetText('')
end
 
if (not value) then
return
end
 
local min, max = self:GetMinMaxValues()
 
if ((value < min) or (value > max) or (value == 0) or (value == 1)) then
return
end
 
if (not self.Text) then
CreateHealthString(self)
end
 
local fullString = GetHealthTag(C['tooltip'].healthbar.healthFullFormat, value, max)
local normalString = GetHealthTag(C['tooltip'].healthbar.healthFormat, value, max)
 
local perc = (value/max)*100
if (perc >= 100 and currentValue ~= 1) then
self.Text:SetText(fullString)
elseif (perc < 100 and currentValue ~= 1) then
self.Text:SetText(normalString)
else
self.Text:SetText('')
end
end)
end
 
if (not C['tooltip'].disableFade) then
return
else
-- GameTooltip.FadeOut = GameTooltip.Hide
GameTooltip.UpdateTime = 0
GameTooltip:HookScript('OnUpdate', function(self, elapsed)
self.UpdateTime = self.UpdateTime + elapsed
if (self.UpdateTime > TOOLTIP_UPDATE_TIME) then
self.UpdateTime = 0
if (GetMouseFocus() == WorldFrame and (not UnitExists('mouseover'))) then
self:Hide()
end
end
end)
end
 
-- Spell ID in Tooltip
hooksecurefunc(GameTooltip, 'SetUnitBuff', function(self,...)
local id = select(11,UnitBuff(...))
if (id) then
self:AddLine('SpellID: '..id, 1, 1, 1)
self:Show()
end
end)
 
hooksecurefunc(GameTooltip, 'SetUnitDebuff', function(self,...)
local id = select(11,UnitDebuff(...))
if (id) then
self:AddLine('SpellID: '..id, 1, 1, 1)
self:Show()
end
end)
 
hooksecurefunc(GameTooltip, 'SetUnitAura', function(self,...)
local id = select(11, UnitAura(...))
if (id) then
self:AddLine('SpellID: '..id, 1, 1, 1)
self:Show()
end
end)
 
hooksecurefunc('SetItemRef', function(link, text, button, chatFrame)
if (string.find(link,'^spell:')) then
local id = string.sub(link,7)
ItemRefTooltip:AddLine('SpellID: '..id, 1, 1, 1)
ItemRefTooltip:Show()
end
end)
 
GameTooltip:HookScript('OnTooltipSetSpell', function(self)
local id = select(3,self:GetSpell())
if (id) then
self:AddLine('SpellID: '..id, 1, 1, 1)
self:Show()
end
end)
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Autogreed.lua New file
0,0 → 1,18
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
--------------------------------------------------------------
-- Autogreed on Items
--------------------------------------------------------------
 
if C['general'].autogreed ~= true then return end
 
 
local AddOn = CreateFrame('Frame')
 
AddOn:RegisterEvent('START_LOOT_ROLL')
AddOn:SetScript('OnEvent', function(_, _, RollID)
local _, Name, _, Quality, BoP, _, _, CanDisenchant = GetLootRollItemInfo(RollID)
if (Quality == 2 and not BoP) then
RollOnLoot(RollID, CanDisenchant and 3 or 2)
end
end)
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Interrupts.lua New file
0,0 → 1,15
local S, C, Soop = unpack(select(2, ...))
 
if C['general'].interrupts ~= true then return end
 
----------------------------------------------------------------------------------------
-- Announce your interrupts(by Elv22)
----------------------------------------------------------------------------------------
local frame = CreateFrame("Frame")
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:SetScript("OnEvent", function(self, _, ...)
local _, event, _, sourceGUID, _, _, _, _, destName, _, _, _, _, _, spellID = ...
if not (event == "SPELL_INTERRUPT" and sourceGUID == UnitGUID("player")) then return end
 
SendChatMessage(INTERRUPTED.." "..destName..": "..GetSpellLink(spellID), T.CheckChat())
end)
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Merchant.lua New file
0,0 → 1,113
local S, C, Soop = unpack(select(2, ...))
 
 
 
--------------------------------------------------------------
-- Merchant
-- Auto vendor and repair functionality
-- Credit for Merchant goes to Tuks and ballagarba
-- Modified for SoopUI by Soopie
--------------------------------------------------------------
 
 
if C['merchant'].enable ~= true then return end
 
 
local filter = {
[6289] = true, -- Raw Longjaw Mud Snapper
[6291] = true, -- Raw Brilliant Smallfish
[6308] = true, -- Raw Bristle Whisker Catfish
[6309] = true, -- 17 Pound Catfish
[6310] = true, -- 19 Pound Catfish
[41808] = true, -- Bonescale Snapper
[42336] = true, -- Bloodstone Band
[42337] = true, -- Sun Rock Ring
[43244] = true, -- Crystal Citrine Necklace
[43571] = true, -- Sewer Carp
[43572] = true, -- Magic Eater
}
 
local f = CreateFrame("Frame")
f:SetScript("OnEvent", function()
-- if C['merchant'].autoSellGrey or C['merchant'].sellMisc then
-- local c = 0
-- for bag = 0, 4 do
-- for slot = 1, GetContainerNumSlots(bag) do
-- local l,lid = GetContainerItemLink(bag, slot), GetContainerItemID(bag, slot)
-- if l and lid then
-- local p = select(11, GetItemInfo(l))*select(2, GetContainerItemInfo(bag, slot))
-- if C['merchant'].autoSellGrey and select(3, GetItemInfo(l))==0 then
-- UseContainerItem(bag, slot)
-- PickupMerchantItem()
-- c = c+p
-- end
-- if C['merchant'].sellMisc and filter[ lid ] then
-- UseContainerItem(bag, slot)
-- PickupMerchantItem()
-- c = c+p
-- end
-- end
-- end
-- end
-- if c>0 then
-- local g, s, c = math.floor(c/10000) or 0, math.floor((c%10000)/100) or 0, c%100
-- DEFAULT_CHAT_FRAME:AddMessage("Your grey item's have been sold for".." |cffffffff"..g.."|cffffd700g|r".." |cffffffff"..s.."|cffc7c7cfs|r".." |cffffffff"..c.."|cffeda55fc|r"..".",255,255,0)
-- end
-- end
-- if not IsShiftKeyDown() then
if CanMerchantRepair() and C['merchant'].autoRepair then
local cost = GetRepairAllCost()
if GetGuildBankWithdrawMoney() >= cost then
RepairAllItems(1)
elseif GetMoney() >= cost then
RepairAllItems()
end
end
 
 
end)
f:RegisterEvent("MERCHANT_SHOW")
 
---------
--AltBuy
---------
 
-- just a new color
 
local NEW_ITEM_VENDOR_STACK_BUY = ITEM_VENDOR_STACK_BUY
ITEM_VENDOR_STACK_BUY = '|cffa9ff00'..NEW_ITEM_VENDOR_STACK_BUY..'|r'
 
-- alt-click to buy a stack
 
local origMerchantItemButton_OnModifiedClick = _G.MerchantItemButton_OnModifiedClick
local function MerchantItemButton_OnModifiedClickHook(self, ...)
origMerchantItemButton_OnModifiedClick(self, ...)
 
if (IsAltKeyDown()) then
local maxStack = select(8, GetItemInfo(GetMerchantItemLink(self:GetID())))
local _, _, _, quantity = GetMerchantItemInfo(self:GetID())
 
if (maxStack and maxStack > 1) then
BuyMerchantItem(self:GetID(), floor(maxStack / quantity))
end
end
end
MerchantItemButton_OnModifiedClick = MerchantItemButton_OnModifiedClickHook
 
-- Google translate ftw...NOT
 
local function GetAltClickString()
if (GetLocale() == 'enUS') then
return '<Alt-click, to buy an stack>'
elseif (GetLocale() == 'frFR') then
return '<Alt-clic, d acheter une pile>'
elseif (GetLocale() == 'esES') then
return '<Alt-clic, para comprar una pila>'
elseif (GetLocale() == 'deDE') then
return '<Alt-klicken, um einen ganzen Stapel zu kaufen>'
else
return '<Alt-click, to buy an stack>'
end
end
 
 
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Quest.lua New file
0,0 → 1,97
local S, C, Soop = unpack(select(2, ...)) -- Import driver || S = Functions || C = Config || Soop = Database
 
 
 
--------------------------------------------------------------
-- Quest Automation and Improvements
--
-- Original coding by Nightcracker
--------------------------------------------------------------
 
if C['quest'].enable ~= true then return end
 
 
--------------------------------------------------------------
-- Add Quest Level in Log
--------------------------------------------------------------
local function questlevel()
local buttons = QuestLogScrollFrame.buttons
local numButtons = #buttons
local scrollOffset = HybridScrollFrame_GetOffset(QuestLogScrollFrame)
local numEntries, numQuests = GetNumQuestLogEntries()
 
for i = 1, numButtons do
local questIndex = i + scrollOffset
local questLogTitle = buttons[i]
if questIndex <= numEntries then
local title, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questIndex)
if not isHeader then
questLogTitle:SetText("[" .. level .. "] " .. title)
QuestLogTitleButton_Resize(questLogTitle)
end
end
end
end
 
hooksecurefunc("QuestLog_Update", questlevel)
QuestLogScrollFrameScrollBar:HookScript("OnValueChanged", questlevel)
 
local QuestFrame = CreateFrame("Frame")
 
local function MostValueable()
local bestp, besti = 0
for i=1,GetNumQuestChoices() do
local link, name, _, qty = GetQuestItemLink("choice", i), GetQuestItemInfo("choice", i)
local price = link and select(11, GetItemInfo(link))
if not price then
return
elseif (price * (qty or 1)) > bestp then
bestp, besti = (price * (qty or 1)), i
end
end
if besti then
local btn = _G["QuestInfoItem"..besti]
if (btn.type == "choice") then
btn:GetScript("OnClick")(btn)
end
end
 
end
 
--------------------------------------------------------------
-- Quest Auto Complete
--------------------------------------------------------------
if C['quest'].autocomplete == true then
QuestFrame:SetScript("OnEvent", function(self, event, ...)
if (event == "QUEST_DETAIL") then
AcceptQuest()
CompleteQuest()
elseif (event == "QUEST_COMPLETE") then
if (GetNumQuestChoices() and GetNumQuestChoices() < 1) then
GetQuestReward()
else
MostValueable()
end
elseif (event == "QUEST_ACCEPT_CONFIRM") then
ConfirmAcceptQuest()
end
end)
else
QuestFrame:SetScript("OnEvent", function(self, event, ...)
if (event == "QUEST_COMPLETE") then
if (GetNumQuestChoices() and GetNumQuestChoices() < 1) then
GetQuestReward()
else
MostValueable()
end
end
end)
end
 
QuestFrame:RegisterEvent("QUEST_ACCEPT_CONFIRM")
QuestFrame:RegisterEvent("QUEST_DETAIL")
QuestFrame:RegisterEvent("QUEST_COMPLETE")
 
 
local timeout = CreateFrame("Frame")
timeout:Hide()
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Watchframe.lua New file
0,0 → 1,48
local S, C, Soop = unpack(select(2, ...)) -- Import driver || S = Functions || C = Config || Soop = Database
 
 
--------------------------------------------------------------
-- Watchframe Improvements
--------------------------------------------------------------
 
local watchFrame = _G['WatchFrame']
watchFrame:SetHeight(400)
watchFrame:ClearAllPoints()
watchFrame.ClearAllPoints = function() end
watchFrame:SetPoint('TOPRIGHT', UIParent, -100, -250)
watchFrame:SetClampedToScreen(true)
watchFrame:SetMovable(true)
watchFrame:SetUserPlaced(true)
watchFrame.SetPoint = function() end
watchFrame:SetScale(1.01)
 
local watchHead = _G['WatchFrameHeader']
watchHead:EnableMouse(true)
watchHead:RegisterForDrag('LeftButton')
watchHead:SetHitRectInsets(-15, 0, -5, -5)
watchHead:SetScript('OnDragStart', function(self)
if (IsShiftKeyDown()) then
self:GetParent():StartMoving()
end
end)
 
watchHead:SetScript('OnDragStop', function(self)
self:GetParent():StopMovingOrSizing()
end)
 
watchHead:SetScript('OnEnter', function()
if InCombatLockdown() then return end
GameTooltip:SetOwner(watchHead, "ANCHOR_TOPLEFT")
GameTooltip:ClearLines()
GameTooltip:AddLine("|cffeda55fShift+Left Click|r to Drag")
GameTooltip:Show()
end)
watchHead:SetScript('OnLeave', function() GameTooltip:Hide() end)
 
local watchHeadTitle = _G['WatchFrameTitle']
watchHeadTitle:SetFont(C['media'].font, 15)
if C['general'].classcolor ~= true then
watchHeadTitle:SetTextColor(C['general'].color.r,C['general'].color.g,C['general'].color.b)
else
watchHeadTitle:SetTextColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Font.lua New file
0,0 → 1,59
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
--------------------------------------------------------------
-- Font Options Setup
--------------------------------------------------------------
 
local function SetFont(obj, font, size, style, r, g, b, sr, sg, sb, sox, soy)
obj:SetFont(font, size, style)
if sr and sg and sb then obj:SetShadowColor(sr, sg, sb) end
if sox and soy then obj:SetShadowOffset(sox, soy) end
if r and g and b then obj:SetTextColor(r, g, b)
elseif r then obj:SetAlpha(r) end
end
 
 
local NORMAL = C['media'].font
local COMBAT = C['media'].font
local NUMBER = C['media'].font
local _, editBoxFontSize, _, _, _, _, _, _, _, _ = GetChatWindowInfo(1)
 
UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = 12
CHAT_FONT_HEIGHTS = {12, 13, 14, 15, 16, 17, 18, 19, 20}
 
UNIT_NAME_FONT = NORMAL
NAMEPLATE_FONT = NORMAL
DAMAGE_TEXT_FONT = COMBAT
STANDARD_TEXT_FONT = NORMAL
 
 
-- Base fonts
SetFont(GameTooltipHeader, NORMAL, C['media'].fontSize)
SetFont(NumberFont_OutlineThick_Mono_Small, NUMBER, C['media'].fontSize, "OUTLINE")
SetFont(NumberFont_Outline_Huge, NUMBER, 28, "THICKOUTLINE", 28)
SetFont(NumberFont_Outline_Large, NUMBER, 15, "OUTLINE")
SetFont(NumberFont_Outline_Med, NUMBER, C['media'].fontSize*1.1, "OUTLINE")
SetFont(NumberFont_Shadow_Med, NORMAL, C['media'].fontSize) -- Chat editbox uses this
SetFont(NumberFont_Shadow_Small, NORMAL, C['media'].fontSize)
SetFont(QuestFont, NORMAL, C['media'].fontSize)
SetFont(QuestFont_Large, NORMAL, 14)
SetFont(SystemFont_Large, NORMAL, 15)
SetFont(SystemFont_Shadow_Huge1, NORMAL, 20, "OUTLINE") -- Raid Warning, Boss emote frame too
SetFont(SystemFont_Med1, NORMAL, C['media'].fontSize)
SetFont(SystemFont_Med3, NORMAL, C['media'].fontSize*1.1)
SetFont(SystemFont_OutlineThick_Huge2, NORMAL, 20, "THICKOUTLINE")
SetFont(SystemFont_Outline_Small, NUMBER, C['media'].fontSize, "OUTLINE")
SetFont(SystemFont_Shadow_Large, NORMAL, 15)
SetFont(SystemFont_Shadow_Med1, NORMAL, C['media'].fontSize)
SetFont(SystemFont_Shadow_Med3, NORMAL, C['media'].fontSize*1.1)
SetFont(SystemFont_Shadow_Outline_Huge2, NORMAL, 20, "OUTLINE")
SetFont(SystemFont_Shadow_Small, NORMAL, C['media'].fontSize*0.9)
SetFont(SystemFont_Small, NORMAL, C['media'].fontSize)
SetFont(SystemFont_Tiny, NORMAL, C['media'].fontSize)
SetFont(Tooltip_Med, NORMAL, C['media'].fontSize)
SetFont(Tooltip_Small, NORMAL, C['media'].fontSize)
SetFont(ZoneTextString, NORMAL, 32, "OUTLINE")
SetFont(SubZoneTextString, NORMAL, 25, "OUTLINE")
SetFont(PVPInfoTextString, NORMAL, 22, "OUTLINE")
SetFont(PVPArenaTextString, NORMAL, 22, "OUTLINE")
SetFont(CombatTextFont, COMBAT, 100, "OUTLINE") -- Increases font quality
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/General/Store.lua New file
0,0 → 1,34
local S, C, Soop = unpack(select(2, ...))
 
--------------------------------------------------------------
-- Hide the Blizzard store button
--------------------------------------------------------------
 
GameMenuButtonStore:ClearAllPoints()
GameMenuButtonStore:Hide()
GameMenuButtonStore:HookScript("OnShow", GameMenuButtonStore.Hide)
 
GameMenuButtonOptions:ClearAllPoints()
GameMenuButtonOptions:SetPoint("TOP", GameMenuButtonHelp, "BOTTOM", 0, -16)
 
function GameMenuFrame_UpdateVisibleButtons(self) -- Adapted from GameMenuFrame.lua
local height = 290
 
if IsMacClient() then
height = height + 20
GameMenuButtonMacOptions:Show()
GameMenuButtonUIOptions:SetPoint("TOP", GameMenuButtonMacOptions, "BOTTOM", 0, -1)
else
GameMenuButtonMacOptions:Hide()
GameMenuButtonUIOptions:SetPoint("TOP", GameMenuButtonOptions, "BOTTOM", 0, -1)
end
 
if GameMenuButtonRatings:IsShown() then
height = height + 20
GameMenuButtonLogout:SetPoint("TOP", GameMenuButtonRatings, "BOTTOM", 0, -16)
else
GameMenuButtonLogout:SetPoint("TOP", GameMenuButtonMacros, "BOTTOM", 0, -16)
end
 
self:SetHeight(height)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Positions.lua New file
0,0 → 1,101
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function; C - config; Soop - Database
 
--[[
 
All Credit for Positions.lua goes to Tuks.
Tukui = http://www.tukui.org/download.php.
 
 
]]
 
if C['datatext'].enable ~= true then return end
 
-- Datatext Positions
S.PP = function(p, obj)
 
local left = PanelLeft
local center = PanelCenter
local right = PanelRight
 
-- Left Panel Data
if p == 1 then
obj:SetParent(left)
obj:SetHeight(left:GetHeight())
obj:SetPoint('LEFT', left, 5, 0)
obj:SetPoint('TOP', left)
obj:SetPoint('BOTTOM', left)
elseif p == 2 then
obj:SetParent(left)
obj:SetHeight(left:GetHeight())
obj:SetPoint('TOP', left)
obj:SetPoint('BOTTOM', left)
elseif p == 3 then
obj:SetParent(left)
obj:SetHeight(left:GetHeight())
obj:SetPoint('RIGHT', left, 0, 0)
obj:SetPoint('TOP', left)
obj:SetPoint('BOTTOM', left)
 
-- Center Panel Data
elseif p == 4 then
obj:SetParent(center)
obj:SetHeight(center:GetHeight())
obj:SetPoint('LEFT', center, 5, 0)
obj:SetPoint('TOP', center)
obj:SetPoint('BOTTOM', center)
elseif p == 5 then
obj:SetParent(center)
obj:SetHeight(center:GetHeight())
obj:SetPoint('LEFT', center, 60, 0)
obj:SetPoint('TOP', center)
obj:SetPoint('BOTTOM', center)
elseif p == 6 then
obj:SetParent(center)
obj:SetHeight(center:GetHeight())
obj:SetPoint('RIGHT', center, 45, 0)
obj:SetPoint('TOP', center)
obj:SetPoint('BOTTOM', center)
 
-- Right Panel Data
elseif p == 7 then
obj:SetParent(right)
obj:SetHeight(right:GetHeight())
obj:SetPoint('LEFT', right, 50, 0)
obj:SetPoint('TOP', right)
obj:SetPoint('BOTTOM', right)
elseif p == 8 then
obj:SetParent(right)
obj:SetHeight(right:GetHeight())
obj:SetPoint('RIGHT', right, 80, 0)
obj:SetPoint('TOP', right)
obj:SetPoint('BOTTOM', right)
elseif p == 9 then
obj:SetParent(right)
obj:SetHeight(right:GetHeight())
obj:SetPoint('RIGHT', right, -10, 0)
obj:SetPoint('TOP', right)
obj:SetPoint('BOTTOM', right)
end
 
end
 
S.DataTextTooltipAnchor = function(self)
local panel = self:GetParent()
local anchor = 'GameTooltip'
local xoff = 1
local yoff = 3
 
 
for _, panel in pairs ({
PanelLeft,
PanelCenter,
PanelRight,
}) do
if C['datatext'].top == true then
anchor = 'ANCHOR_BOTTOM'
else
anchor = 'ANCHOR_TOP'
end
end
return anchor, panel, xoff, yoff
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Coords.lua New file
0,0 → 1,29
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Coords Datapanel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].coords and C['datatext'].coords > 0 then
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata('BACKGROUND')
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].coords, Text)
 
local function Update(self)
local px,py=GetPlayerMapPosition("player")
Text:SetText(format("%i , %i",px*100,py*100))
end
 
Stat:SetScript("OnUpdate", Update)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Datapanel.lua New file
0,0 → 1,191
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Data Panel (originally by Tuks of Tukui.org)
--------------------------------------------------------------
if C['datatext'].enable ~= true then return end
 
 
local DataPanel = CreateFrame('Frame', 'DataPanel', UIParent)
local PanelLeft = CreateFrame('Frame', 'PanelLeft', UIParent)
local PanelCenter = CreateFrame('Frame', 'PanelCenter', UIParent)
local PanelRight = CreateFrame('Frame', 'PanelRight', UIParent)
local BattleGroundPanel = CreateFrame('Frame', 'BattleGroundPanel', UIParent)
 
if C['datatext'].top == true then
DataPanel:SetPoint('TOP', UIParent, 0, 0)
DataPanel:SetHeight(30)
DataPanel:SetWidth(S.getscreenwidth / 6)
DataPanel:SetFrameStrata('LOW')
DataPanel:SetFrameLevel(0)
DataPanel:SetBackdrop({
bgFile = C['datatext'].background,
edgeFile = C['datatext'].border,
tile = true, tileSize = 16, edgeSize = 14,
insets = {left = 15, right = 15, top = 2, bottom = 2},
})
 
 
if C['datatext'].border == "fer09" then
if C['general'].classcolor ~= true then
DataPanel:SetBackdropBorderColor(C['general'].color.r,C['general'].color.g,C['general'].color.b)
else
DataPanel:SetBackdropBorderColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
else
DataPanel:SetBackdropBorderColor(1, 1, 1)
end
 
 
-- Left Panel
PanelLeft:SetPoint('LEFT', DataPanel, 5, 0)
PanelLeft:SetHeight(30)
PanelLeft:SetWidth(S.getscreenwidth / 6)
PanelLeft:SetFrameStrata('LOW')
PanelLeft:SetFrameLevel(1)
 
-- Center Panel
PanelCenter:SetPoint('CENTER', DataPanel, 0, 0)
PanelCenter:SetHeight(30)
PanelCenter:SetWidth(S.getscreenwidth / 6)
PanelCenter:SetFrameStrata('LOW')
PanelCenter:SetFrameLevel(1)
 
-- Right Panel
PanelRight:SetPoint('RIGHT', DataPanel, -5, 0)
PanelRight:SetHeight(30)
PanelRight:SetWidth(S.getscreenwidth / 6)
PanelRight:SetFrameStrata('LOW')
PanelRight:SetFrameLevel(1)
 
-- Battleground Panel
BattleGroundPanel:SetAllPoints(PanelLeft)
BattleGroundPanel:SetFrameStrata('LOW')
BattleGroundPanel:SetFrameLevel(1)
else
DataPanel:SetPoint('BOTTOM', UIParent, 40, -5)
DataPanel:SetHeight(30)
DataPanel:SetWidth(560)
DataPanel:SetFrameStrata('LOW')
DataPanel:SetFrameLevel(0)
DataPanel:SetBackdrop({
bgFile = C['datatext'].background,
edgeFile = C['datatext'].border,
tile = true, tileSize = 16, edgeSize = 5,
insets = {left = 3, right = 3, top = 3, bottom = 3}
})
DataPanel:SetBackdropColor(1, 0, 0, 0)
 
if C['datatext'].border == "edgeFile" then
if C['general'].classcolor ~= true then
DataPanel:SetBackdropBorderColor(C['general'].color.r,C['general'].color.g,C['general'].color.b)
else
DataPanel:SetBackdropBorderColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
else
DataPanel:SetBackdropBorderColor(0, 0, 0, 1)
DataPanel:SetAlpha(.60)
end
 
 
 
-- Left Panel
PanelLeft:SetPoint('LEFT', DataPanel, 68, 0)
PanelLeft:SetHeight(30)
PanelLeft:SetWidth(560 / 3)
PanelLeft:SetFrameStrata('LOW')
PanelLeft:SetFrameLevel(1)
 
-- -- Center Panel
PanelCenter:SetPoint('CENTER', DataPanel, 0, 0)
PanelCenter:SetHeight(30)
PanelCenter:SetWidth(560 / 3)
PanelCenter:SetFrameStrata('LOW')
PanelCenter:SetFrameLevel(1)
 
-- Right panel
PanelRight:SetPoint('RIGHT', DataPanel, -5, 0)
PanelRight:SetHeight(30)
PanelRight:SetWidth(560 / 3)
PanelRight:SetFrameStrata('LOW')
PanelRight:SetFrameLevel(1)
 
-- Battleground Panel
BattleGroundPanel:SetAllPoints(PanelLeft)
BattleGroundPanel:SetFrameStrata('LOW')
BattleGroundPanel:SetFrameLevel(1)
 
end
 
 
-- move some frames to make way for the datapanel
if C['datatext'].top == true then
 
local top = function() end
PlayerFrame:ClearAllPoints() PlayerFrame:SetPoint("TOPLEFT", -19, -20) PlayerFrame.ClearAllPoints = top PlayerFrame.SetPoint = top
TargetFrame:ClearAllPoints() TargetFrame:SetPoint("TOPLEFT", 250, -20) TargetFrame.ClearAllPoints = top TargetFrame.SetPoint = top
MinimapCluster:ClearAllPoints() MinimapCluster:SetPoint('TOPRIGHT', 0, -32) MinimapCluster.ClearAllPoints = top MinimapCluster.SetPoint = top
BuffFrame:ClearAllPoints() BuffFrame:SetPoint('TOP', MinimapCluster, -110, -2) BuffFrame.ClearAllPoints = top BuffFrame.SetPoint = top
WorldStateAlwaysUpFrame:ClearAllPoints() WorldStateAlwaysUpFrame:SetPoint('TOP', 0, -32) WorldStateAlwaysUpFrame.ClearAllpoints = top WorldStateAlwaysUpFrame.Setpoint = top
 
else
 
-- Move the Bags above the Actionbar
CONTAINER_WIDTH = 192;
CONTAINER_SPACING = 5;
VISIBLE_CONTAINER_SPACING = 3;
CONTAINER_OFFSET_Y = 70;
CONTAINER_OFFSET_X = 0;
 
 
function UpdateContainerFrameAnchors()
local _, xOffset, yOffset, _, _, _, _;
local containerScale = 1;
screenHeight = GetScreenHeight() / containerScale;
-- Adjust the start anchor for bags depending on the multibars
xOffset = CONTAINER_OFFSET_X / containerScale;
yOffset = CONTAINER_OFFSET_Y / containerScale + 25;
-- freeScreenHeight determines when to start a new column of bags
freeScreenHeight = screenHeight - yOffset;
column = 0;
for index, frameName in ipairs(ContainerFrame1.bags) do
frame = _G[frameName];
frame:SetScale(containerScale);
if ( index == 1 ) then
-- First bag
frame:SetPoint('BOTTOMRIGHT', frame:GetParent(), 'BOTTOMRIGHT', -xOffset, yOffset );
elseif ( freeScreenHeight < frame:GetHeight() ) then
-- Start a new column
column = column + 1;
freeScreenHeight = screenHeight - yOffset;
frame:SetPoint('BOTTOMRIGHT', frame:GetParent(), 'BOTTOMRIGHT', -(column * CONTAINER_WIDTH) - xOffset, yOffset );
else
-- Anchor to the previous bag
frame:SetPoint('BOTTOMRIGHT', ContainerFrame1.bags[index - 1], 'TOPRIGHT', 0, CONTAINER_SPACING);
end
freeScreenHeight = freeScreenHeight - frame:GetHeight() - VISIBLE_CONTAINER_SPACING;
end
end
 
-- Move some stuff for the panel on bottom.
 
local bottom = function() end
MainMenuBar:ClearAllPoints() MainMenuBar:SetPoint("BOTTOM", DataPanel, "TOP", 0, -3) MainMenuBar.ClearAllPoints = bottom MainMenuBar.SetPoint = bottom
PetBattleFrame.BottomFrame:ClearAllPoints() PetBattleFrame.BottomFrame:SetPoint("BOTTOM", DataPanel, "TOP", 0, -3) PetBattleFrame.BottomFrame.ClearAllPoints = bottom PetBattleFrame.BottomFrame.SetPoint = bottom
OverrideActionBar:ClearAllPoints() OverrideActionBar:SetPoint("BOTTOM", DataPanel, "TOP", 0, -3) OverrideActionBar.ClearAllPoints = bottom OverrideActionBar.SetPoint = bottom
PetActionBarFrame:ClearAllPoints() PetActionBarFrame:SetPoint("BOTTOM", MainMenuBar, "TOP", 40, 47) PetActionBarFrame.ClearAllPoints = bottom PetActionBarFrame.SetPoint = bottom
WorldStateAlwaysUpFrame:ClearAllPoints() WorldStateAlwaysUpFrame:SetPoint('TOP', -20, -40) WorldStateAlwaysUpFrame.ClearAllpoints = bottom WorldStateAlwaysUpFrame.Setpoint = bottom
BuffFrame:ClearAllPoints() BuffFrame:SetPoint('TOP', MinimapCluster, -110, -15) BuffFrame.ClearAllPoints = bottom BuffFrame.SetPoint = bottom
 
-- Move the tooltip above the Actionbar
if C["tooltip"].enable == true then
hooksecurefunc('GameTooltip_SetDefaultAnchor', function(self)
self:SetPoint('BOTTOMRIGHT', UIParent, -95, 135)
end)
end
 
 
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Battleground.lua New file
0,0 → 1,134
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- BG Datapanel
--------------------------------------------------------------
 
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].battleground == true then
 
--Map IDs
local WSG = 443
local TP = 626
local AV = 401
local SOTA = 512
local IOC = 540
local EOTS = 482
local TBFG = 736
local AB = 461
 
local bgframe = BattleGroundPanel
bgframe:SetScript('OnEnter', function(self)
local numScores = GetNumBattlefieldScores()
for i=1, numScores do
local name, killingBlows, honorableKills, deaths, honorGained, faction, race, class, classToken, damageDone, healingDone, bgRating, ratingChange = GetBattlefieldScore(i)
if ( name ) then
if ( name == UnitName('player') ) then
GameTooltip:SetOwner(self, 'ANCHOR_TOPLEFT', 0, 4)
GameTooltip:ClearLines()
GameTooltip:SetPoint('BOTTOM', self, 'TOP', 0, 1)
GameTooltip:ClearLines()
GameTooltip:AddLine("Stats for : "..hexa..name..hexb)
GameTooltip:AddLine' '
GameTooltip:AddDoubleLine("Killing Blows:", killingBlows,1,1,1)
GameTooltip:AddDoubleLine("Honorable Kills:", honorableKills,1,1,1)
GameTooltip:AddDoubleLine("Deaths:", deaths,1,1,1)
GameTooltip:AddDoubleLine("Honor Gained:", format('%d', honorGained),1,1,1)
GameTooltip:AddDoubleLine("Damage Done:", damageDone,1,1,1)
GameTooltip:AddDoubleLine("Healing Done:", healingDone,1,1,1)
--Add extra statistics to watch based on what BG you are in.
if curmapid == WSG or curmapid == TP then
GameTooltip:AddDoubleLine("Flags Captured:",GetBattlefieldStatData(i, 1),1,1,1)
GameTooltip:AddDoubleLine("Flags Returned:",GetBattlefieldStatData(i, 2),1,1,1)
elseif curmapid == EOTS then
GameTooltip:AddDoubleLine("Flags Captured:",GetBattlefieldStatData(i, 1),1,1,1)
elseif curmapid == AV then
GameTooltip:AddDoubleLine("Graveyards Assaulted:",GetBattlefieldStatData(i, 1),1,1,1)
GameTooltip:AddDoubleLine("Graveyards Defended:",GetBattlefieldStatData(i, 2),1,1,1)
GameTooltip:AddDoubleLine("Towers Assaulted:",GetBattlefieldStatData(i, 3),1,1,1)
GameTooltip:AddDoubleLine("Towers Defended:",GetBattlefieldStatData(i, 4),1,1,1)
elseif curmapid == SOTA then
GameTooltip:AddDoubleLine("Demolishers Destroyed:",GetBattlefieldStatData(i, 1),1,1,1)
GameTooltip:AddDoubleLine("Gates Destroyed:",GetBattlefieldStatData(i, 2),1,1,1)
elseif curmapid == IOC or curmapid == TBFG or curmapid == AB then
GameTooltip:AddDoubleLine("Bases Assaulted:",GetBattlefieldStatData(i, 1),1,1,1)
GameTooltip:AddDoubleLine("Bases Defended:",GetBattlefieldStatData(i, 2),1,1,1)
end
GameTooltip:Show()
end
end
end
end)
bgframe:SetScript('OnLeave', function(self) GameTooltip:Hide() end)
 
local Stat = CreateFrame('Frame')
Stat:EnableMouse(true)
 
local Text1 = BattleGroundPanel:CreateFontString(nil, 'OVERLAY')
Text1:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
Text1:SetPoint('LEFT', BattleGroundPanel, 30, 0)
Text1:SetHeight(DataPanel:GetHeight())
 
local Text2 = BattleGroundPanel:CreateFontString(nil, 'OVERLAY')
Text2:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
Text2:SetPoint('CENTER', BattleGroundPanel, 0, 0)
Text2:SetHeight(DataPanel:GetHeight())
 
local Text3 = BattleGroundPanel:CreateFontString(nil, 'OVERLAY')
Text3:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
Text3:SetPoint('RIGHT', BattleGroundPanel, -30, 0)
Text3:SetHeight(DataPanel:GetHeight())
 
local int = 2
local function Update(self, t)
int = int - t
if int < 0 then
local dmgtxt
RequestBattlefieldScoreData()
local numScores = GetNumBattlefieldScores()
for i=1, numScores do
local name, killingBlows, honorableKills, deaths, honorGained, faction, race, class, classToken, damageDone, healingDone, bgRating, ratingChange = GetBattlefieldScore(i)
if healingDone > damageDone then
dmgtxt = ("Healing : "..hexa..healingDone..hexb)
else
dmgtxt = ("Damage : "..hexa..damageDone..hexb)
end
if ( name ) then
if ( name == myname ) then
Text2:SetText("Honor : "..hexa..format('%d', honorGained)..hexb)
Text1:SetText(dmgtxt)
Text3:SetText("Killing Blows : "..hexa..killingBlows..hexb)
end
end
end
int = 0
end
end
 
--hide text when not in an bg
local function OnEvent(self, event)
if event == 'PLAYER_ENTERING_WORLD' then
local inInstance, instanceType = IsInInstance()
if inInstance and (instanceType == 'pvp') then
bgframe:Show()
PanelLeft:Hide()
else
Text1:SetText('')
Text2:SetText('')
Text3:SetText('')
bgframe:Hide()
PanelLeft:Show()
end
end
end
 
Stat:RegisterEvent('PLAYER_ENTERING_WORLD')
Stat:SetScript('OnEvent', OnEvent)
Stat:SetScript('OnUpdate', Update)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Friends.lua New file
0,0 → 1,358
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Friends Data Panel
--------------------------------------------------------------
 
if not C["datatext"].friends or C["datatext"].friends == 0 then return end
 
-- create a popup
StaticPopupDialogs["SET_BN_BROADCAST"] = {
text = BN_BROADCAST_TOOLTIP,
button1 = ACCEPT,
button2 = CANCEL,
hasEditBox = 1,
editBoxWidth = 350,
maxLetters = 127,
OnAccept = function(self) BNSetCustomMessage(self.editBox:GetText()) end,
OnShow = function(self) self.editBox:SetText(select(3, BNGetInfo()) ) self.editBox:SetFocus() end,
OnHide = ChatEdit_FocusActiveWindow,
EditBoxOnEnterPressed = function(self) BNSetCustomMessage(self:GetText()) self:GetParent():Hide() end,
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end,
timeout = 0,
exclusive = 1,
whileDead = 1,
hideOnEscape = 1
}
 
-- localized references for global functions (about 50% faster)
local join = string.join
local find = string.find
local format = string.format
local split = string.split
local sort = table.sort
local insert = table.insert
local sizeof = table.getn
 
-- for datatext display
local displayString = join("", hexa.."%s: "..hexb, "|cffffffff", "%d|r")
 
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata("MEDIUM")
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C["media"].font, C["datatext"].fontsize,'THINOUTLINE')
S.PP(C["datatext"].friends, Text)
 
 
local menuFrame = CreateFrame("Frame", "FriendRightClickMenu", UIParent, "UIDropDownMenuTemplate")
local menuList = {
{ text = OPTIONS_MENU, isTitle = true,notCheckable=true},
{ text = INVITE, hasArrow = true,notCheckable=true, },
{ text = CHAT_MSG_WHISPER_INFORM, hasArrow = true,notCheckable=true, },
{ text = PLAYER_STATUS, hasArrow = true, notCheckable=true,
menuList = {
{ text = "|cff2BC226"..AVAILABLE.."|r", notCheckable=true, func = function() if IsChatAFK() then SendChatMessage("", "AFK") elseif IsChatDND() then SendChatMessage("", "DND") end end },
{ text = "|cffE7E716"..DND.."|r", notCheckable=true, func = function() if not IsChatDND() then SendChatMessage("", "DND") end end },
{ text = "|cffFF0000"..AFK.."|r", notCheckable=true, func = function() if not IsChatAFK() then SendChatMessage("", "AFK") end end },
},
},
{ text = BN_BROADCAST_TOOLTIP, notCheckable=true, func = function() StaticPopup_Show("SET_BN_BROADCAST") end },
}
 
local function GetTableIndex(table, fieldIndex, value)
for k,v in ipairs(table) do
if v[fieldIndex] == value then return k end
end
return -1
end
 
local function inviteClick(self, arg1, arg2, checked)
menuFrame:Hide()
if type(arg1) ~= 'number' then
InviteUnit(arg1)
else
BNInviteFriend(arg1);
end
end
 
local function whisperClick(self,name,bnet)
menuFrame:Hide()
if bnet then
ChatFrame_SendSmartTell(name)
else
SetItemRef( "player:"..name, ("|Hplayer:%1$s|h[%1$s]|h"):format(name), "LeftButton" )
end
end
 
local levelNameString = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r"
local clientLevelNameString = "%s (|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r%s) |cff%02x%02x%02x%s|r"
local levelNameClassString = "|cff%02x%02x%02x%d|r %s%s%s"
local worldOfWarcraftString = "World of Warcraft"
local battleNetString = "Battle.NET"
local wowString = "WoW"
local totalOnlineString = "Online:" .. "%s/%s"
local tthead, ttsubh, ttoff = {r=0.4, g=0.78, b=1}, {r=0.75, g=0.9, b=1}, {r=.3,g=1,b=.3}
local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
local displayString = string.join("", "%s ", "%d|r")
local statusTable = { "|cffff0000[AFK]|r", "|cffff0000[DND]|r", "" }
local groupedTable = { "|cffaaaaaa*|r", "" }
local friendTable, BNTable = {}, {}
local totalOnline, BNTotalOnline = 0, 0
 
local function BuildFriendTable(total)
totalOnline = 0
wipe(friendTable)
local name, level, class, area, connected, status, note
for i = 1, total do
name, level, class, area, connected, status, note = GetFriendInfo(i)
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
 
if status == "<"..AFK..">" then
status = "|cffff0000[AFK]|r"
elseif status == "<"..DND..">" then
status = "|cffff0000[DND]|r"
end
 
friendTable[i] = { name, level, class, area, connected, status, note }
if connected then totalOnline = totalOnline + 1 end
end
end
 
local function UpdateFriendTable(total)
totalOnline = 0
local name, level, class, area, connected, status, note
for i = 1, #friendTable do
name, level, class, area, connected, status, note = GetFriendInfo(i)
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
 
-- get the correct index in our table
local index = GetTableIndex(friendTable, 1, name)
-- we cannot find a friend in our table, so rebuild it
if index == -1 then
BuildFriendTable(total)
break
end
-- update on-line status for all members
friendTable[index][5] = connected
-- update information only for on-line members
if connected then
friendTable[index][2] = level
friendTable[index][3] = class
friendTable[index][4] = area
friendTable[index][6] = status
friendTable[index][7] = note
totalOnline = totalOnline + 1
end
end
end
 
local function BuildBNTable(total)
BNTotalOnline = 0
wipe(BNTable)
 
for i = 1, total do
local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(i)
local hasFocus, _, _, realmName, realmID, faction, race, class, guild, zoneName, level, gameText = BNGetToonInfo(presenceID)
 
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
 
BNTable[i] = { presenceID, presenceName, battleTag, toonName, toonID, client, isOnline, isAFK, isDND, noteText, realmName, faction, race, class, zoneName, level }
if isOnline then BNTotalOnline = BNTotalOnline + 1 end
end
end
 
local function UpdateBNTable(total)
BNTotalOnline = 0
for i = 1, #BNTable do
-- get guild roster information
local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(i)
local hasFocus, _, _, realmName, realmID, faction, race, class, guild, zoneName, level, gameText = BNGetToonInfo(presenceID)
 
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
 
-- get the correct index in our table
local index = GetTableIndex(BNTable, 1, presenceID)
-- we cannot find a BN member in our table, so rebuild it
if index == -1 then
BuildBNTable(total)
return
end
-- update on-line status for all members
BNTable[index][7] = isOnline
-- update information only for on-line members
if isOnline then
BNTable[index][2] = presenceName
BNTable[index][3] = battleTag
BNTable[index][4] = toonName
BNTable[index][5] = toonID
BNTable[index][6] = client
BNTable[index][8] = isAFK
BNTable[index][9] = isDND
BNTable[index][10] = noteText
BNTable[index][11] = realmName
BNTable[index][12] = faction
BNTable[index][13] = race
BNTable[index][14] = class
BNTable[index][15] = zoneName
BNTable[index][16] = level
 
BNTotalOnline = BNTotalOnline + 1
end
end
end
 
Stat:SetScript("OnMouseUp", function(self, btn)
if btn ~= "RightButton" then return end
 
GameTooltip:Hide()
 
local menuCountWhispers = 0
local menuCountInvites = 0
local classc, levelc
 
menuList[2].menuList = {}
menuList[3].menuList = {}
 
if totalOnline > 0 then
for i = 1, #friendTable do
if (friendTable[i][5]) then
menuCountInvites = menuCountInvites + 1
menuCountWhispers = menuCountWhispers + 1
 
classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[friendTable[i][3]], GetQuestDifficultyColor(friendTable[i][2])
if classc == nil then classc = GetQuestDifficultyColor(friendTable[i][2]) end
 
menuList[2].menuList[menuCountInvites] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],classc.r*255,classc.g*255,classc.b*255,friendTable[i][1]), arg1 = friendTable[i][1],notCheckable=true, func = inviteClick}
menuList[3].menuList[menuCountWhispers] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],classc.r*255,classc.g*255,classc.b*255,friendTable[i][1]), arg1 = friendTable[i][1],notCheckable=true, func = whisperClick}
end
end
end
 
if BNTotalOnline > 0 then
local realID, grouped
for i = 1, #BNTable do
if (BNTable[i][7]) then
realID = BNTable[i][2]
menuCountWhispers = menuCountWhispers + 1
menuList[3].menuList[menuCountWhispers] = {text = realID, arg1 = realID, arg2 = true, notCheckable=true, func = whisperClick}
 
if BNTable[i][6] == wowString and UnitFactionGroup("player") == BNTable[i][12] then
classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[BNTable[i][14]], GetQuestDifficultyColor(BNTable[i][16])
if classc == nil then classc = GetQuestDifficultyColor(BNTable[i][16]) end
 
if UnitInParty(BNTable[i][4]) or UnitInRaid(BNTable[i][4]) then grouped = 1 else grouped = 2 end
menuCountInvites = menuCountInvites + 1
menuList[2].menuList[menuCountInvites] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,BNTable[i][16],classc.r*255,classc.g*255,classc.b*255,BNTable[i][4]), arg1 = BNTable[i][5],notCheckable=true, func = inviteClick}
end
end
end
end
 
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
end)
 
local function Update(self, event)
if event == "BN_FRIEND_INFO_CHANGED" or "BN_FRIEND_ACCOUNT_ONLINE" or "BN_FRIEND_ACCOUNT_OFFLINE" or "BN_TOON_NAME_UPDATED"
or "BN_FRIEND_TOON_ONLINE" or "BN_FRIEND_TOON_OFFLINE" or "PLAYER_ENTERING_WORLD" then
local BNTotal = BNGetNumFriends()
if BNTotal == #BNTable then
UpdateBNTable(BNTotal)
else
BuildBNTable(BNTotal)
end
end
 
if event == "FRIENDLIST_UPDATE" or "PLAYER_ENTERING_WORLD" then
local total = GetNumFriends()
if total == #friendTable then
UpdateFriendTable(total)
else
BuildFriendTable(total)
end
end
 
Text:SetFormattedText(displayString, hexa.."Friends:"..hexb, totalOnline + BNTotalOnline)
self:SetAllPoints(Text)
end
 
Stat:SetScript("OnMouseDown", function(self, btn) if btn == "LeftButton" then ToggleFriendsFrame(1) end end)
Stat:SetScript("OnEnter", function(self)
if InCombatLockdown() then return end
 
local totalonline = totalOnline + BNTotalOnline
local totalfriends = #friendTable + #BNTable
local zonec, classc, levelc, realmc, grouped
if totalonline > 0 then
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Friends")
GameTooltip:AddLine' '
GameTooltip:AddLine( format(totalOnlineString, totalonline, totalfriends),tthead.r,tthead.g,tthead.b)
if totalOnline > 0 then
GameTooltip:AddLine(' ')
GameTooltip:AddLine(worldOfWarcraftString)
for i = 1, #friendTable do
if friendTable[i][5] then
if GetRealZoneText() == friendTable[i][4] then zonec = activezone else zonec = inactivezone end
classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[friendTable[i][3]], GetQuestDifficultyColor(friendTable[i][2])
if classc == nil then classc = GetQuestDifficultyColor(friendTable[i][2]) end
 
if UnitInParty(friendTable[i][1]) or UnitInRaid(friendTable[i][1]) then grouped = 1 else grouped = 2 end
GameTooltip:AddDoubleLine(format(levelNameClassString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],friendTable[i][1],groupedTable[grouped]," "..friendTable[i][6]),friendTable[i][4],classc.r,classc.g,classc.b,zonec.r,zonec.g,zonec.b)
end
end
end
if BNTotalOnline > 0 then
GameTooltip:AddLine(' ')
GameTooltip:AddLine(battleNetString)
 
local status = 0
for i = 1, #BNTable do
if BNTable[i][7] then
if BNTable[i][6] == wowString then
if (BNTable[i][8] == true) then status = 1 elseif (BNTable[i][9] == true) then status = 2 else status = 3 end
 
classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[BNTable[i][14]], GetQuestDifficultyColor(BNTable[i][16])
if classc == nil then classc = GetQuestDifficultyColor(BNTable[i][16]) end
 
if UnitInParty(BNTable[i][4]) or UnitInRaid(BNTable[i][4]) then grouped = 1 else grouped = 2 end
GameTooltip:AddDoubleLine(format(clientLevelNameString, BNTable[i][6],levelc.r*255,levelc.g*255,levelc.b*255,BNTable[i][16],classc.r*255,classc.g*255,classc.b*255,BNTable[i][4],groupedTable[grouped], 255, 0, 0, statusTable[status]),BNTable[i][2],238,238,238,238,238,238)
if IsShiftKeyDown() then
if GetRealZoneText() == BNTable[i][15] then zonec = activezone else zonec = inactivezone end
if GetRealmName() == BNTable[i][11] then realmc = activezone else realmc = inactivezone end
GameTooltip:AddDoubleLine(" ".."Zone: "..BNTable[i][15], "Realm: "..BNTable[i][11], zonec.r, zonec.g, zonec.b, realmc.r, realmc.g, realmc.b)
end
else
GameTooltip:AddDoubleLine("|cffeeeeee"..BNTable[i][6].." ("..BNTable[i][4]..")|r", "|cffeeeeee"..BNTable[i][2].."|r")
end
end
end
end
GameTooltip:AddLine' '
GameTooltip:AddLine("|cffeda55fLeft Click|r to Open Friend Panel")
GameTooltip:AddLine("|cffeda55fHold Shift & Mouseover|r to See Friend's Zone/Realm")
GameTooltip:AddLine("|cffeda55fRight Click|r to open Options Menu")
GameTooltip:Show()
else
GameTooltip:Hide()
end
end)
 
Stat:RegisterEvent("BN_FRIEND_ACCOUNT_ONLINE")
Stat:RegisterEvent("BN_FRIEND_ACCOUNT_OFFLINE")
Stat:RegisterEvent("BN_FRIEND_INFO_CHANGED")
Stat:RegisterEvent("BN_FRIEND_TOON_ONLINE")
Stat:RegisterEvent("BN_FRIEND_TOON_OFFLINE")
Stat:RegisterEvent("BN_TOON_NAME_UPDATED")
Stat:RegisterEvent("FRIENDLIST_UPDATE")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
 
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:SetScript("OnEvent", Update)
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Spec.lua New file
0,0 → 1,100
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Spec Data Panel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].spec and C['datatext'].spec > 0 then
 
local Stat = CreateFrame('Frame')
Stat:EnableMouse(true)
Stat:SetFrameStrata('BACKGROUND')
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, 'OVERLAY')
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].spec, Text)
 
local talent = {}
local active
local talentString = string.join('', '|cffFFFFFF%s|r ')
local talentStringTip = string.join('', '|cffFFFFFF%s:|r ')
local activeString = string.join('', '|cff00FF00' , ACTIVE_PETS, '|r')
local inactiveString = string.join('', '|cffFF0000', FACTION_INACTIVE, '|r')
 
 
local int = 1
local function Update(self, t)
int = int - t
if int > 0 or not GetSpecialization () then return end
 
active = GetActiveSpecGroup(false, false)
Text:SetFormattedText(talentString, hexa..select(2, GetSpecializationInfo (GetSpecialization (false, false, active)))..hexb)
int = 1
 
-- disable script
self:SetScript('OnUpdate', nil)
end
 
 
Stat:SetScript('OnEnter', function(self)
if InCombatLockdown() then return end
 
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
 
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Spec")
GameTooltip:AddLine' '
for i = 1, GetNumSpecGroups () do
if GetSpecialization (false, false, i) then
GameTooltip:AddLine(string.join(' ', string.format(talentStringTip, select(2, GetSpecializationInfo (GetSpecialization (false, false, i)))), (i == active and activeString or inactiveString)),1,1,1)
end
end
 
GameTooltip:AddLine' '
GameTooltip:AddLine("|cffeda55fLeft Click|r to Switch Spec's")
GameTooltip:AddLine("|cffeda55fRight Click|r to Open Talent Tree")
GameTooltip:Show()
end)
 
Stat:SetScript('OnLeave', function() GameTooltip:Hide() end)
 
local function OnEvent(self, event, ...)
if event == 'PLAYER_ENTERING_WORLD' then
self:UnregisterEvent('PLAYER_ENTERING_WORLD')
end
 
 
-- Setup Talents Tooltip
self:SetAllPoints(Text)
 
-- update datatext
if event ~= 'PLAYER_ENTERING_WORLD' then
self:SetScript('OnUpdate', Update)
end
end
 
 
 
Stat:RegisterEvent('PLAYER_ENTERING_WORLD');
Stat:RegisterEvent('CHARACTER_POINTS_CHANGED');
Stat:RegisterEvent('PLAYER_TALENT_UPDATE');
Stat:RegisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
Stat:RegisterEvent("EQUIPMENT_SETS_CHANGED")
Stat:SetScript('OnEvent', OnEvent)
Stat:SetScript('OnUpdate', Update)
 
Stat:SetScript("OnMouseDown", function(self, button)
if button == "LeftButton" then
SetActiveSpecGroup (active == 1 and 2 or 1)
elseif button == "RightButton" then
ToggleTalentFrame()
end
end)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Stat1.lua New file
0,0 → 1,210
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Stat Data Panel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].stat1 and C['datatext'].stat1 > 0 then
 
local Stat = CreateFrame("Frame")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:SetFrameStrata("BACKGROUND")
Stat:SetFrameLevel(3)
Stat:EnableMouse(true)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].stat1, Text)
 
local format = string.format
local targetlv, playerlv = UnitLevel("target"), UnitLevel("player")
local basemisschance, leveldifference, dodge, parry, block
local chanceString = "%.2f%%"
local modifierString = string.join("", "%d (+", chanceString, ")")
local manaRegenString = "%d / %d"
local displayNumberString = string.join("", "%s", "%d|r")
local displayFloatString = string.join("", "%s", "%.2f%%|r")
local spellpwr, avoidance, pwr
local haste, hasteBonus
local level = UnitLevel("player")
 
local function ShowTooltip(self)
if InCombatLockdown() then return end
 
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Statistics")
GameTooltip:AddLine' '
 
if S.Role == "Tank" then
if targetlv > 1 then
GameTooltip:AddDoubleLine("Avoidance Breakdown", string.join("", " (", "lvl", " ", targetlv, ")"))
elseif targetlv == -1 then
GameTooltip:AddDoubleLine("Avoidance Breakdown", string.join("", " (", "Boss", ")"))
else
GameTooltip:AddDoubleLine("Avoidance Breakdown", string.join("", " (", "lvl", " ", playerlv, ")"))
end
GameTooltip:AddLine' '
GameTooltip:AddDoubleLine(DODGE_CHANCE, format(chanceString, dodge),1,1,1)
GameTooltip:AddDoubleLine(PARRY_CHANCE, format(chanceString, parry),1,1,1)
GameTooltip:AddDoubleLine(BLOCK_CHANCE, format(chanceString, block),1,1,1)
GameTooltip:AddDoubleLine(MISS_CHANCE, format(chanceString, basemisschance),1,1,1)
elseif S.Role == "Caster" then
GameTooltip:AddDoubleLine(STAT_HIT_CHANCE, format(modifierString, GetCombatRating(CR_HIT_SPELL), GetCombatRatingBonus(CR_HIT_SPELL)), 1, 1, 1)
GameTooltip:AddDoubleLine(STAT_HASTE, format(modifierString, GetCombatRating(CR_HASTE_SPELL), GetCombatRatingBonus(CR_HASTE_SPELL)), 1, 1, 1)
local base, combat = GetManaRegen()
GameTooltip:AddDoubleLine(MANA_REGEN, format(manaRegenString, base * 5, combat * 5), 1, 1, 1)
elseif S.Role == "Melee" then
local hit = S.myclass == "HUNTER" and GetCombatRating(CR_HIT_RANGED) or GetCombatRating(CR_HIT_MELEE)
local hitBonus = S.myclass == "HUNTER" and GetCombatRatingBonus(CR_HIT_RANGED) or GetCombatRatingBonus(CR_HIT_MELEE)
 
GameTooltip:AddDoubleLine(STAT_HIT_CHANCE, format(modifierString, hit, hitBonus), 1, 1, 1)
 
--Hunters don't use expertise
--[[if S.myclass ~= "HUNTER" then
local expertisePercent, offhandExpertisePercent = GetExpertisePercent()
expertisePercent = format("%.2f", expertisePercent)
offhandExpertisePercent = format("%.2f", offhandExpertisePercent)
 
local expertisePercentDisplay
if IsDualWielding() then
expertisePercentDisplay = expertisePercent.."% / "..offhandExpertisePercent.."%"
else
expertisePercentDisplay = expertisePercent.."%"
end
GameTooltip:AddDoubleLine(COMBAT_RATING_NAME24, format('%d (+%s)', GetCombatRating(CR_EXPERTISE), expertisePercentDisplay), 1, 1, 1)
end]]
 
local haste = S.myclass == "HUNTER" and GetCombatRating(CR_HASTE_RANGED) or GetCombatRating(CR_HASTE_MELEE)
local hasteBonus = S.myclass == "HUNTER" and GetCombatRatingBonus(CR_HASTE_RANGED) or GetCombatRatingBonus(CR_HASTE_MELEE)
 
GameTooltip:AddDoubleLine(STAT_HASTE, format(modifierString, haste, hasteBonus), 1, 1, 1)
end
 
local masteryspell
if GetCombatRating(CR_MASTERY) ~= 0 and GetSpecialization () then
if S.myclass == "DRUID" then
if S.Role == "Melee" then
masteryspell = select(2, GetSpecializationMasterySpells(GetSpecialization ()))
elseif S.Role == "Tank" then
masteryspell = select(1, GetSpecializationMasterySpells(GetSpecialization ()))
else
masteryspell = GetSpecializationMasterySpells(GetSpecialization ())
end
else
masteryspell = GetSpecializationMasterySpells(GetSpecialization ())
end
 
 
 
local masteryName, _, _, _, _, _, _, _, _ = GetSpellInfo(masteryspell)
if masteryName then
GameTooltip:AddLine' '
GameTooltip:AddDoubleLine(masteryName, format(modifierString, GetCombatRating(CR_MASTERY), GetCombatRatingBonus(CR_MASTERY)), 1, 1, 1)
end
end
 
GameTooltip:Show()
end
 
local function UpdateTank(self)
 
-- the 5 is for base miss chance
if targetlv == -1 then
basemisschance = (5 - (3*.2))
leveldifference = 3
elseif targetlv > playerlv then
basemisschance = (5 - ((targetlv - playerlv)*.2))
leveldifference = (targetlv - playerlv)
elseif targetlv < playerlv and targetlv > 0 then
basemisschance = (5 + ((playerlv - targetlv)*.2))
leveldifference = (targetlv - playerlv)
else
basemisschance = 5
leveldifference = 0
end
 
if select(2, UnitRace("player")) == "NightElf" then basemisschance = basemisschance + 2 end
 
if leveldifference >= 0 then
dodge = (GetDodgeChance()-leveldifference*.2)
parry = (GetParryChance()-leveldifference*.2)
block = (GetBlockChance()-leveldifference*.2)
else
dodge = (GetDodgeChance()+abs(leveldifference*.2))
parry = (GetParryChance()+abs(leveldifference*.2))
block = (GetBlockChance()+abs(leveldifference*.2))
end
 
if dodge <= 0 then dodge = 0 end
if parry <= 0 then parry = 0 end
if block <= 0 then block = 0 end
 
if S.myclass == "DRUID" then
parry = 0
block = 0
elseif S.myclass == "DEATHKNIGHT" then
block = 0
end
avoidance = (dodge+parry+block+basemisschance)
 
Text:SetFormattedText(displayFloatString, hexa.."AVD: "..hexb, avoidance)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
local function UpdateCaster(self)
if GetSpellBonusHealing() > GetSpellBonusDamage(7) then
spellpwr = GetSpellBonusHealing()
else
spellpwr = GetSpellBonusDamage(7)
end
 
Text:SetFormattedText(displayNumberString, hexa.."SP: "..hexb, spellpwr)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
local function UpdateMelee(self)
local base, posBuff, negBuff = UnitAttackPower("player");
local effective = base + posBuff + negBuff;
local Rbase, RposBuff, RnegBuff = UnitRangedAttackPower("player");
local Reffective = Rbase + RposBuff + RnegBuff;
 
if S.myclass == "HUNTER" then
pwr = Reffective
else
pwr = effective
end
 
Text:SetFormattedText(displayNumberString, hexa.."AP: "..hexb, pwr)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
-- initial delay for update (let the ui load)
local int = 5
local function Update(self, t)
int = int - t
if int > 0 then return end
if S.Role == "Tank" then
UpdateTank(self)
elseif S.Role == "Caster" then
UpdateCaster(self)
elseif S.Role == "Melee" then
UpdateMelee(self)
end
int = 2
end
 
Stat:SetScript("OnEnter", function() ShowTooltip(Stat) end)
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:SetScript("OnUpdate", Update)
Update(Stat, 10)
end
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Stat2.lua New file
0,0 → 1,148
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Stats 2 Data Panel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].stat2 and C['datatext'].stat2 > 0 then
 
local Stat = CreateFrame("Frame")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:SetFrameStrata("BACKGROUND")
Stat:SetFrameLevel(3)
Stat:EnableMouse(true)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].stat2, Text)
 
local _G = getfenv(0)
local format = string.format
local chanceString = "%.2f%%"
local armorString = hexa..ARMOR..hexb..": "
local modifierString = string.join("", "%d (+", chanceString, ")")
local baseArmor, effectiveArmor, armor, posBuff, negBuff
local displayNumberString = string.join("", "%s", "%d|r")
local displayFloatString = string.join("", "%s", "%.2f%%|r")
local level = UnitLevel("player")
 
 
local function CalculateMitigation(level, effective)
local mitigation
 
if not effective then
_, effective, _, _, _ = UnitArmor("player")
end
 
if level < 60 then
mitigation = (effective/(effective + 400 + (85 * level)));
else
mitigation = (effective/(effective + (467.5 * level - 22167.5)));
end
if mitigation > .75 then
mitigation = .75
end
return mitigation
end
 
local function AddTooltipHeader(description)
GameTooltip:AddLine(description)
GameTooltip:AddLine(' ')
end
 
local function ShowTooltip(self)
if InCombatLockdown() then return end
 
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Statistics")
GameTooltip:AddLine' '
 
if S.Role == "Tank" then
AddTooltipHeader("Mitigation By Level: ")
local lv = level +3
for i = 1, 4 do
GameTooltip:AddDoubleLine(lv,format(chanceString, CalculateMitigation(lv, effectiveArmor) * 100),1,1,1)
lv = lv - 1
end
lv = UnitLevel("target")
if lv and lv > 0 and (lv > level + 3 or lv < level) then
GameTooltip:AddDoubleLine(lv, format(chanceString, CalculateMitigation(lv, effectiveArmor) * 100),1,1,1)
end
elseif S.Role == "Caster" or S.Role == "Melee" then
AddTooltipHeader(MAGIC_RESISTANCES_COLON)
 
local baseResistance, effectiveResistance, posResitance, negResistance
for i = 2, 6 do
baseResistance, effectiveResistance, posResitance, negResistance = UnitResistance("player", i)
GameTooltip:AddDoubleLine(_G["DAMAGE_SCHOOL"..(i+1)], format(chanceString, (effectiveResistance / (effectiveResistance + (500 + level + 2.5))) * 100),1,1,1)
end
 
local spellpen = GetSpellPenetration()
if (S.myclass == "SHAMAN" or S.Role == "Caster") and spellpen > 0 then
GameTooltip:AddLine' '
GameTooltip:AddDoubleLine(ITEM_MOD_SPELL_PENETRATION_SHORT, spellpen,1,1,1)
end
end
GameTooltip:Show()
end
 
local function UpdateTank(self)
baseArmor, effectiveArmor, armor, posBuff, negBuff = UnitArmor("player");
 
Text:SetFormattedText(displayNumberString, armorString, effectiveArmor)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
local function UpdateCaster(self)
local spellcrit = GetSpellCritChance(1)
 
Text:SetFormattedText(displayFloatString, hexa.."Crit: "..hexb, spellcrit)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
local function UpdateMelee(self)
local meleecrit = GetCritChance()
local rangedcrit = GetRangedCritChance()
local critChance
 
if S.myclass == "HUNTER" then
critChance = rangedcrit
else
critChance = meleecrit
end
 
Text:SetFormattedText(displayFloatString, hexa.."Crit: "..hexb, critChance)
--Setup Tooltip
self:SetAllPoints(Text)
end
 
-- initial delay for update (let the ui load)
local int = 5
local function Update(self, t)
int = int - t
if int > 0 then return end
 
if S.Role == "Tank" then
UpdateTank(self)
elseif S.Role == "Caster" then
UpdateCaster(self)
elseif S.Role == "Melee" then
UpdateMelee(self)
end
int = 2
end
 
Stat:SetScript("OnEnter", function() ShowTooltip(Stat) end)
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:SetScript("OnUpdate", Update)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Time.lua New file
0,0 → 1,217
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function; C - config; Soop - Database
 
--[[
 
All Credit for Time.lua goes to Tuks.
Tukui = http://www.tukui.org/download.php.
Edited by Cokedriver.
 
]]
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].wowtime and C['datatext'].wowtime > 0 then
 
local europeDisplayFormat = string.join("", "%02d", ":|r%02d")
local ukDisplayFormat = string.join("", "", "%d", ":|r%02d", " %s|r")
local timerLongFormat = "%d:%02d:%02d"
local timerShortFormat = "%d:%02d"
local lockoutInfoFormat = "%s |cffaaaaaa(%s%s, %s/%s)"
local formatBattleGroundInfo = "%s: "
local lockoutColorExtended, lockoutColorNormal = { r=0.3,g=1,b=0.3 }, { r=1,g=1,b=1 }
local difficultyInfo = { "N", "N", "H", "H" }
local curHr, curMin, curAmPm
 
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata("MEDIUM")
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, 'OVERLAY')
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].wowtime, Text)
 
local APM = { TIMEMANAGER_PM, TIMEMANAGER_AM }
 
local function CalculateTimeValues(tt)
if tt == nil then tt = false end
local Hr, Min, AmPm
if tt == true then
if C['datatext'].localtime == true then
Hr, Min = GetGameTime()
if C['datatext'].time24 == true then
return Hr, Min, -1
else
if Hr>=12 then
if Hr>12 then Hr = Hr - 12 end
AmPm = 1
else
if Hr == 0 then Hr = 12 end
AmPm = 2
end
return Hr, Min, AmPm
end
else
local Hr24 = tonumber(date("%H"))
Hr = tonumber(date("%I"))
Min = tonumber(date("%M"))
if C['datatext'].time24 == true then
return Hr24, Min, -1
else
if Hr24>=12 then AmPm = 1 else AmPm = 2 end
return Hr, Min, AmPm
end
end
else
if C['datatext'].localtime == true then
local Hr24 = tonumber(date("%H"))
Hr = tonumber(date("%I"))
Min = tonumber(date("%M"))
if C['datatext'].time24 == true then
return Hr24, Min, -1
else
if Hr24>=12 then AmPm = 1 else AmPm = 2 end
return Hr, Min, AmPm
end
else
Hr, Min = GetGameTime()
if C['datatext'].time24 == true then
return Hr, Min, -1
else
if Hr>=12 then
if Hr>12 then Hr = Hr - 12 end
AmPm = 1
else
if Hr == 0 then Hr = 12 end
AmPm = 2
end
return Hr, Min, AmPm
end
end
end
end
 
local function CalculateTimeLeft(time)
local hour = floor(time / 3600)
local min = floor(time / 60 - (hour*60))
local sec = time - (hour * 3600) - (min * 60)
 
return hour, min, sec
end
 
local function formatResetTime(sec,table)
local table = table or {}
local d,h,m,s = ChatFrame_TimeBreakDown(floor(sec))
local string = gsub(gsub(format(" %dd %dh %dm "..((d==0 and h==0) and "%ds" or ""),d,h,m,s)," 0[dhms]"," "),"%s+"," ")
local string = strtrim(gsub(string, "([dhms])", {d=table.days or "d",h=table.hours or "h",m=table.minutes or "m",s=table.seconds or "s"})," ")
return strmatch(string,"^%s*$") and "0"..(table.seconds or L"s") or string
end
 
local int = 1
local function Update(self, t)
int = int - t
if int > 0 then return end
 
local Hr, Min, AmPm = CalculateTimeValues()
 
if CalendarGetNumPendingInvites() > 0 then
Text:SetTextColor(1, 0, 0)
else
Text:SetTextColor(1, 1, 1)
end
 
-- no update quick exit
if (Hr == curHr and Min == curMin and AmPm == curAmPm) then
int = 2
return
end
 
curHr = Hr
curMin = Min
curAmPm = AmPm
 
if AmPm == -1 then
Text:SetFormattedText(europeDisplayFormat, Hr, Min)
else
Text:SetFormattedText(ukDisplayFormat, Hr, Min, hexa..APM[AmPm]..hexb)
end
 
self:SetAllPoints(Text)
int = 2
end
 
Stat:SetScript("OnEnter", function(self)
if InCombatLockdown() then return end
OnLoad = function(self) RequestRaidInfo() end
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Time")
GameTooltip:AddLine' '
 
local localizedName, isActive, canQueue, startTime, canEnter
for i = 1, GetNumWorldPVPAreas() do
_, localizedName, isActive, canQueue, startTime, canEnter = GetWorldPVPAreaInfo(i)
if canEnter then
if isActive then
startTime = WINTERGRASP_IN_PROGRESS
elseif startTime == nil then
startTime = QUEUE_TIME_UNAVAILABLE
else
local hour, min, sec = CalculateTimeLeft(startTime)
if hour > 0 then
startTime = string.format(timerLongFormat, hour, min, sec)
else
startTime = string.format(timerShortFormat, min, sec)
end
end
GameTooltip:AddDoubleLine(format(formatBattleGroundInfo, localizedName), startTime)
end
end
 
local timeText
local Hr, Min, AmPm = CalculateTimeValues(true)
 
if C['datatext'].localtime == true then
timeText = "Server Time: "
else
timeText = "Local Time: "
end
 
if AmPm == -1 then
GameTooltip:AddDoubleLine(timeText, string.format(europeDisplayFormat, Hr, Min))
else
GameTooltip:AddDoubleLine(timeText, string.format(ukDisplayFormat, Hr, Min, APM[AmPm]))
end
 
local oneraid, lockoutColor
for i = 1, GetNumSavedInstances() do
local name, _, reset, difficulty, locked, extended, _, isRaid, maxPlayers, _, numEncounters, encounterProgress = GetSavedInstanceInfo(i)
if isRaid and (locked or extended) then
local tr,tg,tb,diff
if not oneraid then
GameTooltip:AddLine(" ")
GameTooltip:AddLine("Saved Raid(s)")
oneraid = true
end
if extended then lockoutColor = lockoutColorExtended else lockoutColor = lockoutColorNormal end
GameTooltip:AddDoubleLine(format(name, maxPlayers, difficultyInfo[difficulty],encounterProgress,numEncounters), formatResetTime(reset), 1,1,1, lockoutColor.r,lockoutColor.g,lockoutColor.b)
end
end
GameTooltip:Show()
end)
 
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:RegisterEvent("CALENDAR_UPDATE_PENDING_INVITES")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:SetScript("OnUpdate", Update)
Stat:RegisterEvent("UPDATE_INSTANCE_INFO")
Stat:SetScript("OnMouseDown", function(self, btn)
if btn == 'RightButton' then
ToggleTimeManager()
else
GameTimeFrame:Click()
end
end)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Calltoarms.lua New file
0,0 → 1,128
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- CTA Datapanel
--------------------------------------------------------------
 
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].calltoarms and C['datatext'].calltoarms > 0 then
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata("MEDIUM")
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].calltoarms, Text)
 
local function MakeIconString(tank, healer, damage)
local str = ""
if tank then
str = str..'T'
end
if healer then
str = str..', H'
end
if damage then
str = str..', D'
end
 
return str
end
 
local function MakeString(tank, healer, damage)
local str = ""
if tank then
str = str..'Tank'
end
if healer then
str = str..', Healer'
end
if damage then
str = str..', DPS'
end
 
return str
end
 
local function OnEvent(self, event, ...)
local tankReward = false
local healerReward = false
local dpsReward = false
local unavailable = true
for i=1, GetNumRandomDungeons() do
local id, name = GetLFGRandomDungeonInfo(i)
for x = 1,LFG_ROLE_NUM_SHORTAGE_TYPES do
local eligible, forTank, forHealer, forDamage, itemCount = GetLFGRoleShortageRewards(id, x)
if eligible then unavailable = false end
if eligible and forTank and itemCount > 0 then tankReward = true end
if eligible and forHealer and itemCount > 0 then healerReward = true end
if eligible and forDamage and itemCount > 0 then dpsReward = true end
end
end
 
if unavailable then
Text:SetText(QUEUE_TIME_UNAVAILABLE)
else
Text:SetText(hexa..'C to A'..hexb.." : "..MakeIconString(tankReward, healerReward, dpsReward).." ")
end
 
self:SetAllPoints(Text)
end
 
local function OnEnter(self)
if InCombatLockdown() then return end
 
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Call to Arms")
GameTooltip:AddLine(' ')
 
local allUnavailable = true
local numCTA = 0
for i=1, GetNumRandomDungeons() do
local id, name = GetLFGRandomDungeonInfo(i)
local tankReward = false
local healerReward = false
local dpsReward = false
local unavailable = true
for x=1, LFG_ROLE_NUM_SHORTAGE_TYPES do
local eligible, forTank, forHealer, forDamage, itemCount = GetLFGRoleShortageRewards(id, x)
if eligible then unavailable = false end
if eligible and forTank and itemCount > 0 then tankReward = true end
if eligible and forHealer and itemCount > 0 then healerReward = true end
if eligible and forDamage and itemCount > 0 then dpsReward = true end
end
if not unavailable then
allUnavailable = false
local rolesString = MakeString(tankReward, healerReward, dpsReward)
if rolesString ~= "" then
GameTooltip:AddDoubleLine(name.." : ", rolesString..' ', 1, 1, 1)
end
if tankReward or healerReward or dpsReward then numCTA = numCTA + 1 end
end
end
 
if allUnavailable then
GameTooltip:AddLine("Could not get Call To Arms information.")
elseif numCTA == 0 then
GameTooltip:AddLine("Could not get Call To Arms information.")
end
GameTooltip:AddLine' '
GameTooltip:AddLine("|cffeda55fClick|r to Open Dungeon Finder")
GameTooltip:Show()
end
 
Stat:RegisterEvent("LFG_UPDATE_RANDOM_INFO")
Stat:RegisterEvent("PLAYER_LOGIN")
Stat:SetScript("OnEvent", OnEvent)
Stat:SetScript("OnMouseDown", function() ToggleFrame(LFDParentFrame) end)
Stat:SetScript("OnEnter", OnEnter)
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Colors.lua New file
0,0 → 1,22
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Colors
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
 
if C["general"].classcolor ~= true then
local r, g, b = C["general"].color.r, C["general"].color.g, C["general"].color.b
hexa = ("|cff%.2x%.2x%.2x"):format(r * 255, g * 255, b * 255)
hexb = "|r"
else
hexa = ("|cff%.2x%.2x%.2x"):format(S.ccolor.r * 255, S.ccolor.g * 255, S.ccolor.b * 255)
hexb = "|r"
end
 
 
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Guild.lua New file
0,0 → 1,253
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Data Panel (originally by Tuks of Tukui.org)
--------------------------------------------------------------
 
if not C["datatext"].guild or C["datatext"].guild == 0 then return end
 
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata("MEDIUM")
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C["media"].font, C["datatext"].fontsize,'THINOUTLINE')
S.PP(C["datatext"].guild, Text)
 
local tthead, ttsubh, ttoff = {r=0.4, g=0.78, b=1}, {r=0.75, g=0.9, b=1}, {r=.3,g=1,b=.3}
local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
local displayString = string.join("", hexa.."%s: "..hexb, "|cffffffff", "%d|r")
local guildInfoString0 = "%s"
local guildInfoString1 = "%s [%d]"
local guildInfoString2 = "%s: %d/%d"
local guildMotDString = "%s |cffaaaaaa- |cffffffff%s"
local levelNameString = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"
local levelNameStatusString = "|cff%02x%02x%02x%d|r %s %s"
local nameRankString = "%s |cff999999-|cffffffff %s"
local noteString = " '%s'"
local officerNoteString = " o: '%s'"
 
local guildTable, guildXP, guildMotD = {}, {}, ""
local totalOnline = 0
 
 
local function BuildGuildTable()
totalOnline = 0
wipe(guildTable)
local _, name, rank, level, zone, note, officernote, connected, status, class, isMobile
for i = 1, GetNumGuildMembers() do
name, rank, _, level, _, zone, note, officernote, connected, status, class, _, _, isMobile = GetGuildRosterInfo(i)
 
if status == 1 then
status = "|cffff0000["..AFK.."]|r"
elseif status == 2 then
status = "|cffff0000["..DND.."]|r"
else
status = ""
end
 
guildTable[i] = { name, rank, level, zone, note, officernote, connected, status, class, isMobile }
if connected then totalOnline = totalOnline + 1 end
end
table.sort(guildTable, function(a, b)
if a and b then
return a[1] < b[1]
end
end)
end
 
local function UpdateGuildXP()
local currentXP, remainingXP = UnitGetGuildXP("player")
local nextLevelXP = currentXP + remainingXP
 
-- prevent 4.3 division / 0
if nextLevelXP == 0 or maxDailyXP == 0 then return end
 
local percentTotal = tostring(math.ceil((currentXP / nextLevelXP) * 100))
 
guildXP[0] = { currentXP, nextLevelXP, percentTotal }
end
 
local function UpdateGuildMessage()
guildMotD = GetGuildRosterMOTD()
end
 
local function Update(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
if IsInGuild() and not GuildFrame then LoadAddOn("Blizzard_GuildUI") end
end
 
if IsInGuild() then
totalOnline = 0
local name, rank, level, zone, note, officernote, connected, status, class
for i = 1, GetNumGuildMembers() do
local connected = select(9, GetGuildRosterInfo(i))
if connected then totalOnline = totalOnline + 1 end
end
Text:SetFormattedText(displayString, "Guild", totalOnline)
else
Text:SetText("No Guild")
end
 
self:SetAllPoints(Text)
end
 
local menuFrame = CreateFrame("Frame", "GuildRightClickMenu", UIParent, "UIDropDownMenuTemplate")
local menuList = {
{ text = OPTIONS_MENU, isTitle = true,notCheckable=true},
{ text = INVITE, hasArrow = true,notCheckable=true,},
{ text = CHAT_MSG_WHISPER_INFORM, hasArrow = true,notCheckable=true,}
}
 
local function inviteClick(self, arg1, arg2, checked)
menuFrame:Hide()
InviteUnit(arg1)
end
 
local function whisperClick(self,arg1,arg2,checked)
menuFrame:Hide()
SetItemRef( "player:"..arg1, ("|Hplayer:%1$s|h[%1$s]|h"):format(arg1), "LeftButton" )
end
 
local function ToggleGuildFrame()
if IsInGuild() then
if not GuildFrame then LoadAddOn("Blizzard_GuildUI") end
GuildFrame_Toggle()
GuildFrame_TabClicked(GuildFrameTab2)
else
if not LookingForGuildFrame then LoadAddOn("Blizzard_LookingForGuildUI") end
LookingForGuildFrame_Toggle()
end
end
 
Stat:SetScript("OnMouseUp", function(self, btn)
if btn ~= "RightButton" or not IsInGuild() then return end
 
GameTooltip:Hide()
 
local classc, levelc, grouped
local menuCountWhispers = 0
local menuCountInvites = 0
 
menuList[2].menuList = {}
menuList[3].menuList = {}
 
for i = 1, #guildTable do
if (guildTable[i][7] and guildTable[i][1] ~= S.myname) then
local classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[guildTable[i][9]], GetQuestDifficultyColor(guildTable[i][3])
 
if UnitInParty(guildTable[i][1]) or UnitInRaid(guildTable[i][1]) then
grouped = "|cffaaaaaa*|r"
else
grouped = ""
if not guildTable[i][10] then
menuCountInvites = menuCountInvites + 1
menuList[2].menuList[menuCountInvites] = {text = string.format(levelNameString, levelc.r*255,levelc.g*255,levelc.b*255, guildTable[i][3], classc.r*255,classc.g*255,classc.b*255, guildTable[i][1], ""), arg1 = guildTable[i][1],notCheckable=true, func = inviteClick}
end
end
menuCountWhispers = menuCountWhispers + 1
menuList[3].menuList[menuCountWhispers] = {text = string.format(levelNameString, levelc.r*255,levelc.g*255,levelc.b*255, guildTable[i][3], classc.r*255,classc.g*255,classc.b*255, guildTable[i][1], grouped), arg1 = guildTable[i][1],notCheckable=true, func = whisperClick}
end
end
 
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
end)
 
Stat:SetScript("OnEnter", function(self)
if InCombatLockdown() or not IsInGuild() then return end
 
GuildRoster()
UpdateGuildMessage()
BuildGuildTable()
 
local name, rank, level, zone, note, officernote, connected, status, class, isMobile
local zonec, classc, levelc
local online = totalOnline
local guildName, guildRankName, guildRankIndex = GetGuildInfo("player");
local GuildInfo = GetGuildInfo('player')
local GuildLevel = GetGuildLevel()
 
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Guild")
if GuildInfo then
GameTooltip:AddDoubleLine(string.format(guildInfoString0, GuildInfo), string.format(guildInfoString1, "Guild Level:", GuildLevel),tthead.r,tthead.g,tthead.b,tthead.r,tthead.g,tthead.b)
end
GameTooltip:AddLine' '
if GuildLevel then
GameTooltip:AddLine( string.format(guildInfoString2, "Member's Online", online, #guildTable),tthead.r,tthead.g,tthead.b)
end
 
if guildMotD ~= "" then GameTooltip:AddLine(' ')
GameTooltip:AddLine(string.format(guildMotDString, GUILD_MOTD, guildMotD), ttsubh.r, ttsubh.g, ttsubh.b, 1)
end
 
local col = S.RGBToHex(ttsubh.r, ttsubh.g, ttsubh.b)
GameTooltip:AddLine' '
if GuildLevel and GuildLevel ~= 25 then
--UpdateGuildXP()
 
if guildXP[0] then
local currentXP, nextLevelXP, percentTotal = unpack(guildXP[0])
 
GameTooltip:AddLine(string.format(col..GUILD_EXPERIENCE_CURRENT, "|r |cFFFFFFFF"..S.ShortValue(currentXP), S.ShortValue(nextLevelXP), percentTotal))
end
end
 
local _, _, standingID, barMin, barMax, barValue = GetGuildFactionInfo()
if standingID ~= 8 then -- Not Max Rep
barMax = barMax - barMin
barValue = barValue - barMin
barMin = 0
GameTooltip:AddLine(string.format("%s:|r |cFFFFFFFF%s/%s (%s%%)",col..COMBAT_FACTION_CHANGE, S.ShortValue(barValue), S.ShortValue(barMax), math.ceil((barValue / barMax) * 100)))
end
 
if online > 1 then
GameTooltip:AddLine(' ')
for i = 1, #guildTable do
if online <= 1 then
if online > 1 then GameTooltip:AddLine(format("+ %d More...", online - modules.Guild.maxguild),ttsubh.r,ttsubh.g,ttsubh.b) end
break
end
 
name, rank, level, zone, note, officernote, connected, status, class, isMobile = unpack(guildTable[i])
if connected and name ~= S.myname then
if GetRealZoneText() == zone then zonec = activezone else zonec = inactivezone end
classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[class], GetQuestDifficultyColor(level)
 
if isMobile then zone = "" end
 
if IsShiftKeyDown() then
GameTooltip:AddDoubleLine(string.format(nameRankString, name, rank), zone, classc.r, classc.g, classc.b, zonec.r, zonec.g, zonec.b)
if note ~= "" then GameTooltip:AddLine(string.format(noteString, note), ttsubh.r, ttsubh.g, ttsubh.b, 1) end
if officernote ~= "" then GameTooltip:AddLine(string.format(officerNoteString, officernote), ttoff.r, ttoff.g, ttoff.b ,1) end
else
GameTooltip:AddDoubleLine(string.format(levelNameStatusString, levelc.r*255, levelc.g*255, levelc.b*255, level, name, status), zone, classc.r,classc.g,classc.b, zonec.r,zonec.g,zonec.b)
end
end
end
end
GameTooltip:AddLine' '
GameTooltip:AddLine("|cffeda55fLeft Click|r to Open Guild Roster")
GameTooltip:AddLine("|cffeda55fHold Shift & Mouseover|r to See Guild and Officer Note's")
GameTooltip:AddLine("|cffeda55fRight Click|r to open Options Menu")
GameTooltip:Show()
end)
 
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:SetScript("OnMouseDown", function(self, btn)
if btn ~= "LeftButton" then return end
ToggleGuildFrame()
end)
 
Stat:RegisterEvent("GUILD_ROSTER_SHOW")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:RegisterEvent("GUILD_ROSTER_UPDATE")
Stat:RegisterEvent("PLAYER_GUILD_UPDATE")
Stat:SetScript("OnEvent", Update)
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Durability.lua New file
0,0 → 1,90
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Durability Data Panel
--------------------------------------------------------------
 
if C["datatext"].enable ~= true then return end
 
if C["datatext"].dur and C["datatext"].dur > 0 then
 
Slots = {
[1] = {1, "Head", 1000},
[2] = {3, "Shoulder", 1000},
[3] = {5, "Chest", 1000},
[4] = {6, "Waist", 1000},
[5] = {9, "Wrist", 1000},
[6] = {10, "Hands", 1000},
[7] = {7, "Legs", 1000},
[8] = {8, "Feet", 1000},
[9] = {16, "Main Hand", 1000},
[10] = {17, "Off Hand", 1000},
[11] = {18, "Ranged", 1000}
}
 
 
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata("MEDIUM")
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C["media"].font, C["datatext"].fontsize,'THINOUTLINE')
S.PP(C["datatext"].dur, Text)
 
local function OnEvent(self)
local Total = 0
local current, max
 
for i = 1, 11 do
if GetInventoryItemLink("player", Slots[i][1]) ~= nil then
current, max = GetInventoryItemDurability(Slots[i][1])
if current then
Slots[i][3] = current/max
Total = Total + 1
end
end
end
table.sort(Slots, function(a, b) return a[3] < b[3] end)
 
if Total > 0 then
Text:SetText(hexa.."Armor: "..hexb..floor(Slots[1][3]*100).."% |r")
else
Text:SetText(hexa.."Armor: "..hexb.."100% |r")
end
-- Setup Durability Tooltip
self:SetAllPoints(Text)
Total = 0
end
 
Stat:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
Stat:RegisterEvent("MERCHANT_SHOW")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:SetScript("OnMouseDown", function() ToggleCharacter("PaperDollFrame") end)
Stat:SetScript("OnEvent", OnEvent)
Stat:SetScript("OnEnter", function(self)
if not InCombatLockdown() then
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Durability")
GameTooltip:AddLine' '
for i = 1, 11 do
if Slots[i][3] ~= 1000 then
local green, red
green = Slots[i][3]*2
red = 1 - green
GameTooltip:AddDoubleLine(Slots[i][2], floor(Slots[i][3]*100).."%",1 ,1 , 1, red + 1, green, 0)
end
end
GameTooltip:AddLine(" ")
GameTooltip:AddLine("|cffeda55fClick|r to Show Character Panel")
GameTooltip:Show()
end
end)
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
 
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Professions.lua New file
0,0 → 1,106
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Professions Datapanel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].pro and C['datatext'].pro > 0 then
 
local Stat = CreateFrame('Button')
Stat:RegisterEvent('PLAYER_ENTERING_WORLD')
Stat:SetFrameStrata('BACKGROUND')
Stat:SetFrameLevel(3)
Stat:EnableMouse(true)
Stat.tooltip = false
 
local Text = DataPanel:CreateFontString(nil, 'OVERLAY')
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].pro, Text)
 
local function Update(self)
for i = 1, select("#", GetProfessions()) do
local v = select(i, GetProfessions());
if v ~= nil then
local name, texture, rank, maxRank = GetProfessionInfo(v)
Text:SetFormattedText(hexa.."Professions"..hexb)
end
end
self:SetAllPoints(Text)
end
 
Stat:SetScript('OnEnter', function()
if InCombatLockdown() then return end
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Professions")
GameTooltip:AddLine' '
for i = 1, select("#", GetProfessions()) do
local v = select(i, GetProfessions());
if v ~= nil then
local name, texture, rank, maxRank = GetProfessionInfo(v)
GameTooltip:AddDoubleLine(name, rank..' / '..maxRank,.75,.9,1,.3,1,.3)
end
end
GameTooltip:AddLine' '
GameTooltip:AddLine("|cffeda55fLeft Click|r to Open Profession #1")
GameTooltip:AddLine("|cffeda55fMiddle Click|r to Open Spell Book")
GameTooltip:AddLine("|cffeda55fRight Click|r to Open Profession #2")
 
GameTooltip:Show()
end)
 
 
Stat:SetScript("OnClick",function(self,btn)
local prof1, prof2 = GetProfessions()
if btn == "LeftButton" then
if prof1 then
if (GetProfessionInfo(prof1) == (S.locale == "deDE" and "Kr\195\164uterkunde" or'Herbalism')) then
print('Soop: Herbalism doesnt have any options')
elseif(GetProfessionInfo(prof1) == (S.locale == "deDE" and "K\195\188rschnerei" or 'Skinning')) then
print('Soop: Skinning doesnt have any options')
elseif(GetProfessionInfo(prof1) == (S.locale == "deDE" and "Bergbau" or 'Mining')) then
if(S.locale == "deDE") then
CastSpellByName("Verh\195\188ttung")
else
CastSpellByName("Smelting")
end
else
CastSpellByName((GetProfessionInfo(prof1)))
end
else
print('Soop: No Profession Found')
end
elseif btn == 'MiddleButton' then
ToggleFrame(SpellBookFrame)
elseif btn == "RightButton" then
if prof2 then
if (GetProfessionInfo(prof2) == (S.locale == "deDE" and "Kräuterkunde" or'Herbalism')) then
print('Soop: Herbalism doesnt have any options')
elseif(GetProfessionInfo(prof2) == (S.locale == "deDE" and "K\195\188rschnerei" or 'Skinning')) then
print('Soop" Skinning doesnt have any options')
elseif(GetProfessionInfo(prof2) == (S.locale == "deDE" and "Bergbau" or 'Mining')) then
if(S.locale == "deDE") then
CastSpellByName("Verh\195\188ttung")
else
CastSpellByName("Smelting")
end
else
CastSpellByName((GetProfessionInfo(prof2)))
end
else
print('Soop: No profession found')
end
end
end)
 
 
Stat:RegisterForClicks("AnyUp")
Stat:SetScript('OnUpdate', Update)
Stat:SetScript('OnLeave', function() GameTooltip:Hide() end)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/Zone.lua New file
0,0 → 1,32
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- Zone Data Panel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].zone and C['datatext'].zone > 0 then
local Stat = CreateFrame("Frame")
Stat:EnableMouse(true)
Stat:SetFrameStrata('BACKGROUND')
Stat:SetFrameLevel(3)
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].zone, Text)
 
local function Update(self)
if GetMinimapZoneText() == "Putricide's Laboratory of Alchemical Horrors and Fun" then
Text:SetText("Putricides's Laboratory")
else
Text:SetText(hexa..GetMinimapZoneText()..hexb)
end
end
 
Stat:SetScript("OnUpdate", Update)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Datatext/System.lua New file
0,0 → 1,160
local S, C, Soop = unpack(select(2, ...)) -- Import driver S = Functions C = Config Soop = Database
 
 
 
 
--------------------------------------------------------------
-- System Data Panel
--------------------------------------------------------------
 
if C['datatext'].enable ~= true then return end
 
if C['datatext'].system and C['datatext'].system > 0 then
 
local Stat = CreateFrame("Frame")
Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
Stat:SetFrameStrata("BACKGROUND")
Stat:SetFrameLevel(3)
Stat:EnableMouse(true)
Stat.tooltip = false
 
local Text = DataPanel:CreateFontString(nil, "OVERLAY")
Text:SetFont(C['media'].font, C['datatext'].fontsize,'THINOUTLINE')
S.PP(C['datatext'].system, Text)
 
local bandwidthString = "%.2f Mbps"
local percentageString = "%.2f%%"
local homeLatencyString = "%d ms"
local worldLatencyString = "%d ms"
local kiloByteString = "%d kb"
local megaByteString = "%.2f mb"
 
local function formatMem(memory)
local mult = 10^1
if memory > 999 then
local mem = ((memory/1024) * mult) / mult
return string.format(megaByteString, mem)
else
local mem = (memory * mult) / mult
return string.format(kiloByteString, mem)
end
end
 
local memoryTable = {}
 
local function RebuildAddonList(self)
local addOnCount = GetNumAddOns()
if (addOnCount == #memoryTable) or self.tooltip == true then return end
 
-- Number of loaded addons changed, create new memoryTable for all addons
memoryTable = {}
for i = 1, addOnCount do
memoryTable[i] = { i, select(2, GetAddOnInfo(i)), 0, IsAddOnLoaded(i) }
end
self:SetAllPoints(Text)
end
 
local function UpdateMemory()
-- Update the memory usages of the addons
UpdateAddOnMemoryUsage()
-- Load memory usage in table
local addOnMem = 0
local totalMemory = 0
for i = 1, #memoryTable do
addOnMem = GetAddOnMemoryUsage(memoryTable[i][1])
memoryTable[i][3] = addOnMem
totalMemory = totalMemory + addOnMem
end
-- Sort the table to put the largest addon on top
table.sort(memoryTable, function(a, b)
if a and b then
return a[3] > b[3]
end
end)
 
return totalMemory
end
 
-- initial delay for update (let the ui load)
local int, int2 = 6, 5
local statusColors = {
"|cff0CD809",
"|cffE8DA0F",
"|cffFF9000",
"|cffD80909"
}
 
local function Update(self, t)
int = int - t
int2 = int2 - t
 
if int < 0 then
RebuildAddonList(self)
int = 10
end
if int2 < 0 then
local framerate = floor(GetFramerate())
local fpscolor = 4
local latency = select(4, GetNetStats())
local latencycolor = 4
 
if latency < 150 then
latencycolor = 1
elseif latency >= 150 and latency < 300 then
latencycolor = 2
elseif latency >= 300 and latency < 500 then
latencycolor = 3
end
if framerate >= 30 then
fpscolor = 1
elseif framerate >= 20 and framerate < 30 then
fpscolor = 2
elseif framerate >= 10 and framerate < 20 then
fpscolor = 3
end
local displayFormat = string.join("", hexa.."FPS: "..hexb, statusColors[fpscolor], "%d|r", hexa.." MS: "..hexb, statusColors[latencycolor], "%d|r")
Text:SetFormattedText(displayFormat, framerate, latency)
int2 = 1
end
end
Stat:SetScript("OnMouseDown", function () collectgarbage("collect") Update(Stat, 20) end)
Stat:SetScript("OnEnter", function(self)
if InCombatLockdown() then return end
local bandwidth = GetAvailableBandwidth()
local _, _, latencyHome, latencyWorld = GetNetStats()
local anchor, panel, xoff, yoff = S.DataTextTooltipAnchor(Text)
GameTooltip:SetOwner(panel, anchor, xoff, yoff)
GameTooltip:ClearLines()
GameTooltip:AddLine(hexa..S.myname.."'s"..hexb.." Latency")
GameTooltip:AddLine' '
if C['datatext'].fps.enable == true then
if C['datatext'].fps.home == true then
GameTooltip:AddDoubleLine("Home Latency: ", string.format(homeLatencyString, latencyHome), 0.80, 0.31, 0.31,0.84, 0.75, 0.65)
elseif C['datatext'].fps.world == true then
GameTooltip:AddDoubleLine("World Latency: ", string.format(worldLatencyString, latencyWorld), 0.80, 0.31, 0.31,0.84, 0.75, 0.65)
elseif C['datatext'].fps.both == true then
GameTooltip:AddDoubleLine("Home Latency: ", string.format(homeLatencyString, latencyHome), 0.80, 0.31, 0.31,0.84, 0.75, 0.65)
GameTooltip:AddDoubleLine("World Latency: ", string.format(worldLatencyString, latencyWorld), 0.80, 0.31, 0.31,0.84, 0.75, 0.65)
end
end
if bandwidth ~= 0 then
GameTooltip:AddDoubleLine(L.datatext_bandwidth , string.format(bandwidthString, bandwidth),0.69, 0.31, 0.31,0.84, 0.75, 0.65)
GameTooltip:AddDoubleLine("Download: " , string.format(percentageString, GetDownloadedPercentage() *100),0.69, 0.31, 0.31, 0.84, 0.75, 0.65)
GameTooltip:AddLine(" ")
end
local totalMemory = UpdateMemory()
GameTooltip:AddDoubleLine("Total Memory Usage:", formatMem(totalMemory), 0.69, 0.31, 0.31,0.84, 0.75, 0.65)
GameTooltip:AddLine(" ")
for i = 1, #memoryTable do
if (memoryTable[i][4]) then
local red = memoryTable[i][3] / totalMemory
local green = 1 - red
GameTooltip:AddDoubleLine(memoryTable[i][2], formatMem(memoryTable[i][3]), 1, 1, 1, red, green + .5, 0)
end
end
GameTooltip:Show()
end)
Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
Stat:SetScript("OnUpdate", Update)
Update(Stat, 10)
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Modules/Chat/Chat.lua New file
0,0 → 1,903
local S, C, Soop = unpack(select(2, ...)) -- Import driver || S = Functions || C = Config || Soop = Database
 
if C['chat'].enable ~= true then return end
 
 
 
--------------------------------------------------------------
-- Chat Module
--------------------------------------------------------------
FCF_ResetChatWindows()
FCF_OpenNewWindow("")
 
FCF_DockFrame(ChatFrame2)
FCF_DockFrame(ChatFrame3)
 
FCF_SetLocked(ChatFrame1, 1)
FCF_SetLocked(ChatFrame2, 1)
FCF_SetLocked(ChatFrame3, 1)
FCF_SetLocked(ChatFrame4, 1)
 
for i = 1, NUM_CHAT_WINDOWS do
local frame = _G[format("ChatFrame%s", i)]
local id = frame:GetID()
 
-- set default font size
FCF_SetChatWindowFontSize(nil, frame, 12)
 
-- rename windows general and combat log
if i == 1 then FCF_SetWindowName(frame, "Social") end
if i == 2 then FCF_SetWindowName(frame, "Combat") end
if i == 3 then FCF_SetWindowName(frame, "Loot") end
if i == 4 then FCF_SetWindowName(frame, "Trade.General") end
end
 
ChatFrame_RemoveAllMessageGroups(ChatFrame1)
ChatFrame_AddMessageGroup(ChatFrame1, "SAY")
ChatFrame_AddMessageGroup(ChatFrame1, "EMOTE")
ChatFrame_AddMessageGroup(ChatFrame1, "YELL")
ChatFrame_AddMessageGroup(ChatFrame1, "GUILD")
ChatFrame_AddMessageGroup(ChatFrame1, "OFFICER")
ChatFrame_AddMessageGroup(ChatFrame1, "GUILD_ACHIEVEMENT")
ChatFrame_AddMessageGroup(ChatFrame1, "WHISPER")
ChatFrame_AddMessageGroup(ChatFrame1, "BN_WHISPER")
ChatFrame_AddMessageGroup(ChatFrame1, "BN_CONVERSATION")
ChatFrame_AddMessageGroup(ChatFrame1, "BN_INLINE_TOAST_ALERT")
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_SAY")
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_EMOTE")
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_YELL")
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_BOSS_EMOTE")
ChatFrame_AddMessageGroup(ChatFrame1, "PARTY")
ChatFrame_AddMessageGroup(ChatFrame1, "PARTY_LEADER")
ChatFrame_AddMessageGroup(ChatFrame1, "RAID")
ChatFrame_AddMessageGroup(ChatFrame1, "RAID_LEADER")
ChatFrame_AddMessageGroup(ChatFrame1, "RAID_WARNING")
ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT")
ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT_LEADER")
ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND")
ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND_LEADER")
ChatFrame_AddMessageGroup(ChatFrame1, "BG_HORDE")
ChatFrame_AddMessageGroup(ChatFrame1, "BG_ALLIANCE")
ChatFrame_AddMessageGroup(ChatFrame1, "BG_NEUTRAL")
ChatFrame_AddMessageGroup(ChatFrame1, "SYSTEM")
ChatFrame_AddMessageGroup(ChatFrame1, "ERRORS")
ChatFrame_AddMessageGroup(ChatFrame1, "AFK")
ChatFrame_AddMessageGroup(ChatFrame1, "DND")
ChatFrame_AddMessageGroup(ChatFrame1, "IGNORED")
ChatFrame_AddMessageGroup(ChatFrame1, "ACHIEVEMENT")
ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_FACTION_CHANGE")
 
 
 
ChatFrame_RemoveAllMessageGroups(ChatFrame3)
ChatFrame_AddMessageGroup(ChatFrame3, "SKILL")
ChatFrame_AddMessageGroup(ChatFrame3, "LOOT")
ChatFrame_AddMessageGroup(ChatFrame3, "MONEY")
ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_XP_GAIN")
ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_HONOR_GAIN")
ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_GUILD_XP_GAIN")
 
ChatFrame_RemoveAllMessageGroups(ChatFrame5)
ChatFrame_AddMessageGroup(ChatFrame5, "General")
ChatFrame_AddMessageGroup(ChatFrame3, "Trade")
 
 
-- enable classcolor automatically on login and on each character without doing /configure each time.
ToggleChatColorNamesByClassGroup(true, "SAY")
ToggleChatColorNamesByClassGroup(true, "EMOTE")
ToggleChatColorNamesByClassGroup(true, "YELL")
ToggleChatColorNamesByClassGroup(true, "GUILD")
ToggleChatColorNamesByClassGroup(true, "OFFICER")
ToggleChatColorNamesByClassGroup(true, "GUILD_ACHIEVEMENT")
ToggleChatColorNamesByClassGroup(true, "ACHIEVEMENT")
ToggleChatColorNamesByClassGroup(true, "WHISPER")
ToggleChatColorNamesByClassGroup(true, "PARTY")
ToggleChatColorNamesByClassGroup(true, "PARTY_LEADER")
ToggleChatColorNamesByClassGroup(true, "RAID")
ToggleChatColorNamesByClassGroup(true, "RAID_LEADER")
ToggleChatColorNamesByClassGroup(true, "RAID_WARNING")
ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND")
ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND_LEADER")
ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT")
ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT_LEADER")
ToggleChatColorNamesByClassGroup(true, "CHANNEL1")
ToggleChatColorNamesByClassGroup(true, "CHANNEL2")
ToggleChatColorNamesByClassGroup(true, "CHANNEL3")
ToggleChatColorNamesByClassGroup(true, "CHANNEL4")
ToggleChatColorNamesByClassGroup(true, "CHANNEL5")
ToggleChatColorNamesByClassGroup(true, "CHANNEL6")
ToggleChatColorNamesByClassGroup(true, "CHANNEL7")
ToggleChatColorNamesByClassGroup(true, "CHANNEL8")
ToggleChatColorNamesByClassGroup(true, "CHANNEL9")
ToggleChatColorNamesByClassGroup(true, "CHANNEL10")
ToggleChatColorNamesByClassGroup(true, "CHANNEL11")
 
local _G = _G
local type = type
local select = select
local unpack = unpack
local tostring = tostring
local concat = table.concat
local find = string.find
 
local gsub = string.gsub
local format = string.format
 
 
_G.CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA = 1
_G.CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0
 
_G.CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA = 0.5
_G.CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0
 
--_G.CHAT_FRAME_FADE_OUT_TIME = 0
--_G.CHAT_FRAME_FADE_TIME = 0
 
_G.CHAT_FONT_HEIGHTS = {
[1] = 8,
[2] = 9,
[3] = 10,
[4] = 11,
[5] = 12,
[6] = 13,
[7] = 14,
[8] = 15,
[9] = 16,
[10] = 17,
[11] = 18,
[12] = 19,
[13] = 20,
}
 
 
_G.CHAT_SAY_GET = '%s:\32'
_G.CHAT_YELL_GET = '%s:\32'
 
_G.CHAT_WHISPER_GET = '[from] %s:\32'
_G.CHAT_WHISPER_INFORM_GET = '[to] %s:\32'
 
_G.CHAT_BN_WHISPER_GET = '[from] %s:\32'
_G.CHAT_BN_WHISPER_GET = '[to] %s:\32'
 
 
_G.CHAT_FLAG_AFK = '[AFK] '
_G.CHAT_FLAG_DND = '[DND] '
_G.CHAT_FLAG_GM = '[GM] '
 
_G.CHAT_GUILD_GET = '[|Hchannel:Guild|hG|h] %s:\32'
_G.CHAT_OFFICER_GET = '[|Hchannel:o|hO|h] %s:\32'
 
_G.CHAT_PARTY_GET = '[|Hchannel:party|hP|h] %s:\32'
_G.CHAT_PARTY_LEADER_GET = '[|Hchannel:party|hPL|h] %s:\32'
_G.CHAT_PARTY_GUIDE_GET = '[|Hchannel:party|hDG|h] %s:\32'
_G.CHAT_MONSTER_PARTY_GET = '[|Hchannel:raid|hR|h] %s:\32'
 
_G.CHAT_RAID_GET = '[|Hchannel:raid|hR|h] %s:\32'
_G.CHAT_RAID_WARNING_GET = '[RW!] %s:\32'
_G.CHAT_RAID_LEADER_GET = '[|Hchannel:raid|hL|h] %s:\32'
 
_G.CHAT_BATTLEGROUND_GET = '[|Hchannel:Battleground|hBG|h] %s:\32'
_G.CHAT_BATTLEGROUND_LEADER_GET = '[|Hchannel:Battleground|hBL|h] %s:\32'
 
 
local channelFormat
do
local a, b = '.*%[(.*)%].*', '%%[%1%%]'
channelFormat = {
[1] = {gsub(CHAT_BATTLEGROUND_GET, a, b), '[BG]'},
[2] = {gsub(CHAT_BATTLEGROUND_LEADER_GET, a, b), '[BGL]'},
 
[3] = {gsub(CHAT_GUILD_GET, a, b), '[G]'},
[4] = {gsub(CHAT_OFFICER_GET, a, b), '[O]'},
 
[5] = {gsub(CHAT_PARTY_GET, a, b), '[P]'},
[6] = {gsub(CHAT_PARTY_LEADER_GET, a, b), '[PL]'},
[7] = {gsub(CHAT_PARTY_GUIDE_GET, a, b), '[PL]'},
 
[8] = {gsub(CHAT_RAID_GET, a, b), '[R]'},
[9] = {gsub(CHAT_RAID_LEADER_GET, a, b), '[RL]'},
[10] = {gsub(CHAT_RAID_WARNING_GET, a, b), '[RW]'},
 
[11] = {gsub(CHAT_FLAG_AFK, a, b), '[AFK] '},
[12] = {gsub(CHAT_FLAG_DND, a, b), '[DND] '},
[13] = {gsub(CHAT_FLAG_GM, a, b), '[GM] '},
}
end
 
 
local AddMessage = ChatFrame1.AddMessage
local function FCF_AddMessage(self, text, ...)
if (type(text) == 'string') then
text = gsub(text, '(|HBNplayer.-|h)%[(.-)%]|h', '%1%2|h')
text = gsub(text, '(|Hplayer.-|h)%[(.-)%]|h', '%1%2|h')
text = gsub(text, '%[(%d0?)%. (.-)%]', '[%1]')
 
 
for i = 1, #channelFormat do
text = gsub(text, channelFormat[i][1], channelFormat[i][2])
end
 
end
 
return AddMessage(self, text, ...)
end
 
-- Modify the editbox
 
for k = 6, 11 do
select(k, ChatFrame1EditBox:GetRegions()):SetTexture(nil)
end
 
ChatFrame1EditBox:SetAltArrowKeyMode(false)
ChatFrame1EditBox:ClearAllPoints()
ChatFrame1EditBox:SetFont(C['media'].font, C['media'].fontMedium)
ChatFrame1EditBox:SetPoint('BOTTOMLEFT', ChatFrame1, 'TOPLEFT', 2, 33)
ChatFrame1EditBox:SetPoint('BOTTOMRIGHT', ChatFrame1, 'TOPRIGHT', 0, 33)
ChatFrame1EditBox:SetBackdrop({
bgFile = C['chat'].editboxbackground,
edgeFile = C['chat'].editboxborder,
tile = true, tileSize = 16, edgeSize = 18,
insets = {left = 3, right = 3, top = 2, bottom = 3},
})
 
 
ChatFrame1EditBox:SetBackdropColor(0, 0, 0, 0.5)
 
if (C['chat'].enableBorderColoring) then
 
hooksecurefunc('ChatEdit_UpdateHeader', function(editBox)
local type = editBox:GetAttribute('chatType')
if (not type) then
return
end
 
local info = ChatTypeInfo[type]
ChatFrame1EditBox:SetBackdropBorderColor(info.r, info.g, info.b)
end)
end
 
-- Hide the menu and friend button
 
FriendsMicroButton:SetAlpha(0)
FriendsMicroButton:EnableMouse(false)
FriendsMicroButton:UnregisterAllEvents()
 
ChatFrameMenuButton:SetAlpha(0)
ChatFrameMenuButton:EnableMouse(false)
 
-- Tab text colors for the tabs
 
hooksecurefunc('FCFTab_UpdateColors', function(self, selected)
if (selected) then
self:GetFontString():SetTextColor(0, 0.75, 1)
else
self:GetFontString():SetTextColor(1, 1, 1)
end
end)
 
-- Tab text fadeout
 
local origFCF_FadeOutChatFrame = _G.FCF_FadeOutChatFrame
local function FCF_FadeOutChatFrameHook(chatFrame)
origFCF_FadeOutChatFrame(chatFrame)
 
local frameName = chatFrame:GetName()
local chatTab = _G[frameName..'Tab']
local tabGlow = _G[frameName..'TabGlow']
 
if (not tabGlow:IsShown()) then
if (frameName.isDocked) then
securecall('UIFrameFadeOut', chatTab, CHAT_FRAME_FADE_OUT_TIME, chatTab:GetAlpha(), CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA)
else
securecall('UIFrameFadeOut', chatTab, CHAT_FRAME_FADE_OUT_TIME, chatTab:GetAlpha(), CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA)
end
end
end
FCF_FadeOutChatFrame = FCF_FadeOutChatFrameHook
 
-- Improve mousewheel scrolling
 
hooksecurefunc('FloatingChatFrame_OnMouseScroll', function(self, direction)
if (direction > 0) then
if (IsShiftKeyDown()) then
self:ScrollToTop()
else
self:ScrollUp()
self:ScrollUp()
end
elseif (direction < 0) then
if (IsShiftKeyDown()) then
self:ScrollToBottom()
else
self:ScrollDown()
self:ScrollDown()
end
end
 
if (C['chat'].enableBottomButton) then
local buttonBottom = _G[self:GetName() .. 'ButtonFrameBottomButton']
if (self:AtBottom()) then
buttonBottom:SetAlpha(0)
buttonBottom:EnableMouse(false)
else
buttonBottom:SetAlpha(0.7)
buttonBottom:EnableMouse(true)
end
end
end)
 
-- Reposit toast frame
 
BNToastFrame:HookScript('OnShow', function(self)
BNToastFrame:ClearAllPoints()
BNToastFrame:SetPoint('BOTTOMLEFT', ChatFrame1EditBox, 'TOPLEFT', 0, 15)
end)
 
-- Modify the chat tabs
 
function SkinTab(self)
local chat = _G[self]
 
local tab = _G[self..'Tab']
for i = 1, select('#', tab:GetRegions()) do
local texture = select(i, tab:GetRegions())
if (texture and texture:GetObjectType() == 'Texture') then
texture:SetTexture(nil)
end
end
 
local tabText = _G[self..'TabText']
tabText:SetJustifyH('CENTER')
tabText:SetWidth(60)
if (C['chat'].taS.fontOutline) then
tabText:SetFont(C['media'].font, C['media'].fontLarge, 'THINOUTLINE')
tabText:SetShadowOffset(0, 0)
else
tabText:SetFont(C['media'].font, C['media'].fontLarge)
tabText:SetShadowOffset(1, -1)
end
 
local a1, a2, a3, a4, a5 = tabText:GetPoint()
tabText:SetPoint(a1, a2, a3, a4, 1)
 
local s1, s2, s3 = C['chat'].taS.specialColor.r, C['chat'].taS.specialColor.g, C['chat'].taS.specialColor.b
local e1, e2, e3 = C['chat'].taS.selectedColor.r, C['chat'].taS.selectedColor.g, C['chat'].taS.selectedColor.b
local n1, n2, n3 = C['chat'].taS.normalColor.r, C['chat'].taS.normalColor.g, C['chat'].taS.normalColor.b
 
local tabGlow = _G[self..'TabGlow']
hooksecurefunc(tabGlow, 'Show', function()
tabText:SetTextColor(s1, s2, s3, CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA)
end)
 
hooksecurefunc(tabGlow, 'Hide', function()
tabText:SetTextColor(n1, n2, n3)
end)
 
tab:SetScript('OnEnter', function()
tabText:SetTextColor(s1, s2, s3, tabText:GetAlpha())
end)
 
tab:SetScript('OnLeave', function()
local hasNofication = tabGlow:IsShown()
 
local r, g, b
if (_G[self] == SELECTED_CHAT_FRAME and chat.isDocked) then
r, g, b = e1, e2, e3
elseif (hasNofication) then
r, g, b = s1, s2, s3
else
r, g, b = n1, n2, n3
end
 
tabText:SetTextColor(r, g, b)
end)
 
hooksecurefunc(tab, 'Show', function()
if (not taS.wasShown) then
local hasNofication = tabGlow:IsShown()
 
if (chat:IsMouseOver()) then
tab:SetAlpha(CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA)
else
tab:SetAlpha(CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA)
end
 
local r, g, b
if (_G[self] == SELECTED_CHAT_FRAME and chat.isDocked) then
r, g, b = e1, e2, e3
elseif (hasNofication) then
r, g, b = s1, s2, s3
else
r, g, b = n1, n2, n3
end
 
tabText:SetTextColor(r, g, b)
 
taS.wasShown = true
end
end)
end
 
local function ModChat(self)
local chat = _G[self]
 
if (not C['chat'].chatOutline) then
chat:SetShadowOffset(1, -1)
end
 
if (C['chat'].disableFade) then
chat:SetFading(false)
end
 
SkinTab(self)
 
local font, fontsize, fontflags = chat:GetFont()
chat:SetFont(C["media"].font, fontsize, C['chat'].chatOutline and 'THINOUTLINE' or fontflags)
chat:SetClampedToScreen(false)
 
chat:SetClampRectInsets(0, 0, 0, 0)
chat:SetMaxResize(UIParent:GetWidth(), UIParent:GetHeight())
chat:SetMinResize(150, 25)
 
if (self ~= 'ChatFrame2') then
chat.AddMessage = FCF_AddMessage
end
 
local buttonUp = _G[self..'ButtonFrameUpButton']
buttonUp:SetAlpha(0)
buttonUp:EnableMouse(false)
 
local buttonDown = _G[self..'ButtonFrameDownButton']
buttonDown:SetAlpha(0)
buttonDown:EnableMouse(false)
 
local buttonBottom = _G[self..'ButtonFrameBottomButton']
buttonBottom:SetAlpha(0)
buttonBottom:EnableMouse(false)
 
if (C['chat'].enableBottomButton) then
buttonBottom:ClearAllPoints()
buttonBottom:SetPoint('BOTTOMRIGHT', chat, -1, -3)
buttonBottom:HookScript('OnClick', function(self)
self:SetAlpha(0)
self:EnableMouse(false)
end)
end
 
for _, texture in pairs({
'ButtonFrameBackground',
'ButtonFrameTopLeftTexture',
'ButtonFrameBottomLeftTexture',
'ButtonFrameTopRightTexture',
'ButtonFrameBottomRightTexture',
'ButtonFrameLeftTexture',
'ButtonFrameRightTexture',
'ButtonFrameBottomTexture',
'ButtonFrameTopTexture',
}) do
_G[self..texture]:SetTexture(nil)
end
end
 
local function SetChatStyle()
for _, v in pairs(CHAT_FRAMES) do
local chat = _G[v]
if (chat and not chat.hasModification) then
ModChat(chat:GetName())
 
local convButton = _G[chat:GetName()..'ConversationButton']
if (convButton) then
convButton:SetAlpha(0)
convButton:EnableMouse(false)
end
 
local chatMinimize = _G[chat:GetName()..'ButtonFrameMinimizeButton']
if (chatMinimize) then
chatMinimize:SetAlpha(0)
chatMinimize:EnableMouse(0)
end
 
chat.hasModification = true
end
end
end
hooksecurefunc('FCF_OpenTemporaryWindow', SetChatStyle)
SetChatStyle()
 
-- Chat menu, just a middle click on the chatframe 1 tab
 
hooksecurefunc('ChatFrameMenu_UpdateAnchorPoint', function()
if (FCF_GetButtonSide(DEFAULT_CHAT_FRAME) == 'right') then
ChatMenu:ClearAllPoints()
ChatMenu:SetPoint('BOTTOMRIGHT', ChatFrame1Tab, 'TOPLEFT')
else
ChatMenu:ClearAllPoints()
ChatMenu:SetPoint('BOTTOMLEFT', ChatFrame1Tab, 'TOPRIGHT')
end
end)
 
ChatFrame1Tab:RegisterForClicks('AnyUp')
ChatFrame1Tab:HookScript('OnClick', function(self, button)
if (button == 'MiddleButton' or button == 'Button4' or button == 'Button5') then
if (ChatMenu:IsShown()) then
ChatMenu:Hide()
else
ChatMenu:Show()
end
else
ChatMenu:Hide()
end
end)
 
-- Modify the gm chatframe and add a sound notification on incoming whispers
 
local f = CreateFrame('Frame')
f:RegisterEvent('ADDON_LOADED')
f:RegisterEvent('CHAT_MSG_WHISPER')
f:RegisterEvent('CHAT_MSG_BN_WHISPER')
f:SetScript('OnEvent', function(_, event)
if (event == 'ADDON_LOADED' and arg1 == 'Blizzard_GMChatUI') then
GMChatFrame:EnableMouseWheel(true)
GMChatFrame:SetScript('OnMouseWheel', ChatFrame1:GetScript('OnMouseWheel'))
GMChatFrame:SetHeight(200)
 
GMChatFrameUpButton:SetAlpha(0)
GMChatFrameUpButton:EnableMouse(false)
 
GMChatFrameDownButton:SetAlpha(0)
GMChatFrameDownButton:EnableMouse(false)
 
GMChatFrameBottomButton:SetAlpha(0)
GMChatFrameBottomButton:EnableMouse(false)
end
 
if (event == 'CHAT_MSG_WHISPER' or event == 'CHAT_MSG_BN_WHISPER') then
PlaySoundFile(C['chat'].sound)
end
end)
 
local combatLog = {
text = 'CombatLog',
colorCode = '|cffFFD100',
isNotRadio = true,
 
func = function()
if (not LoggingCombat()) then
LoggingCombat(true)
DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGENABLED, 1, 1, 0)
else
LoggingCombat(false)
DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGDISABLED, 1, 1, 0)
end
end,
 
checked = function()
if (LoggingCombat()) then
return true
else
return false
end
end
}
 
local chatLog = {
text = 'ChatLog',
colorCode = '|cffFFD100',
isNotRadio = true,
 
func = function()
if (not LoggingChat()) then
LoggingChat(true)
DEFAULT_CHAT_FRAME:AddMessage(CHATLOGENABLED, 1, 1, 0)
else
LoggingChat(false)
DEFAULT_CHAT_FRAME:AddMessage(CHATLOGDISABLED, 1, 1, 0)
end
end,
 
checked = function()
if (LoggingChat()) then
return true
else
return false
end
end
}
 
local origFCF_Tab_OnClick = _G.FCF_Tab_OnClick
local function FCF_Tab_OnClickHook(chatTab, ...)
origFCF_Tab_OnClick(chatTab, ...)
 
combatLog.arg1 = chatTab
UIDropDownMenu_AddButton(combatLog)
 
chatLog.arg1 = chatTab
UIDropDownMenu_AddButton(chatLog)
end
FCF_Tab_OnClick = FCF_Tab_OnClickHook
 
 
-- Chat Copy
 
local f = CreateFrame('Frame', nil, UIParent)
f:SetHeight(220)
f:SetBackdropColor(0, 0, 0, 1)
f:SetPoint('BOTTOMLEFT', ChatFrame1EditBox, 'TOPLEFT', 3, 10)
f:SetPoint('BOTTOMRIGHT', ChatFrame1EditBox, 'TOPRIGHT', -3, 10)
f:SetFrameStrata('DIALOG')
f:SetBackdrop({
bgFile = C['chat'].background,
edgeFile = C['chat'].border,
tile = true, tileSize = 16, edgeSize = 18,
insets = {left = 3, right = 3, top = 3, bottom = 3
}})
f:SetBackdropBorderColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
f:Hide()
 
f.t = f:CreateFontString(nil, 'OVERLAY')
f.t:SetFont(C['media'].font, C['media'].fontHuge)
f.t:SetPoint('TOPLEFT', f, 8, -8)
f.t:SetTextColor(1, 1, 0)
f.t:SetShadowOffset(1, -1)
f.t:SetJustifyH('LEFT')
 
f.b = CreateFrame('EditBox', nil, f)
f.b:SetMultiLine(true)
f.b:SetMaxLetters(20000)
f.b:SetSize(450, 270)
f.b:SetScript('OnEscapePressed', function()
f:Hide()
end)
 
f.s = CreateFrame('ScrollFrame', '$parentScrollBar', f, 'UIPanelScrollFrameTemplate')
f.s:SetPoint('TOPLEFT', f, 'TOPLEFT', 8, -30)
f.s:SetPoint('BOTTOMRIGHT', f, 'BOTTOMRIGHT', -30, 8)
f.s:SetScrollChild(f.b)
 
f.c = CreateFrame('Button', nil, f, 'UIPanelCloseButton')
f.c:SetPoint('TOPRIGHT', f, 'TOPRIGHT', 0, -1)
 
local lines = {}
local function GetChatLines(...)
local count = 1
for i = select('#', ...), 1, -1 do
local region = select(i, ...)
if (region:GetObjectType() == 'FontString') then
lines[count] = tostring(region:GetText())
count = count + 1
end
end
 
return count - 1
end
 
local function copyChat(self)
local chat = _G[self:GetName()]
local _, fontSize = chat:GetFont()
 
FCF_SetChatWindowFontSize(self, chat, 0.1)
local lineCount = GetChatLines(chat:GetRegions())
FCF_SetChatWindowFontSize(self, chat, fontSize)
 
if (lineCount > 0) then
ToggleFrame(f)
f.t:SetText(chat:GetName())
 
local f1, f2, f3 = ChatFrame1:GetFont()
f.b:SetFont(f1, f2, f3)
 
local text = concat(lines, '\n', 1, lineCount)
f.b:SetText(text)
end
end
 
local function CreateCopyButton(self)
self.Copy = CreateFrame('Button', nil, _G[self:GetName()])
self.Copy:SetSize(20, 20)
self.Copy:SetPoint('TOPRIGHT', self, -5, -5)
 
self.Copy:SetNormalTexture([[Interface\AddOns\SoopUI\Media\Textures\textureCopyNormal]])
self.Copy:GetNormalTexture():SetSize(20, 20)
 
self.Copy:SetHighlightTexture([[Interface\AddOns\SoopUI\Media\Textures\textureCopyHighlight]])
self.Copy:GetHighlightTexture():SetAllPoints(self.Copy:GetNormalTexture())
 
local tab = _G[self:GetName()..'Tab']
hooksecurefunc(tab, 'SetAlpha', function()
self.Copy:SetAlpha(tab:GetAlpha()*0.55)
end)
 
self.Copy:SetScript('OnMouseDown', function(self)
self:GetNormalTexture():ClearAllPoints()
self:GetNormalTexture():SetPoint('CENTER', 1, -1)
end)
 
self.Copy:SetScript('OnMouseUp', function()
self.Copy:GetNormalTexture():ClearAllPoints()
self.Copy:GetNormalTexture():SetPoint('CENTER')
 
if (self.Copy:IsMouseOver()) then
copyChat(self)
end
end)
end
 
local function EnableCopyButton()
for _, v in pairs(CHAT_FRAMES) do
local chat = _G[v]
if (chat and not chat.Copy) then
CreateCopyButton(chat)
end
end
end
hooksecurefunc('FCF_OpenTemporaryWindow', EnableCopyButton)
EnableCopyButton()
 
-- Copy URL
 
local urlStyle = '|cffff00ff|Hurl:%1|h%1|h|r'
local urlPatterns = {
'(http://%S+)', -- http://xxx.com
'(www%.%S+)', -- www.xxx.com/site/index.php
'(%d+%.%d+%.%d+%.%d+:?%d*)', -- 192.168.1.1 / 192.168.1.1:1110
}
 
local messageTypes = {
'CHAT_MSG_CHANNEL',
'CHAT_MSG_GUILD',
'CHAT_MSG_PARTY',
'CHAT_MSG_RAID',
'CHAT_MSG_SAY',
'CHAT_MSG_WHISPER',
}
 
local function urlFilter(self, event, text, ...)
for _, pattern in ipairs(urlPatterns) do
local result, matches = gsub(text, pattern, urlStyle)
 
if (matches > 0) then
return false, result, ...
end
end
end
 
for _, event in ipairs(messageTypes) do
ChatFrame_AddMessageEventFilter(event, urlFilter)
end
 
local origSetItemRef = _G.SetItemRef
local currentLink
local SetItemRefHook = function(link, text, button)
if (link:sub(0, 3) == 'url') then
currentLink = link:sub(5)
StaticPopup_Show('UrlCopyDialog')
return
end
 
return origSetItemRef(link, text, button)
end
 
SetItemRef = SetItemRefHook
 
StaticPopupDialogs['UrlCopyDialog'] = {
text = 'URL',
button2 = CLOSE,
hasEditBox = 1,
editBoxWidth = 250,
 
OnShow = function(frame)
local editBox = _G[frame:GetName()..'EditBox']
if (editBox) then
editBox:SetText(currentLink)
editBox:SetFocus()
editBox:HighlightText(0)
end
 
local button = _G[frame:GetName()..'Button2']
if (button) then
button:ClearAllPoints()
button:SetWidth(100)
button:SetPoint('CENTER', editBox, 'CENTER', 0, -30)
end
end,
 
EditBoxOnEscapePressed = function(frame)
frame:GetParent():Hide()
end,
 
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
maxLetters = 1024,
}
 
if C['chat'].enableHyperlinkTooltip ~= true then return end
 
--[[
 
All Create for hyperlink.lua goes to Neal, ballagarba, and Tuks.
Neav UI = http://www.wowinterface.com/downloads/info13981-NeavUI.html.
Tukui = http://www.tukui.org/download.php.
Edited by Cokedriver.
 
]]
 
local _G = getfenv(0)
local orig1, orig2 = {}, {}
local GameTooltip = GameTooltip
 
local linktypes = {
item = true,
enchant = true,
spell = true,
quest = true,
unit = true,
talent = true,
achievement = true,
glyph = true
}
 
local function OnHyperlinkEnter(frame, link, ...)
local linktype = link:match('^([^:]+)')
if (linktype and linktypes[linktype]) then
GameTooltip:SetOwner(ChatFrame1, 'ANCHOR_CURSOR', 0, 20)
GameTooltip:SetHyperlink(link)
GameTooltip:Show()
else
GameTooltip:Hide()
end
 
if (orig1[frame]) then
return orig1[frame](frame, link, ...)
end
end
 
local function OnHyperlinkLeave(frame, ...)
GameTooltip:Hide()
 
if (orig2[frame]) then
return orig2[frame](frame, ...)
end
end
 
local function EnableItemLinkTooltip()
for _, v in pairs(CHAT_FRAMES) do
local chat = _G[v]
if (chat and not chat.URLCopy) then
orig1[chat] = chat:GetScript('OnHyperlinkEnter')
chat:SetScript('OnHyperlinkEnter', OnHyperlinkEnter)
 
orig2[chat] = chat:GetScript('OnHyperlinkLeave')
chat:SetScript('OnHyperlinkLeave', OnHyperlinkLeave)
chat.URLCopy = true
end
end
end
hooksecurefunc('FCF_OpenTemporaryWindow', EnableItemLinkTooltip)
EnableItemLinkTooltip()
 
if C["chat"].windowborder == true then
for i = 1, NUM_CHAT_WINDOWS do
local cf = _G['ChatFrame'..i]
local bg = CreateFrame("Frame", nil, cf);
bg:SetFrameStrata("BACKGROUND");
 
if i == 2 then
bg:SetPoint("TOPLEFT", -8, 32);
else
bg:SetPoint("TOPLEFT", -8, 8);
end
bg:SetPoint("BOTTOMRIGHT", 8, -12);
bg:SetBackdrop({
edgeFile = C['chat'].border,
tile = true, tileSize = 16, edgeSize = 18,
})
 
if C['general'].classcolor ~= true then
bg:SetBackdropBorderColor(C['general'].color.r,C['general'].color.g,C['general'].color.b)
else
bg:SetBackdropBorderColor(S.ccolor.r, S.ccolor.g, S.ccolor.b)
end
 
end
end
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/LibDataBroker-1.1/LibDataBroker-1.1.lua New file
0,0 → 1,90
 
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
 
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
 
 
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
 
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
 
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
 
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
 
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
 
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
 
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
 
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
 
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return next, attributestorage[dataobj], nil
end
 
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return ipairs_iter, attributestorage[dataobj], 0
end
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/LibDataBroker-1.1/README.textile New file
0,0 → 1,13
LibDataBroker is a small WoW addon library designed to provide a "MVC":http://en.wikipedia.org/wiki/Model-view-controller interface for use in various addons.
LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon.
Plugins can provide data into a simple table, and display addons can receive callbacks to refresh their display of this data.
LDB also provides a place for addons to register "quicklaunch" functions, removing the need for authors to embed many large libraries to create minimap buttons.
Users who do not wish to be "plagued" by these buttons simply do not install an addon to render them.
 
Due to it's simple generic design, LDB can be used for any design where you wish to have an addon notified of changes to a table.
 
h2. Links
 
* "API documentation":http://github.com/tekkub/libdatabroker-1-1/wikis/api
* "Data specifications":http://github.com/tekkub/libdatabroker-1-1/wikis/data-specifications
* "Addons using LDB":http://github.com/tekkub/libdatabroker-1-1/wikis/addons-using-ldb
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/LibDataBroker.toc New file
0,0 → 1,10
## Interface: 40300
## LoadOnDemand: 1
## Title: Lib: LibDataBroker-1.1
## Notes: LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon.
## Author: Tekkub
## X-Website: http://github.com/tekkub/libdatabroker-1-1/
## X-Category: Library
## X-License: All Rights Reserved
 
Load.xml
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/CallBackHandler/CallbackHandler-1.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/CallBackHandler/CallbackHandler-1.0.lua New file
0,0 → 1,240
--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 6
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
 
if not CallbackHandler then return end -- No upgrade needed
 
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
 
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
 
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
 
local method, ARGS
local function call() method(ARGS) end
 
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
 
return dispatch
]]
 
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
 
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
 
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
 
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
 
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
 
 
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
 
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
 
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
 
registry.recurse = oldrecurse
 
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
 
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
 
method = method or eventname
 
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
 
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
 
local regfunc
 
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId" or self=thread
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
 
 
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
 
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
 
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
 
 
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
 
return registry
end
 
 
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
 
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibDataBroker/Load.xml New file
0,0 → 1,4
<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/">
<Include file="CallbackHandler\CallbackHandler-1.0.xml"/>
<Script file="LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
</Ui>
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,240
--[[ $Id: CallbackHandler-1.0.lua 965 2010-08-09 00:47:52Z mikk $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 6
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
 
if not CallbackHandler then return end -- No upgrade needed
 
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
 
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
 
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
 
local method, ARGS
local function call() method(ARGS) end
 
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
 
return dispatch
]]
 
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
 
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
 
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
 
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
 
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
 
 
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
 
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
 
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
 
registry.recurse = oldrecurse
 
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
 
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
 
method = method or eventname
 
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
 
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
 
local regfunc
 
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId" or self=thread
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
 
 
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
 
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
 
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
 
 
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
 
return registry
end
 
 
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
 
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceHook-3.0/AceHook-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceHook-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceHook-3.0/AceHook-3.0.lua New file
0,0 → 1,514
--- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
-- when you manually restore the original function.
--
-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceHook itself.\\
-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceHook.
-- @class file
-- @name AceHook-3.0
-- @release $Id: AceHook-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
 
if not AceHook then return end -- No upgrade needed
 
AceHook.embeded = AceHook.embeded or {}
AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
AceHook.handlers = AceHook.handlers or {}
AceHook.actives = AceHook.actives or {}
AceHook.scripts = AceHook.scripts or {}
AceHook.onceSecure = AceHook.onceSecure or {}
AceHook.hooks = AceHook.hooks or {}
 
-- local upvalues
local registry = AceHook.registry
local handlers = AceHook.handlers
local actives = AceHook.actives
local scripts = AceHook.scripts
local onceSecure = AceHook.onceSecure
 
-- Lua APIs
local pairs, next, type = pairs, next, type
local format = string.format
local assert, error = assert, error
 
-- WoW APIs
local issecurevariable, hooksecurefunc = issecurevariable, hooksecurefunc
local _G = _G
 
-- functions for later definition
local donothing, createHook, hook
 
local protectedScripts = {
OnClick = true,
}
 
-- upgrading of embeded is done at the bottom of the file
 
local mixins = {
"Hook", "SecureHook",
"HookScript", "SecureHookScript",
"Unhook", "UnhookAll",
"IsHooked",
"RawHook", "RawHookScript"
}
 
-- AceHook:Embed( target )
-- target (object) - target object to embed AceHook in
--
-- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
function AceHook:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeded[target] = true
-- inject the hooks table safely
target.hooks = target.hooks or {}
return target
end
 
-- AceHook:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unhooks all hooks when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceHook:OnEmbedDisable( target )
target:UnhookAll()
end
 
function createHook(self, handler, orig, secure, failsafe)
local uid
local method = type(handler) == "string"
if failsafe and not secure then
-- failsafe hook creation
uid = function(...)
if actives[uid] then
if method then
self[handler](self, ...)
else
handler(...)
end
end
return orig(...)
end
-- /failsafe hook
else
-- all other hooks
uid = function(...)
if actives[uid] then
if method then
return self[handler](self, ...)
else
return handler(...)
end
elseif not secure then -- backup on non secure
return orig(...)
end
end
-- /hook
end
return uid
end
 
function donothing() end
 
function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
if not handler then handler = method end
 
-- These asserts make sure AceHooks's devs play by the rules.
assert(not script or type(script) == "boolean")
assert(not secure or type(secure) == "boolean")
assert(not raw or type(raw) == "boolean")
assert(not forceSecure or type(forceSecure) == "boolean")
assert(usage)
 
-- Error checking Battery!
if obj and type(obj) ~= "table" then
error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
end
if type(method) ~= "string" then
error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
end
if type(handler) ~= "string" and type(handler) ~= "function" then
error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
end
if type(handler) == "string" and type(self[handler]) ~= "function" then
error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
end
if script then
if not secure and obj:IsProtected() and protectedScripts[method] then
error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
end
if not obj or not obj.GetScript or not obj:HasScript(method) then
error(format("%s: You can only hook a script on a frame object", usage), 3)
end
else
local issecure
if obj then
issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
else
issecure = onceSecure[method] or issecurevariable(method)
end
if issecure then
if forceSecure then
if obj then
onceSecure[obj] = onceSecure[obj] or {}
onceSecure[obj][method] = true
else
onceSecure[method] = true
end
elseif not secure then
error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
end
end
end
 
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
 
if uid then
if actives[uid] then
-- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
error(format("Attempting to rehook already active hook %s.", method))
end
 
if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
actives[uid] = true
return
elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
if self.hooks and self.hooks[obj] then
self.hooks[obj][method] = nil
end
registry[self][obj][method] = nil
else
if self.hooks then
self.hooks[method] = nil
end
registry[self][method] = nil
end
handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
uid = nil
end
 
local orig
if script then
orig = obj:GetScript(method) or donothing
elseif obj then
orig = obj[method]
else
orig = _G[method]
end
 
if not orig then
error(format("%s: Attempting to hook a non existing target", usage), 3)
end
 
uid = createHook(self, handler, orig, secure, not (raw or secure))
 
if obj then
self.hooks[obj] = self.hooks[obj] or {}
registry[self][obj] = registry[self][obj] or {}
registry[self][obj][method] = uid
 
if not secure then
self.hooks[obj][method] = orig
end
 
if script then
-- If the script is empty before, HookScript will not work, so use SetScript instead
-- This will make the hook insecure, but shouldnt matter, since it was empty before.
-- It does not taint the full frame.
if not secure or orig == donothing then
obj:SetScript(method, uid)
elseif secure then
obj:HookScript(method, uid)
end
else
if not secure then
obj[method] = uid
else
hooksecurefunc(obj, method, uid)
end
end
else
registry[self][method] = uid
 
if not secure then
_G[method] = uid
self.hooks[method] = orig
else
hooksecurefunc(method, uid)
end
end
 
actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
end
 
--- Hook a function or a method on an object.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:Hook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- print(button:GetName() .. " is updating its HotKey")
-- end
function AceHook:Hook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
 
if handler == true then
handler, hookSecure = nil, true
end
 
hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
end
 
--- RawHook a function or a method on an object.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
-- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original function.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:RawHook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- if button:GetName() == "MyButton" then
-- -- do stuff here
-- else
-- self.hooks.ActionButton_UpdateHotkeys(button, type)
-- end
-- end
function AceHook:RawHook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
 
if handler == true then
handler, hookSecure = nil, true
end
 
hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
end
 
--- SecureHook a function or a method on an object.
-- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig [object], method, [handler]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
function AceHook:SecureHook(object, method, handler)
if type(object) == "string" then
method, handler, object = object, method, nil
end
 
hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
end
 
--- Hook a script handler on a frame.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
-- when a certain event happens to a frame.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- print("The FriendsFrame was shown!")
-- end
function AceHook:HookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])")
end
 
--- RawHook a script handler on a frame.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
-- The original script will be stored in `self.hooks[frame][script]`.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original script.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- -- Call the original function
-- self.hooks[frame].OnShow(frame)
-- -- Do our processing
-- -- .. stuff
-- end
function AceHook:RawHookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
end
 
--- SecureHook a script handler on a frame.
-- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
function AceHook:SecureHookScript(frame, script, handler)
hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
end
 
--- Unhook from the specified function, method or script.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:Unhook(obj, method)
local usage = "Usage: Unhook([obj], method)"
if type(obj) == "string" then
method, obj = obj, nil
end
 
if obj and type(obj) ~= "table" then
error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
end
if type(method) ~= "string" then
error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
end
 
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
 
if not uid or not actives[uid] then
-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
return false
end
 
actives[uid], handlers[uid] = nil, nil
 
if obj then
registry[self][obj][method] = nil
registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
 
-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
if not self.hooks[obj] or not self.hooks[obj][method] then return true end
 
if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
scripts[uid] = nil
elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
obj[method] = self.hooks[obj][method]
end
 
self.hooks[obj][method] = nil
self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
else
registry[self][method] = nil
 
-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
if not self.hooks[method] then return true end
 
if self.hooks[method] and _G[method] == uid then -- unhooks functions
_G[method] = self.hooks[method]
end
 
self.hooks[method] = nil
end
return true
end
 
--- Unhook all existing hooks for this addon.
function AceHook:UnhookAll()
for key, value in pairs(registry[self]) do
if type(key) == "table" then
for method in pairs(value) do
self:Unhook(key, method)
end
else
self:Unhook(key)
end
end
end
 
--- Check if the specific function, method or script is already hooked.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:IsHooked(obj, method)
-- we don't check if registry[self] exists, this is done by evil magicks in the metatable
if type(obj) == "string" then
if registry[self][obj] and actives[registry[self][obj]] then
return true, handlers[registry[self][obj]]
end
else
if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
return true, handlers[registry[self][obj][method]]
end
end
 
return false, nil
end
 
--- Upgrade our old embeded
for target, v in pairs( AceHook.embeded ) do
AceHook:Embed( target )
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceDBOptions-3.0/AceDBOptions-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDBOptions-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua New file
0,0 → 1,440
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file
-- @name AceDBOptions-3.0
-- @release $Id: AceDBOptions-3.0.lua 1066 2012-09-18 14:36:49Z nevcairiel $
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 14
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
 
if not AceDBOptions then return end -- No upgrade needed
 
-- Lua APIs
local pairs, next = pairs, next
 
-- WoW APIs
local UnitClass = UnitClass
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE
 
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
AceDBOptions.handlers = AceDBOptions.handlers or {}
 
--[[
Localization of AceDBOptions-3.0
]]
 
local L = {
choose = "Existing Profiles",
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
choose_sub = "Select one of your currently available profiles.",
copy = "Copy From",
copy_desc = "Copy the settings from one existing profile into the currently active profile.",
current = "Current Profile:",
default = "Default",
delete = "Delete a Profile",
delete_confirm = "Are you sure you want to delete the selected profile?",
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
delete_sub = "Deletes a profile from the database.",
intro = "You can change the active database profile, so you can have different settings for every character.",
new = "New",
new_sub = "Create a new empty profile.",
profiles = "Profiles",
profiles_sub = "Manage Profiles",
reset = "Reset Profile",
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
reset_sub = "Reset the current profile to the default",
}
 
local LOCALE = GetLocale()
if LOCALE == "deDE" then
L["choose"] = "Vorhandene Profile"
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder wähle eines der vorhandenen Profile aus."
L["choose_sub"] = "Wählt ein bereits vorhandenes Profil aus."
L["copy"] = "Kopieren von..."
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
-- L["current"] = "Current Profile:"
L["default"] = "Standard"
L["delete"] = "Profil löschen"
L["delete_confirm"] = "Willst du das ausgewählte Profil wirklich löschen?"
L["delete_desc"] = "Lösche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
L["delete_sub"] = "Löscht ein Profil aus der Datenbank."
L["intro"] = "Hier kannst du das aktive Datenbankprofile ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird."
L["new"] = "Neu"
L["new_sub"] = "Ein neues Profil erstellen."
L["profiles"] = "Profile"
L["profiles_sub"] = "Profile verwalten"
L["reset"] = "Profil zurücksetzen"
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zurück, für den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen."
elseif LOCALE == "frFR" then
L["choose"] = "Profils existants"
L["choose_desc"] = "Vous pouvez créer un nouveau profil en entrant un nouveau nom dans la boîte de saisie, ou en choississant un des profils déjà existants."
L["choose_sub"] = "Permet de choisir un des profils déjà disponibles."
L["copy"] = "Copier à partir de"
L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif."
-- L["current"] = "Current Profile:"
L["default"] = "Défaut"
L["delete"] = "Supprimer un profil"
L["delete_confirm"] = "Etes-vous sûr de vouloir supprimer le profil sélectionné ?"
L["delete_desc"] = "Supprime les profils existants inutilisés de la base de données afin de gagner de la place et de nettoyer le fichier SavedVariables."
L["delete_sub"] = "Supprime un profil de la base de données."
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des paramètres différents pour chaque personnage, permettant ainsi d'avoir une configuration très flexible."
L["new"] = "Nouveau"
L["new_sub"] = "Créée un nouveau profil vierge."
L["profiles"] = "Profils"
L["profiles_sub"] = "Gestion des profils"
L["reset"] = "Réinitialiser le profil"
L["reset_desc"] = "Réinitialise le profil actuel au cas où votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
L["reset_sub"] = "Réinitialise le profil actuel avec les paramètres par défaut."
elseif LOCALE == "koKR" then
L["choose"] = "프로필 선택"
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
L["copy"] = "복사"
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
-- L["current"] = "Current Profile:"
L["default"] = "기본값"
L["delete"] = "프로필 삭제"
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
L["new"] = "새로운 프로필"
L["new_sub"] = "새로운 프로필을 만듭니다."
L["profiles"] = "프로필"
L["profiles_sub"] = "프로필 설정"
L["reset"] = "프로필 초기화"
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
elseif LOCALE == "esES" or LOCALE == "esMX" then
L["choose"] = "Perfiles existentes"
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
L["copy"] = "Copiar de"
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
-- L["current"] = "Current Profile:"
L["default"] = "Por defecto"
L["delete"] = "Borrar un Perfil"
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
L["delete_sub"] = "Borra un perfil de la base de datos."
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
L["new"] = "Nuevo"
L["new_sub"] = "Crear un nuevo perfil vacio."
L["profiles"] = "Perfiles"
L["profiles_sub"] = "Manejar Perfiles"
L["reset"] = "Reiniciar Perfil"
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
elseif LOCALE == "zhTW" then
L["choose"] = "現有的設定檔"
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
L["copy"] = "複製自"
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
-- L["current"] = "Current Profile:"
L["default"] = "預設"
L["delete"] = "刪除一個設定檔"
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
L["new"] = "新建"
L["new_sub"] = "新建一個空的設定檔。"
L["profiles"] = "設定檔"
L["profiles_sub"] = "管理設定檔"
L["reset"] = "重置設定檔"
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
L["reset_sub"] = "將當前的設定檔恢復為預設值"
elseif LOCALE == "zhCN" then
L["choose"] = "现有的配置文件"
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
L["copy"] = "复制自"
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
-- L["current"] = "Current Profile:"
L["default"] = "默认"
L["delete"] = "删除一个配置文件"
L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
L["delete_sub"] = "从数据库里删除一个配置文件。"
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
L["new"] = "新建"
L["new_sub"] = "新建一个空的配置文件。"
L["profiles"] = "配置文件"
L["profiles_sub"] = "管理配置文件"
L["reset"] = "重置配置文件"
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
L["reset_sub"] = "将当前的配置文件恢复为默认值"
elseif LOCALE == "ruRU" then
L["choose"] = "Существующие профили"
L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
L["choose_sub"] = "Выбор одиного из уже доступных профилей"
L["copy"] = "Скопировать из"
L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
-- L["current"] = "Current Profile:"
L["default"] = "По умолчанию"
L["delete"] = "Удалить профиль"
L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
L["delete_sub"] = "Удаление профиля из БД"
L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
L["new"] = "Новый"
L["new_sub"] = "Создать новый чистый профиль"
L["profiles"] = "Профили"
L["profiles_sub"] = "Управление профилями"
L["reset"] = "Сброс профиля"
L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
L["reset_sub"] = "Сброс текущего профиля на стандартный"
elseif LOCALE == "itIT" then
L["choose"] = "Profili esistenti"
L["choose_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili gia' esistenti."
L["choose_sub"] = "Seleziona uno dei profili disponibili."
L["copy"] = "Copia Da"
L["copy_desc"] = "Copia le impostazioni da un profilo esistente, nel profilo attivo in questo momento."
L["current"] = "Profilo Attivo:"
L["default"] = "Standard"
L["delete"] = "Cancella un profilo"
L["delete_confirm"] = "Sei sicuro di voler cancellare il profilo selezionato?"
L["delete_desc"] = "Cancella i profili non utilizzati dal database per risparmiare spazio e mantenere puliti i file di configurazione SavedVariables."
L["delete_sub"] = "Cancella un profilo dal Database."
L["intro"] = "Puoi cambiare il profilo attivo, in modo da usare impostazioni diverse per ogni personaggio."
L["new"] = "Nuovo"
L["new_sub"] = "Crea un nuovo profilo vuoto."
L["profiles"] = "Profili"
L["profiles_sub"] = "Gestisci Profili"
L["reset"] = "Reimposta Profilo"
L["reset_desc"] = "Riporta il tuo profilo attivo alle sue impostazioni di default, nel caso in cui la tua configurazione si sia corrotta, o semplicemente tu voglia re-inizializzarla."
L["reset_sub"] = "Reimposta il profilo ai suoi valori di default."
end
 
local defaultProfiles
local tmpprofiles = {}
 
-- Get a list of available profiles for the specified database.
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
-- @param db The db object to retrieve the profiles from
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
local function getProfileList(db, common, nocurrent)
local profiles = {}
 
-- copy existing profiles into the table
local currentProfile = db:GetCurrentProfile()
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
if not (nocurrent and v == currentProfile) then
profiles[v] = v
end
end
 
-- add our default profiles to choose from ( or rename existing profiles)
for k,v in pairs(defaultProfiles) do
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
profiles[k] = v
end
end
 
return profiles
end
 
--[[
OptionsHandlerPrototype
prototype class for handling the options in a sane way
]]
local OptionsHandlerPrototype = {}
 
--[[ Reset the profile ]]
function OptionsHandlerPrototype:Reset()
self.db:ResetProfile()
end
 
--[[ Set the profile to value ]]
function OptionsHandlerPrototype:SetProfile(info, value)
self.db:SetProfile(value)
end
 
--[[ returns the currently active profile ]]
function OptionsHandlerPrototype:GetCurrentProfile()
return self.db:GetCurrentProfile()
end
 
--[[
List all active profiles
you can control the output with the .arg variable
currently four modes are supported
 
(empty) - return all available profiles
"nocurrent" - returns all available profiles except the currently active profile
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
"both" - common except the active profile
]]
function OptionsHandlerPrototype:ListProfiles(info)
local arg = info.arg
local profiles
if arg == "common" and not self.noDefaultProfiles then
profiles = getProfileList(self.db, true, nil)
elseif arg == "nocurrent" then
profiles = getProfileList(self.db, nil, true)
elseif arg == "both" then -- currently not used
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
else
profiles = getProfileList(self.db)
end
 
return profiles
end
 
function OptionsHandlerPrototype:HasNoProfiles(info)
local profiles = self:ListProfiles(info)
return ((not next(profiles)) and true or false)
end
 
--[[ Copy a profile ]]
function OptionsHandlerPrototype:CopyProfile(info, value)
self.db:CopyProfile(value)
end
 
--[[ Delete a profile from the db ]]
function OptionsHandlerPrototype:DeleteProfile(info, value)
self.db:DeleteProfile(value)
end
 
--[[ fill defaultProfiles with some generic values ]]
local function generateDefaultProfiles(db)
defaultProfiles = {
["Default"] = L["default"],
[db.keys.char] = db.keys.char,
[db.keys.realm] = db.keys.realm,
[db.keys.class] = UnitClass("player")
}
end
 
--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
local function getOptionsHandler(db, noDefaultProfiles)
if not defaultProfiles then
generateDefaultProfiles(db)
end
 
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
 
for k,v in pairs(OptionsHandlerPrototype) do
handler[k] = v
end
 
AceDBOptions.handlers[db] = handler
return handler
end
 
--[[
the real options table
]]
local optionsTable = {
desc = {
order = 1,
type = "description",
name = L["intro"] .. "\n",
},
descreset = {
order = 9,
type = "description",
name = L["reset_desc"],
},
reset = {
order = 10,
type = "execute",
name = L["reset"],
desc = L["reset_sub"],
func = "Reset",
},
current = {
order = 11,
type = "description",
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
width = "default",
},
choosedesc = {
order = 20,
type = "description",
name = "\n" .. L["choose_desc"],
},
new = {
name = L["new"],
desc = L["new_sub"],
type = "input",
order = 30,
get = false,
set = "SetProfile",
},
choose = {
name = L["choose"],
desc = L["choose_sub"],
type = "select",
order = 40,
get = "GetCurrentProfile",
set = "SetProfile",
values = "ListProfiles",
arg = "common",
},
copydesc = {
order = 50,
type = "description",
name = "\n" .. L["copy_desc"],
},
copyfrom = {
order = 60,
type = "select",
name = L["copy"],
desc = L["copy_desc"],
get = false,
set = "CopyProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
},
deldesc = {
order = 70,
type = "description",
name = "\n" .. L["delete_desc"],
},
delete = {
order = 80,
type = "select",
name = L["delete"],
desc = L["delete_sub"],
get = false,
set = "DeleteProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
confirm = true,
confirmText = L["delete_confirm"],
},
}
 
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
-- @param db The database object to create the options table for.
-- @return The options table to be used in AceConfig-3.0
-- @usage
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
local tbl = AceDBOptions.optionTables[db] or {
type = "group",
name = L["profiles"],
desc = L["profiles_sub"],
}
 
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
tbl.args = optionsTable
 
AceDBOptions.optionTables[db] = tbl
return tbl
end
 
-- upgrade existing tables
for db,tbl in pairs(AceDBOptions.optionTables) do
tbl.handler = getOptionsHandler(db)
tbl.args = optionsTable
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceEvent-3.0/AceEvent-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceEvent-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceEvent-3.0/AceEvent-3.0.lua New file
0,0 → 1,126
--- AceEvent-3.0 provides event registration and secure dispatching.
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
--
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent.
-- @class file
-- @name AceEvent-3.0
-- @release $Id: AceEvent-3.0.lua 975 2010-10-23 11:26:18Z nevcairiel $
local MAJOR, MINOR = "AceEvent-3.0", 3
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceEvent then return end
 
-- Lua APIs
local pairs = pairs
 
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
 
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
 
-- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then
AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end
 
function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname)
end
 
function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname)
end
 
 
-- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then
AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
)
AceEvent.SendMessage = AceEvent.messages.Fire
end
 
--- embedding and embed handling
local mixins = {
"RegisterEvent", "UnregisterEvent",
"RegisterMessage", "UnregisterMessage",
"SendMessage",
"UnregisterAllEvents", "UnregisterAllMessages",
}
 
--- Register for a Blizzard Event.
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent
-- @class function
-- @paramsig event[, callback [, arg]]
-- @param event The event to register for
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
 
--- Unregister an event.
-- @name AceEvent:UnregisterEvent
-- @class function
-- @paramsig event
-- @param event The event to unregister
 
--- Register for a custom AceEvent-internal message.
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage
-- @class function
-- @paramsig message[, callback [, arg]]
-- @param message The message to register for
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
 
--- Unregister a message
-- @name AceEvent:UnregisterMessage
-- @class function
-- @paramsig message
-- @param message The message to unregister
 
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
-- @name AceEvent:SendMessage
-- @class function
-- @paramsig message, ...
-- @param message The message to send
-- @param ... Any arguments to the message
 
 
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceEvent in
function AceEvent:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
 
-- AceEvent:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unregister all events messages etc when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceEvent:OnEmbedDisable(target)
target:UnregisterAllEvents()
target:UnregisterAllMessages()
end
 
-- Script to fire blizzard events into the event listeners
local events = AceEvent.events
AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
events:Fire(event, ...)
end)
 
--- Finally: upgrade our old embeds
for target, v in pairs(AceEvent.embeds) do
AceEvent:Embed(target)
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/Libs.xml New file
0,0 → 1,15
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="libs\AceAddon-3.0\AceAddon-3.0.lua"/>
<Script file="libs\AceDB-3.0\AceDB-3.0.lua"/>
<Script file="CallbackHandler-1.0\CallbackHandler-1.0.lua"/>
<Script file="libs\AceDBOptions-3.0\AceDBOptions-3.0.lua"/>
<Script file="libs\AceConsole-3.0\AceConsole-3.0.lua"/>
<Script file="libs\AceEvent-3.0\AceEvent-3.0.lua"/>
<Script file="libs\LibStub\LibStub.lua"/>
<Include file="LibDataBroker\Load.xml"/>
<Include file="AceHook-3.0\AceHook-3.0.xml"/>
<Include file="LibSharedMedia-3.0\LibSharedMedia-3.0.xml"/>
 
</Ui>
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceConsole-3.0/AceConsole-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConsole-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceConsole-3.0/AceConsole-3.0.lua New file
0,0 → 1,250
--- **AceConsole-3.0** provides registration facilities for slash commands.
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs.
--
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole.
-- @class file
-- @name AceConsole-3.0
-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $
local MAJOR,MINOR = "AceConsole-3.0", 7
 
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConsole then return end -- No upgrade needed
 
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
 
-- Lua APIs
local tconcat, tostring, select = table.concat, tostring, select
local type, pairs, error = type, pairs, error
local format, strfind, strsub = string.format, string.find, string.sub
local max = math.max
 
-- WoW APIs
local _G = _G
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
 
local tmp={}
local function Print(self,frame,...)
local n=0
if self ~= AceConsole then
n=n+1
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
end
for i=1, select("#", ...) do
n=n+1
tmp[n] = tostring(select(i, ...))
end
frame:AddMessage( tconcat(tmp," ",1,n) )
end
 
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] ...
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param ... List of any values to be printed
function AceConsole:Print(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, select(2,...))
else
return Print(self, DEFAULT_CHAT_FRAME, ...)
end
end
 
 
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] "format"[, ...]
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param format Format string - same syntax as standard Lua format()
-- @param ... Arguments to the format string
function AceConsole:Printf(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, format(select(2,...)))
else
return Print(self, DEFAULT_CHAT_FRAME, format(...))
end
end
 
 
 
 
--- Register a simple chat command
-- @param command Chat command to be registered WITHOUT leading "/"
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
 
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
 
local name = "ACECONSOLE_"..command:upper()
 
if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
self[func](self, input, editBox)
end
else
SlashCmdList[name] = func
end
_G["SLASH_"..name.."1"] = "/"..command:lower()
AceConsole.commands[command] = name
-- non-persisting commands are registered for enabling disabling
if not persist then
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
AceConsole.weakcommands[self][command] = func
end
return true
end
 
--- Unregister a chatcommand
-- @param command Chat command to be unregistered WITHOUT leading "/"
function AceConsole:UnregisterChatCommand( command )
local name = AceConsole.commands[command]
if name then
SlashCmdList[name] = nil
_G["SLASH_" .. name .. "1"] = nil
hash_SlashCmdList["/" .. command:upper()] = nil
AceConsole.commands[command] = nil
end
end
 
--- Get an iterator over all Chat Commands registered with AceConsole
-- @return Iterator (pairs) over all commands
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
 
 
local function nils(n, ...)
if n>1 then
return nil, nils(n-1, ...)
elseif n==1 then
return nil, ...
else
return ...
end
end
 
 
--- Retreive one or more space-separated arguments from a string.
-- Treats quoted strings and itemlinks as non-spaced.
-- @param string The raw argument string
-- @param numargs How many arguments to get (default 1)
-- @param startpos Where in the string to start scanning (default 1)
-- @return Returns arg1, arg2, ..., nextposition\\
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
function AceConsole:GetArgs(str, numargs, startpos)
numargs = numargs or 1
startpos = max(startpos or 1, 1)
 
local pos=startpos
 
-- find start of new arg
pos = strfind(str, "[^ ]", pos)
if not pos then -- whoops, end of string
return nils(numargs, 1e9)
end
 
if numargs<1 then
return pos
end
 
-- quoted or space separated? find out which pattern to use
local delim_or_pipe
local ch = strsub(str, pos, pos)
if ch=='"' then
pos = pos + 1
delim_or_pipe='([|"])'
elseif ch=="'" then
pos = pos + 1
delim_or_pipe="([|'])"
else
delim_or_pipe="([| ])"
end
 
startpos = pos
 
while true do
-- find delimiter or hyperlink
local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos)
 
if not pos then break end
 
if ch=="|" then
-- some kind of escape
 
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h
pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
 
pos=strfind(str, "|h", pos+2) -- second |h
if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then
-- It's a |T....|t texture
pos=strfind(str, "|t", pos+2)
if not pos then break end
end
 
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
 
else
-- found delimiter, done with this arg
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
 
end
 
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
return strsub(str, startpos), nils(numargs-1, 1e9)
end
 
 
--- embedding and embed handling
 
local mixins = {
"Print",
"Printf",
"RegisterChatCommand",
"UnregisterChatCommand",
"GetArgs",
}
 
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
function AceConsole:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
 
function AceConsole:OnEmbedEnable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
end
end
end
 
function AceConsole:OnEmbedDisable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
end
end
end
 
for addon in pairs(AceConsole.embeds) do
AceConsole:Embed(addon)
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibSharedMedia-3.0.lua" />
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua New file
0,0 → 1,236
--[[
Name: LibSharedMedia-3.0
Revision: $Revision: 62 $
Author: Elkano (elkano@gmx.de)
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com)
Website: http://www.wowace.com/projects/libsharedmedia-3-0/
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons.
Dependencies: LibStub, CallbackHandler-1.0
License: LGPL v2.1
]]
 
local MAJOR, MINOR = "LibSharedMedia-3.0", 100001 -- increase manualy on changes
local lib = LibStub:NewLibrary(MAJOR, MINOR)
 
if not lib then return end
 
local _G = getfenv(0)
 
local pairs = _G.pairs
local type = _G.type
 
local band = _G.bit.band
 
local table_insert = _G.table.insert
local table_sort = _G.table.sort
 
local locale = GetLocale()
local locale_is_western
local LOCALE_MASK = 0
lib.LOCALE_BIT_koKR = 1
lib.LOCALE_BIT_ruRU = 2
lib.LOCALE_BIT_zhCN = 4
lib.LOCALE_BIT_zhTW = 8
lib.LOCALE_BIT_western = 128
 
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
 
lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
 
lib.DefaultMedia = lib.DefaultMedia or {}
lib.MediaList = lib.MediaList or {}
lib.MediaTable = lib.MediaTable or {}
lib.MediaType = lib.MediaType or {}
lib.OverrideMedia = lib.OverrideMedia or {}
 
local defaultMedia = lib.DefaultMedia
local mediaList = lib.MediaList
local mediaTable = lib.MediaTable
local overrideMedia = lib.OverrideMedia
 
 
-- create mediatype constants
lib.MediaType.BACKGROUND = "background" -- background textures
lib.MediaType.BORDER = "border" -- border textures
lib.MediaType.FONT = "font" -- fonts
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures
lib.MediaType.SOUND = "sound" -- sound files
 
-- populate lib with default Blizzard data
-- BACKGROUND
if not lib.MediaTable.background then lib.MediaTable.background = {} end
lib.MediaTable.background["Blizzard Dialog Background"] = [[Interface\DialogFrame\UI-DialogBox-Background]]
lib.MediaTable.background["Blizzard Dialog Background Dark"] = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]]
lib.MediaTable.background["Blizzard Dialog Background Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Background]]
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]]
lib.MediaTable.background["Blizzard Marble"] = [[Interface\FrameGeneral\UI-Background-Marble]]
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]]
lib.MediaTable.background["Blizzard Parchment"] = [[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]]
lib.MediaTable.background["Blizzard Parchment 2"] = [[Interface\AchievementFrame\UI-GuildAchievement-Parchment-Horizontal]]
lib.MediaTable.background["Blizzard Rock"] = [[Interface\FrameGeneral\UI-Background-Rock]]
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]]
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]]
lib.MediaTable.background["White"] = [[Interface\Buttons\WHITE8X8]]
lib.MediaTable.background["Black"] = [[Interface\AddOns\SoopUI\Media\Textures\BLACK8X8]]
 
-- BORDER
if not lib.MediaTable.border then lib.MediaTable.border = {} end
lib.MediaTable.border["None"] = [[Interface\None]]
lib.MediaTable.border["Blizzard Achievement Wood"] = [[Interface\AchievementFrame\UI-Achievement-WoodBorder]]
lib.MediaTable.border["Blizzard Chat Bubble"] = [[Interface\Tooltips\ChatBubble-Backdrop]]
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]]
lib.MediaTable.border["Blizzard Dialog Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]]
lib.MediaTable.border["Blizzard Party"] = [[Interface\CHARACTERFRAME\UI-Party-Border]]
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]]
 
-- FONT
if not lib.MediaTable.font then lib.MediaTable.font = {} end
local SML_MT_font = lib.MediaTable.font
if locale == "koKR" then
LOCALE_MASK = lib.LOCALE_BIT_koKR
--
SML_MT_font["굵은 글꼴"] = [[Fonts\2002B.TTF]]
SML_MT_font["기본 글꼴"] = [[Fonts\2002.TTF]]
SML_MT_font["데미지 글꼴"] = [[Fonts\K_Damage.TTF]]
SML_MT_font["퀘스트 글꼴"] = [[Fonts\K_Pagetext.TTF]]
--
lib.DefaultMedia["font"] = "기본 글꼴" -- someone from koKR please adjust if needed
--
elseif locale == "zhCN" then
LOCALE_MASK = lib.LOCALE_BIT_zhCN
--
SML_MT_font["伤害数字"] = [[Fonts\ZYKai_C.ttf]]
SML_MT_font["默认"] = [[Fonts\ZYKai_T.ttf]]
SML_MT_font["聊天"] = [[Fonts\ZYHei.ttf]]
--
lib.DefaultMedia["font"] = "默认" -- someone from zhCN please adjust if needed
--
elseif locale == "zhTW" then
LOCALE_MASK = lib.LOCALE_BIT_zhTW
--
SML_MT_font["提示訊息"] = [[Fonts\bHEI00M.ttf]]
SML_MT_font["聊天"] = [[Fonts\bHEI01B.ttf]]
SML_MT_font["傷害數字"] = [[Fonts\bKAI00M.ttf]]
SML_MT_font["預設"] = [[Fonts\bLEI00D.ttf]]
--
lib.DefaultMedia["font"] = "預設" -- someone from zhTW please adjust if needed
 
elseif locale == "ruRU" then
LOCALE_MASK = lib.LOCALE_BIT_ruRU
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
else
LOCALE_MASK = lib.LOCALE_BIT_western
locale_is_western = true
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
end
 
-- STATUSBAR
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]]
lib.MediaTable.statusbar["Blizzard Character Skills Bar"] = [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]]
lib.DefaultMedia.statusbar = "Blizzard"
 
-- SOUND
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
lib.MediaTable.sound["None"] = [[Interface\Quiet.ogg]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input.
lib.DefaultMedia.sound = "None"
 
local function rebuildMediaList(mediatype)
local mtable = mediaTable[mediatype]
if not mtable then return end
if not mediaList[mediatype] then mediaList[mediatype] = {} end
local mlist = mediaList[mediatype]
-- list can only get larger, so simply overwrite it
local i = 0
for k in pairs(mtable) do
i = i + 1
mlist[i] = k
end
table_sort(mlist)
end
 
function lib:Register(mediatype, key, data, langmask)
if type(mediatype) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype))
end
if type(key) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key))
end
mediatype = mediatype:lower()
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end
local mtable = mediaTable[mediatype]
if mtable[key] then return false end
 
mtable[key] = data
rebuildMediaList(mediatype)
self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key)
return true
end
 
function lib:Fetch(mediatype, key, noDefault)
local mtt = mediaTable[mediatype]
local overridekey = overrideMedia[mediatype]
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil
 
return result
end
 
function lib:IsValid(mediatype, key)
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
end
 
function lib:HashTable(mediatype)
return mediaTable[mediatype]
end
 
function lib:List(mediatype)
if not mediaTable[mediatype] then
return nil
end
if not mediaList[mediatype] then
rebuildMediaList(mediatype)
end
return mediaList[mediatype]
end
 
function lib:GetGlobal(mediatype)
return overrideMedia[mediatype]
end
 
function lib:SetGlobal(mediatype, key)
if not mediaTable[mediatype] then
return false
end
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil
self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype])
return true
end
 
function lib:GetDefault(mediatype)
return defaultMedia[mediatype]
end
 
function lib:SetDefault(mediatype, key)
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
defaultMedia[mediatype] = key
return true
else
return false
end
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceAddon-3.0/AceAddon-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceAddon-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceAddon-3.0/AceAddon-3.0.lua New file
0,0 → 1,674
--- **AceAddon-3.0** provides a template for creating addon objects.
-- It'll provide you with a set of callback functions that allow you to simplify the loading
-- process of your addon.\\
-- Callbacks provided are:\\
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
--
-- function MyAddon:OnInitialize()
-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 1084 2013-04-27 20:14:11Z nevcairiel $
 
local MAJOR, MINOR = "AceAddon-3.0", 12
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceAddon then return end -- No Upgrade needed.
 
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
AceAddon.addons = AceAddon.addons or {} -- addons in general
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
 
-- Lua APIs
local tinsert, tconcat, tremove = table.insert, table.concat, table.remove
local fmt, tostring = string.format, tostring
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
local loadstring, assert, error = loadstring, assert, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
 
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
return Dispatchers[select('#', ...)](func, ...)
end
end
 
-- local functions that will be implemented further down
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
 
-- used in the addon metatable
local function addontostring( self ) return self.name end
 
-- Check if the addon is queued for initialization
local function queuedForInitialization(addon)
for i = 1, #AceAddon.initializequeue do
if AceAddon.initializequeue[i] == addon then
return true
end
end
return false
end
 
--- Create a new AceAddon-3.0 addon.
-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
-- -- Create a Addon object based on the table of a frame
-- local MyFrame = CreateFrame("Frame")
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
function AceAddon:NewAddon(objectorname, ...)
local object,name
local i=1
if type(objectorname)=="table" then
object=objectorname
name=...
i=2
else
name=objectorname
end
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
 
object = object or {}
object.name = name
 
local addonmeta = {}
local oldmeta = getmetatable(object)
if oldmeta then
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
 
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
object.orderedModules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
 
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
end
 
 
--- Get the addon object by its name from the internal AceAddon registry.
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
if not silent and not self.addons[name] then
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
end
return self.addons[name]
end
 
-- - Embed a list of libraries into the specified addon.
-- This function will try to embed all of the listed libraries into the addon
-- and error if a single one fails.
--
-- **Note:** This function is for internal use by :NewAddon/:NewModule
-- @paramsig addon, [lib, ...]
-- @param addon addon object to embed the libs in
-- @param lib List of libraries to embed into the addon
function AceAddon:EmbedLibraries(addon, ...)
for i=1,select("#", ... ) do
local libname = select(i, ...)
self:EmbedLibrary(addon, libname, false, 4)
end
end
 
-- - Embed a library into the addon object.
-- This function will check if the specified library is registered with LibStub
-- and if it has a :Embed function to call. It'll error if any of those conditions
-- fails.
--
-- **Note:** This function is for internal use by :EmbedLibraries
-- @paramsig addon, libname[, silent[, offset]]
-- @param addon addon object to embed the library in
-- @param libname name of the library to embed
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
local lib = LibStub:GetLibrary(libname, true)
if not lib and not silent then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
elseif lib and type(lib.Embed) == "function" then
lib:Embed(addon)
tinsert(self.embeds[addon], libname)
return true
elseif lib then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
end
end
 
--- Return the specified module from an addon object.
-- Throws an error if the addon object cannot be found (except if silent is set)
-- @name //addon//:GetModule
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
-- MyModule = MyAddon:GetModule("MyModule")
function GetModule(self, name, silent)
if not self.modules[name] and not silent then
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
end
return self.modules[name]
end
 
local function IsModuleTrue(self) return true end
 
--- Create a new module for the addon.
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
-- an addon object.
-- @name //addon//:NewModule
-- @paramsig name[, prototype|lib[, lib, ...]]
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
 
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
 
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
 
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
 
if type(prototype) == "string" then
AceAddon:EmbedLibraries(module, prototype, ...)
else
AceAddon:EmbedLibraries(module, ...)
end
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
 
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
 
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
 
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
tinsert(self.orderedModules, module)
 
return module
end
 
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
-- @paramsig
-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
return self.moduleName or self.name
end
 
--- Enables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
-- @paramsig
-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
 
-- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still
-- it'll be enabled after the init process
if not queuedForInitialization(self) then
return AceAddon:EnableAddon(self)
end
end
 
--- Disables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
-- @paramsig
-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
function Disable(self)
self:SetEnabledState(false)
return AceAddon:DisableAddon(self)
end
 
--- Enables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
--
-- -- Enable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:EnableModule("MyModule")
function EnableModule(self, name)
local module = self:GetModule( name )
return module:Enable()
end
 
--- Disables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Disable()
--
-- -- Disable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:DisableModule("MyModule")
function DisableModule(self, name)
local module = self:GetModule( name )
return module:Disable()
end
 
--- Set the default libraries to be mixed into all modules created by this object.
-- Note that you can only change the default module libraries before any module is created.
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
-- -- Create a module
-- MyModule = MyAddon:NewModule("MyModule")
function SetDefaultModuleLibraries(self, ...)
if next(self.modules) then
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleLibraries = {...}
end
 
--- Set the default state in which new modules are being created.
-- Note that you can only change the default state before any module is created.
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
-- MyAddon:SetDefaultModuleState(false)
-- -- Create a module and explicilty enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
function SetDefaultModuleState(self, state)
if next(self.modules) then
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleState = state
end
 
--- Set the default prototype to use for new modules on creation.
-- Note that you can only change the default prototype before any module is created.
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
-- MyAddon:SetDefaultModulePrototype(prototype)
-- -- Create a module and explicitly Enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
-- -- should print "OnEnable called!" now
-- @see NewModule
function SetDefaultModulePrototype(self, prototype)
if next(self.modules) then
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
end
if type(prototype) ~= "table" then
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
end
self.defaultModulePrototype = prototype
end
 
--- Set the state of an addon or module
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
-- @name //addon//:SetEnabledState
-- @paramsig state
-- @param state the state of an addon or module (enabled=true, disabled=false)
function SetEnabledState(self, state)
self.enabledState = state
end
 
 
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
-- @paramsig
-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
-- end
local function IterateModules(self) return pairs(self.modules) end
 
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
 
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
-- @paramsig
-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
local function IsEnabled(self) return self.enabledState end
local mixins = {
NewModule = NewModule,
GetModule = GetModule,
Enable = Enable,
Disable = Disable,
EnableModule = EnableModule,
DisableModule = DisableModule,
IsEnabled = IsEnabled,
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
SetDefaultModuleState = SetDefaultModuleState,
SetDefaultModulePrototype = SetDefaultModulePrototype,
SetEnabledState = SetEnabledState,
IterateModules = IterateModules,
IterateEmbeds = IterateEmbeds,
GetName = GetName,
}
local function IsModule(self) return false end
local pmixins = {
defaultModuleState = true,
enabledState = true,
IsModule = IsModule,
}
-- Embed( target )
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
function Embed(target, skipPMixins)
for k, v in pairs(mixins) do
target[k] = v
end
if not skipPMixins then
for k, v in pairs(pmixins) do
target[k] = target[k] or v
end
end
end
 
 
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
 
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
 
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
 
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Enable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
 
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
 
safecall(addon.OnEnable, addon)
 
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
 
-- enable possible modules.
local modules = addon.orderedModules
for i = 1, #modules do
self:EnableAddon(modules[i])
end
end
return self.statuses[addon.name] -- return true if we're disabled
end
 
-- - Disable the addon
-- Note: This function is only used internally.
-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
 
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
 
safecall( addon.OnDisable, addon )
 
-- make sure we're still disabling...
if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
local modules = addon.orderedModules
for i = 1, #modules do
self:DisableAddon(modules[i])
end
end
 
return not self.statuses[addon.name] -- return true if we're disabled
end
 
--- Get an iterator over all registered addons.
-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
-- end
function AceAddon:IterateAddons() return pairs(self.addons) end
 
--- Get an iterator over the internal status registry.
-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
-- print("EnabledAddon: " .. name)
-- end
-- end
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
 
-- Following Iterators are deprecated, and their addon specific versions should be used
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
 
-- Event Handling
local function onEvent(this, event, arg1)
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
-- this might be an issue with recursion - TODO: validate
if event == "ADDON_LOADED" then addon.baseName = arg1 end
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
 
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
AceAddon:EnableAddon(addon)
end
end
end
end
 
AceAddon.frame:RegisterEvent("ADDON_LOADED")
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
AceAddon.frame:SetScript("OnEvent", onEvent)
 
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
Embed(addon, true)
end
 
-- 2010-10-27 nevcairiel - add new "orderedModules" table
if oldminor and oldminor < 10 then
for name, addon in pairs(AceAddon.addons) do
addon.orderedModules = {}
for module_name, module in pairs(addon.modules) do
tinsert(addon.orderedModules, module)
end
end
end
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceDB-3.0/AceDB-3.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDB-3.0.lua"/>
</Ui>
\ No newline at end of file
trunk/SoopUI 3.0 beta 1/SoopUI/Libs/AceDB-3.0/AceDB-3.0.lua New file
0,0 → 1,733
--- **AceDB-3.0** manages the SavedVariables of your addon.
-- It offers profile management, smart defaults and namespaces for modules.\\
-- Data can be saved in different data-types, depending on its intended usage.
-- The most common data-type is the `profile` type, which allows the user to choose
-- the active profile, and manage the profiles of all of his characters.\\
-- The following data types are available:
-- * **char** Character-specific data. Every character has its own database.
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
-- * **class** Class-specific data. All of the players characters of the same class share this database.
-- * **race** Race-specific data. All of the players characters of the same race share this database.
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
-- * **global** Global Data. All characters on the same account share this database.
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
--
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
-- of the DBObjectLib listed here. \\
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
--
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
--
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
--
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
--
-- -- declare defaults to be used in the DB
-- local defaults = {
-- profile = {
-- setting = true,
-- }
-- }
--
-- function MyAddon:OnInitialize()
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
-- end
-- @class file
-- @name AceDB-3.0.lua
-- @release $Id: AceDB-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 22
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
 
if not AceDB then return end -- No upgrade needed
 
-- Lua APIs
local type, pairs, next, error = type, pairs, next, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
 
-- WoW APIs
local _G = _G
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub
 
AceDB.db_registry = AceDB.db_registry or {}
AceDB.frame = AceDB.frame or CreateFrame("Frame")
 
local CallbackHandler
local CallbackDummy = { Fire = function() end }
 
local DBObjectLib = {}
 
--[[-------------------------------------------------------------------------
AceDB Utility Functions
---------------------------------------------------------------------------]]
 
-- Simple shallow copy for copying defaults
local function copyTable(src, dest)
if type(dest) ~= "table" then dest = {} end
if type(src) == "table" then
for k,v in pairs(src) do
if type(v) == "table" then
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
v = copyTable(v, dest[k])
end
dest[k] = v
end
end
return dest
end
 
-- Called to add defaults to a section of the database
--
-- When a ["*"] default section is indexed with a new key, a table is returned
-- and set in the host table. These tables must be cleaned up by removeDefaults
-- in order to ensure we don't write empty default tables.
local function copyDefaults(dest, src)
-- this happens if some value in the SV overwrites our default value with a non-table
--if type(dest) ~= "table" then return end
for k, v in pairs(src) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- This is a metatable used for table defaults
local mt = {
-- This handles the lookup and creation of new subtables
__index = function(t,k)
if k == nil then return nil end
local tbl = {}
copyDefaults(tbl, v)
rawset(t, k, tbl)
return tbl
end,
}
setmetatable(dest, mt)
-- handle already existing tables in the SV
for dk, dv in pairs(dest) do
if not rawget(src, dk) and type(dv) == "table" then
copyDefaults(dv, v)
end
end
else
-- Values are not tables, so this is just a simple return
local mt = {__index = function(t,k) return k~=nil and v or nil end}
setmetatable(dest, mt)
end
elseif type(v) == "table" then
if not rawget(dest, k) then rawset(dest, k, {}) end
if type(dest[k]) == "table" then
copyDefaults(dest[k], v)
if src['**'] then
copyDefaults(dest[k], src['**'])
end
end
else
if rawget(dest, k) == nil then
rawset(dest, k, v)
end
end
end
end
 
-- Called to remove all defaults in the default table from the database
local function removeDefaults(db, defaults, blocker)
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them
setmetatable(db, nil)
-- loop through the defaults and remove their content
for k,v in pairs(defaults) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- Loop through all the actual k,v pairs and remove
for key, value in pairs(db) do
if type(value) == "table" then
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
removeDefaults(value, v)
-- if the table is empty afterwards, remove it
if next(value) == nil then
db[key] = nil
end
-- if it was specified, only strip ** content, but block values which were set in the key table
elseif k == "**" then
removeDefaults(value, v, defaults[key])
end
end
end
elseif k == "*" then
-- check for non-table default
for key, value in pairs(db) do
if defaults[key] == nil and v == value then
db[key] = nil
end
end
end
elseif type(v) == "table" and type(db[k]) == "table" then
-- if a blocker was set, dive into it, to allow multi-level defaults
removeDefaults(db[k], v, blocker and blocker[k])
if next(db[k]) == nil then
db[k] = nil
end
else
-- check if the current value matches the default, and that its not blocked by another defaults table
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
db[k] = nil
end
end
end
end
 
-- This is called when a table section is first accessed, to set up the defaults
local function initSection(db, section, svstore, key, defaults)
local sv = rawget(db, "sv")
 
local tableCreated
if not sv[svstore] then sv[svstore] = {} end
if not sv[svstore][key] then
sv[svstore][key] = {}
tableCreated = true
end
 
local tbl = sv[svstore][key]
 
if defaults then
copyDefaults(tbl, defaults)
end
rawset(db, section, tbl)
 
return tableCreated, tbl
end
 
-- Metatable to handle the dynamic creation of sections and copying of sections.
local dbmt = {
__index = function(t, section)
local keys = rawget(t, "keys")
local key = keys[section]
if key then
local defaultTbl = rawget(t, "defaults")
local defaults = defaultTbl and defaultTbl[section]
 
if section == "profile" then
local new = initSection(t, section, "profiles", key, defaults)
if new then
-- Callback: OnNewProfile, database, newProfileKey
t.callbacks:Fire("OnNewProfile", t, key)
end
elseif section == "profiles" then
local sv = rawget(t, "sv")
if not sv.profiles then sv.profiles = {} end
rawset(t, "profiles", sv.profiles)
elseif section == "global" then
local sv = rawget(t, "sv")
if not sv.global then sv.global = {} end
if defaults then
copyDefaults(sv.global, defaults)
end
rawset(t, section, sv.global)
else
initSection(t, section, section, key, defaults)
end
end
 
return rawget(t, section)
end
}
 
local function validateDefaults(defaults, keyTbl, offset)
if not defaults then return end
offset = offset or 0
for k in pairs(defaults) do
if not keyTbl[k] or k == "profiles" then
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
end
end
end
 
local preserve_keys = {
["callbacks"] = true,
["RegisterCallback"] = true,
["UnregisterCallback"] = true,
["UnregisterAllCallbacks"] = true,
["children"] = true,
}
 
local realmKey = GetRealmName()
local charKey = UnitName("player") .. " - " .. realmKey
local _, classKey = UnitClass("player")
local _, raceKey = UnitRace("player")
local factionKey = UnitFactionGroup("player")
local factionrealmKey = factionKey .. " - " .. realmKey
local factionrealmregionKey = factionrealmKey .. " - " .. string.sub(GetCVar("realmList"), 1, 2):upper()
local localeKey = GetLocale():lower()
 
-- Actual database initialization function
local function initdb(sv, defaults, defaultProfile, olddb, parent)
-- Generate the database keys for each section
 
-- map "true" to our "Default" profile
if defaultProfile == true then defaultProfile = "Default" end
 
local profileKey
if not parent then
-- Make a container for profile keys
if not sv.profileKeys then sv.profileKeys = {} end
 
-- Try to get the profile selected from the char db
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
 
-- save the selected profile for later
sv.profileKeys[charKey] = profileKey
else
-- Use the profile of the parents DB
profileKey = parent.keys.profile or defaultProfile or charKey
 
-- clear the profileKeys in the DB, namespaces don't need to store them
sv.profileKeys = nil
end
 
-- This table contains keys that enable the dynamic creation
-- of each section of the table. The 'global' and 'profiles'
-- have a key of true, since they are handled in a special case
local keyTbl= {
["char"] = charKey,
["realm"] = realmKey,
["class"] = classKey,
["race"] = raceKey,
["faction"] = factionKey,
["factionrealm"] = factionrealmKey,
["factionrealmregion"] = factionrealmregionKey,
["profile"] = profileKey,
["locale"] = localeKey,
["global"] = true,
["profiles"] = true,
}
 
validateDefaults(defaults, keyTbl, 1)
 
-- This allows us to use this function to reset an entire database
-- Clear out the old database
if olddb then
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
end
 
-- Give this database the metatable so it initializes dynamically
local db = setmetatable(olddb or {}, dbmt)
 
if not rawget(db, "callbacks") then
-- try to load CallbackHandler-1.0 if it loaded after our library
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
end
 
-- Copy methods locally into the database object, to avoid hitting
-- the metatable when calling methods
 
if not parent then
for name, func in pairs(DBObjectLib) do
db[name] = func
end
else
-- hack this one in
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
 
-- Set some properties in the database object
db.profiles = sv.profiles
db.keys = keyTbl
db.sv = sv
--db.sv_name = name
db.defaults = defaults
db.parent = parent
 
-- store the DB in the registry
AceDB.db_registry[db] = true
 
return db
end
 
-- handle PLAYER_LOGOUT
-- strip all defaults from all databases
-- and cleans up empty sections
local function logoutHandler(frame, event)
if event == "PLAYER_LOGOUT" then
for db in pairs(AceDB.db_registry) do
db.callbacks:Fire("OnDatabaseShutdown", db)
db:RegisterDefaults(nil)
 
-- cleanup sections that are empty without defaults
local sv = rawget(db, "sv")
for section in pairs(db.keys) do
if rawget(sv, section) then
-- global is special, all other sections have sub-entrys
-- also don't delete empty profiles on main dbs, only on namespaces
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
for key in pairs(sv[section]) do
if not next(sv[section][key]) then
sv[section][key] = nil
end
end
end
if not next(sv[section]) then
sv[section] = nil
end
end
end
end
end
end
 
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
AceDB.frame:SetScript("OnEvent", logoutHandler)
 
 
--[[-------------------------------------------------------------------------
AceDB Object Method Definitions
---------------------------------------------------------------------------]]
 
--- Sets the defaults table for the given database object by clearing any
-- that are currently set, and then setting the new defaults.
-- @param defaults A table of defaults for this database
function DBObjectLib:RegisterDefaults(defaults)
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
end
 
validateDefaults(defaults, self.keys)
 
-- Remove any currently set defaults
if self.defaults then
for section,key in pairs(self.keys) do
if self.defaults[section] and rawget(self, section) then
removeDefaults(self[section], self.defaults[section])
end
end
end
 
-- Set the DBObject.defaults table
self.defaults = defaults
 
-- Copy in any defaults, only touching those sections already created
if defaults then
for section,key in pairs(self.keys) do
if defaults[section] and rawget(self, section) then
copyDefaults(self[section], defaults[section])
end
end
end
end
 
--- Changes the profile of the database and all of it's namespaces to the
-- supplied named profile
-- @param name The name of the profile to set as the current profile
function DBObjectLib:SetProfile(name)
if type(name) ~= "string" then
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
end
 
-- changing to the same profile, dont do anything
if name == self.keys.profile then return end
 
local oldProfile = self.profile
local defaults = self.defaults and self.defaults.profile
 
-- Callback: OnProfileShutdown, database
self.callbacks:Fire("OnProfileShutdown", self)
 
if oldProfile and defaults then
-- Remove the defaults from the old profile
removeDefaults(oldProfile, defaults)
end
 
self.profile = nil
self.keys["profile"] = name
 
-- if the storage exists, save the new profile
-- this won't exist on namespaces.
if self.sv.profileKeys then
self.sv.profileKeys[charKey] = name
end
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.SetProfile(db, name)
end
end
 
-- Callback: OnProfileChanged, database, newProfileKey
self.callbacks:Fire("OnProfileChanged", self, name)
end
 
--- Returns a table with the names of the existing profiles in the database.
-- You can optionally supply a table to re-use for this purpose.
-- @param tbl A table to store the profile names in (optional)
function DBObjectLib:GetProfiles(tbl)
if tbl and type(tbl) ~= "table" then
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
end
 
-- Clear the container table
if tbl then
for k,v in pairs(tbl) do tbl[k] = nil end
else
tbl = {}
end
 
local curProfile = self.keys.profile
 
local i = 0
for profileKey in pairs(self.profiles) do
i = i + 1
tbl[i] = profileKey
if curProfile and profileKey == curProfile then curProfile = nil end
end
 
-- Add the current profile, if it hasn't been created yet
if curProfile then
i = i + 1
tbl[i] = curProfile
end
 
return tbl, i
end
 
--- Returns the current profile name used by the database
function DBObjectLib:GetCurrentProfile()
return self.keys.profile
end
 
--- Deletes a named profile. This profile must not be the active profile.
-- @param name The name of the profile to be deleted
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:DeleteProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
end
 
if self.keys.profile == name then
error("Cannot delete the active profile in an AceDBObject.", 2)
end
 
if not rawget(self.profiles, name) and not silent then
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
end
 
self.profiles[name] = nil
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.DeleteProfile(db, name, true)
end
end
 
-- Callback: OnProfileDeleted, database, profileKey
self.callbacks:Fire("OnProfileDeleted", self, name)
end
 
--- Copies a named profile into the current profile, overwriting any conflicting
-- settings.
-- @param name The name of the profile to be copied into the current profile
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:CopyProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
end
 
if name == self.keys.profile then
error("Cannot have the same source and destination profiles.", 2)
end
 
if not rawget(self.profiles, name) and not silent then
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
end
 
-- Reset the profile before copying
DBObjectLib.ResetProfile(self, nil, true)
 
local profile = self.profile
local source = self.profiles[name]
 
copyTable(source, profile)
 
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.CopyProfile(db, name, true)
end
end
 
-- Callback: OnProfileCopied, database, sourceProfileKey
self.callbacks:Fire("OnProfileCopied", self, name)
end
 
--- Resets the current profile to the default values (if specified).
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
function DBObjectLib:ResetProfile(noChildren, noCallbacks)
local profile = self.profile
 
for k,v in pairs(profile) do
profile[k] = nil
end
 
local defaults = self.defaults and self.defaults.profile
if defaults then
copyDefaults(profile, defaults)
end
 
-- populate to child namespaces
if self.children and not noChildren then
for _, db in pairs(self.children) do
DBObjectLib.ResetProfile(db, nil, noCallbacks)
end
end
 
-- Callback: OnProfileReset, database
if not noCallbacks then
self.callbacks:Fire("OnProfileReset", self)
end
end
 
--- Resets the entire database, using the string defaultProfile as the new default
-- profile.
-- @param defaultProfile The profile name to use as the default
function DBObjectLib:ResetDB(defaultProfile)
if defaultProfile and type(defaultProfile) ~= "string" then
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
end
 
local sv = self.sv
for k,v in pairs(sv) do
sv[k] = nil
end
 
local parent = self.parent
 
initdb(sv, self.defaults, defaultProfile, self)
 
-- fix the child namespaces
if self.children then
if not sv.namespaces then sv.namespaces = {} end
for name, db in pairs(self.children) do
if not sv.namespaces[name] then sv.namespaces[name] = {} end
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
end
end
 
-- Callback: OnDatabaseReset, database
self.callbacks:Fire("OnDatabaseReset", self)
-- Callback: OnProfileChanged, database, profileKey
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
 
return self
end
 
--- Creates a new database namespace, directly tied to the database. This
-- is a full scale database in it's own rights other than the fact that
-- it cannot control its profile individually
-- @param name The name of the new namespace
-- @param defaults A table of values to use as defaults
function DBObjectLib:RegisterNamespace(name, defaults)
if type(name) ~= "string" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
end
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
end
if self.children and self.children[name] then
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
end
 
local sv = self.sv
if not sv.namespaces then sv.namespaces = {} end
if not sv.namespaces[name] then
sv.namespaces[name] = {}
end
 
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
 
if not self.children then self.children = {} end
self.children[name] = newDB
return newDB
end
 
--- Returns an already existing namespace from the database object.
-- @param name The name of the new namespace
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- local namespace = self.db:GetNamespace('namespace')
-- @return the namespace object if found
function DBObjectLib:GetNamespace(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
end
if not silent and not (self.children and self.children[name]) then
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
end
if not self.children then self.children = {} end
return self.children[name]
end
 
--[[-------------------------------------------------------------------------
AceDB Exposed Methods
---------------------------------------------------------------------------]]
 
--- Creates a new database object that can be used to handle database settings and profiles.
-- By default, an empty DB is created, using a character specific profile.
--
-- You can override the default profile used by passing any profile name as the third argument,
-- or by passing //true// as the third argument to use a globally shared profile called "Default".
--
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
-- will use a profile named "char", and not a character-specific profile.
-- @param tbl The name of variable, or table to use for the database
-- @param defaults A table of database defaults
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
-- You can also pass //true// to use a shared global profile called "Default".
-- @usage
-- -- Create an empty DB using a character-specific default profile.
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
-- @usage
-- -- Create a DB using defaults and using a shared default profile
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
function AceDB:New(tbl, defaults, defaultProfile)
if type(tbl) == "string" then
local name = tbl
tbl = _G[name]
if not tbl then
tbl = {}
_G[name] = tbl
end
end
 
if type(tbl) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
end
 
if defaults and type(defaults) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
end
 
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
end
 
return initdb(tbl, defaults, defaultProfile)
end
 
-- upgrade existing databases
for db in pairs(AceDB.db_registry) do
if not db.parent then
for name,func in pairs(DBObjectLib) do
db[name] = func
end
else
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
end
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-MINIMAP-BORDER1.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/DialogFrame-Corners-White.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Eclipse-Solar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Eclipse-Lunar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureArrowBelow.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureCopyNormal.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/NameplateOverlay.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-PVP-FFA.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/nameplate_bg.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-Tooltip-Border-Square.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-PVP-Horde.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-MINIMAP-BORDER.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Shadow.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/BLACK8X8.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-PVP-Alliance.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/statusbarTexture.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/blank.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Minimap_Border.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/ClockButtonBackground.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-Tooltip-Border-Square-Black.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureGlow.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/MMOIconsG.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/nameplate_highlight.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/normTex.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Runes.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-DialogBox-Border.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/bar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureNewGlow_LikeOverlayBorder.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/NameplateNewGlow.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Minimap_Border 2.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/NameplateNewGlow_LikeOverlayBorder.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/nameplate_threat.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-DialogBox-Border-White.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-Tooltip-Border-1.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/NameplateIconOverlay.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-Tooltip-Border.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureNewGlow_LessGlow.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureCopyHighlight.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Eclipse_Solar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/EclipseSolar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/Eclipse_Lunar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/EclipseLunar.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/NameplateNewGlow_LessGlow.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/nameplate_bar.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/textureArrowAbove.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Textures/UI-RaidTargetingIcons.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/LSMLaunch.lua New file
0,0 → 1,35
local S, C, Soop = unpack(select(2, ...)) -- Import: S - function; C - config; Soop - Database
local LSM = LibStub("LibSharedMedia-3.0")
 
--------------------------------------------------------------
-- Load Shared Media
--------------------------------------------------------------
 
 
-- Fonts
--------------------------------------------------------------
C["media"].font = LSM:Fetch("font", C["media"].font)
 
-- Minimap Media
C["minimap"].border = LSM:Fetch("border", C["minimap"].border)
 
-- Item Quality Border
C['general'].IQBorder = LSM:Fetch("border", C["general"].IQBorder)
 
 
 
-- Skins
--------------------------------------------------------------
 
 
-- -- Chat Media
-- C["chat"].border = LSM:Fetch("border", C["chat"].border)
-- C["chat"].background = LSM:Fetch("background", C["chat"].background)
-- C["chat"].editboxborder = LSM:Fetch("border", C["chat"].editboxborder)
-- C["chat"].editboxbackground = LSM:Fetch("background", C["chat"].editboxbackground)
-- C["chat"].sound = LSM:Fetch("sound", C["chat"].sound)
 
-- Datatext Media
C["datatext"].border = LSM:Fetch("border", C["datatext"].border)
C["datatext"].background = LSM:Fetch("background", C["datatext"].background)
 
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Sound/Whisper.mp3 Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Sound/Warning.mp3 Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/SFMoviePoster-Bold.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/VeraSe.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Bazooka.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Fitzgerald.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/swfit.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Adventure.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/BigNoodleTitling.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/YELLOWJACKET.TTF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/SFCovington.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/semplice.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/SFWonderComic.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Gentium.TTF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Expressway.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/LiberationSans.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/HookedUp.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/BasicUI.ttf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/DORISPP.TTF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/Fonts/Enigma__2.TTF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
trunk/SoopUI 3.0 beta 1/SoopUI/Media/LSM.lua New file
0,0 → 1,41
local LSM = LibStub("LibSharedMedia-3.0")
 
if LSM == nil then return end
 
--------------------------------------------------------------
-- Borders
--------------------------------------------------------------