/
local ttName, TipTop = ... |
local f = CreateFrame("FRAME") |
local LSM = LibStub("LibSharedMedia-3.0") |
local widgetLists = AceGUIWidgetLSMlists |
offsetX = "0" |
end |
db.offsetX = offsetX |
mover:ClearAllPoints() |
mover:SetPoint(db.anchorTo, UIParent, db.anchorTo, db.offsetX, db.offsetY) |
end, |
order = 14, |
}, |
offsetY = "0" |
end |
db.offsetY = offsetY |
mover:ClearAllPoints() |
mover:SetPoint(db.anchorTo, UIParent, db.anchorTo, db.offsetX, db.offsetY) |
end, |
order = 15, |
}, |
get = function() return db.topBar end, |
set = function() |
db.topBar = not db.topBar |
TipTop:SBarPosition() |
TipTop:SBPosition() |
end, |
order = 8, |
}, |
get = function() return db.insideBar end, |
set = function() |
db.insideBar = not db.insideBar |
TipTop:SBarPosition() |
TipTop:SBPosition() |
end, |
order = 9, |
}, |
--update for level increases from expansions |
local hugeLevel = 140 |
local hugeLevel = 150 |
local ttName, TipTop = ... |
--CREATE & ASSIGN FRAMES-- |
TipTop = CreateFrame("FRAME", nil, GameTooltip) |
local TipTop = TipTop |
local evfr = CreateFrame("Frame") |
local tt = GameTooltip |
local ttSBar = GameTooltipStatusBar |
local ttSBarBG = CreateFrame("Frame", nil, ttSBar) |
local LSM = LibStub("LibSharedMedia-3.0") |
local player = UnitName("player") |
local server = GetRealmName() |
local _, db, BGPosition, color, font, classif, talentsGUID, factionIcon, factionTable |
local _, db, color, font, classif, talentsGUID, factionIcon, factionTable, ttStyle |
local specializationText = SPECIALIZATION..":" |
local tooltips = { GameTooltip, |
ItemRefTooltip, |
ShoppingTooltip2, |
ItemRefShoppingTooltip1, |
ItemRefShoppingTooltip2, |
WorldMapTooltip} |
WorldMapTooltip, |
WorldMapCompareTooltip1, |
WorldMapCompareTooltip2, |
AdventureMap_MissionPinTooltip} |
--UPVALUES-- |
local table_sort = _G.table.sort |
local GetSpecializationInfoByID = _G.GetSpecializationInfoByID |
local GetGuildInfo = _G.GetGuildInfo |
local strsplit = strsplit |
local SetBorderColor = tt.SetBackdropBorderColor |
function TipTop:SetBackgrounds() |
tooltips[i]:SetScale(db.scale) |
tooltips[i]:SetBackdrop(backdrop) |
tooltips[i]:SetBackdropColor(db.bgColor.r, db.bgColor.g, db.bgColor.b, db.alpha) |
tooltips[i]:SetBackdropBorderColor(db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
SetBorderColor(tooltips[i], db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end |
TipTop:SetBackdrop(backdrop) |
TipTop:SetBackdropColor(db.bgColor.r, db.bgColor.g, db.bgColor.b, db.alpha) |
TipTop:SetBackdropBorderColor(db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
TipTop:SetFrameLevel(tt:GetFrameLevel() - 1) --make sure the tooltip isn't overlapped by the bg frame |
--make the tooltip transparent (take away the bg) to see the TipTop frame behind it |
tt:SetBackdrop(nil) |
--make other frames look like TipTop's tooltips if they imitate the tooltip |
tt.GetBackdrop = function() return backdrop end |
tt.GetBackdropColor = function() return db.bgColor.r, db.bgColor.g, db.bgColor.b, db.alpha end |
tt.GetBackdropBorderColor = function() return db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a end |
-- TOOLTIP_DEFAULT_COLOR = db.borderColor |
-- TOOLTIP_DEFAULT_BACKGROUND_COLOR = db.bgColor |
-- make the map's tooltip always match (will reset itself on every OnShow) |
WorldMapTooltip.SetBackdropColor = function() end |
WorldMapTooltip.SetBackdropBorderColor = function() end |
--copy our style to default style (can't just do ttStyle = backdrop because there's other stuff in there) |
ttStyle.bgFile = backdrop.bgFile |
ttStyle.insets = backdrop.insets |
ttStyle.edgeFile = backdrop.edgeFile |
ttStyle.edgeSize = backdrop.edgeSize |
ttStyle.tile = false |
ttStyle.tileEdge = false |
ttStyle.backdropColor:SetRGBA(db.bgColor.r, db.bgColor.g, db.bgColor.b, db.alpha) |
ttStyle.backdropBorderColor:SetRGBA(db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end |
function TipTop:SetFonts() |
font = LSM:Fetch("font", db.font) --grab font from LSM |
font = LSM:Fetch("font", db.font) |
local size = db.fontSize |
if db.diffFont then |
ttHealth:SetFont(LSM:Fetch("font", db.healthFont), db.healthSize, "OUTLINE") |
ShoppingTooltip2TextLeft1:SetFont(font, size -2, db.fontFlag) |
ShoppingTooltip2TextLeft2:SetFont(font, size, db.fontFlag) |
ShoppingTooltip2TextLeft3:SetFont(font, size -2, db.fontFlag) |
--these were in the tips' onshow before - need to check later |
for i = 1, ShoppingTooltip1:NumLines() do |
_G["ShoppingTooltip1TextRight"..i]:SetFont(font, size -2, db.fontFlag) |
end |
ttSBarBG:SetBackdropColor(db.sbarbgcolor.r, db.sbarbgcolor.g, db.sbarbgcolor.b, db.sbarbgcolor.a) |
end |
function TipTop:SBarPosition() |
ttSBar:ClearAllPoints() |
function TipTop:SBPosition() --call on load and when setting changed |
if db.insideBar then |
if db.topBar then |
ttSBar:SetPoint("TOPRIGHT", tt, "TOPRIGHT", -7, 3) |
ttSBar:SetPoint("TOPLEFT", tt, "TOPLEFT", 10, 3) |
BGPosition = function() --make the TipTop bg frame resize around the health bar |
if ttSBar:IsShown() then |
TipTop:ClearAllPoints() |
TipTop:SetPoint("BOTTOMRIGHT", tt, "BOTTOMRIGHT", 2, 0) |
TipTop:SetPoint("TOPLEFT", ttSBar, "TOPLEFT", -9, 10) |
else |
TipTop:ClearAllPoints() |
TipTop:SetAllPoints(tt) |
end |
end |
ttSBar:ClearAllPoints() |
ttSBar:SetPoint("TOPLEFT", 7, -7) |
ttSBar:SetPoint("TOPRIGHT", -7, -7) |
else |
ttSBar:SetPoint("BOTTOMRIGHT", tt, "BOTTOMRIGHT", -7, -5) |
ttSBar:SetPoint("BOTTOMLEFT", tt, "BOTTOMLEFT", 11, -5) |
BGPosition = function() --make the TipTop bg frame resize around the health bar |
if ttSBar:IsShown() then |
TipTop:ClearAllPoints() |
TipTop:SetPoint("TOPRIGHT", tt, "TOPRIGHT", 2, 0) |
TipTop:SetPoint("BOTTOMLEFT", ttSBar, "BOTTOMLEFT", -9, -9) |
else |
TipTop:ClearAllPoints() |
TipTop:SetAllPoints(tt) |
end |
end |
ttSBar:ClearAllPoints() |
ttSBar:SetPoint("BOTTOMLEFT", 7, 7) |
ttSBar:SetPoint("BOTTOMRIGHT", -7, 7) |
end |
else |
if db.topBar then |
ttSBar:SetPoint("BOTTOMLEFT", tt, "TOPLEFT", 0, 4) |
ttSBar:SetPoint("BOTTOMRIGHT", tt, "TOPRIGHT", 0, 4) |
ttSBar:ClearAllPoints() |
ttSBar:SetPoint("BOTTOMLEFT", tt, "TOPLEFT", 2, 1) |
ttSBar:SetPoint("BOTTOMRIGHT", tt, "TOPRIGHT", -2, 1) |
else |
ttSBar:SetPoint("TOPLEFT", tt, "BOTTOMLEFT", 0, -4) |
ttSBar:SetPoint("TOPRIGHT", tt, "BOTTOMRIGHT", 0, -4) |
ttSBar:ClearAllPoints() |
ttSBar:SetPoint("TOPLEFT", tt, "BOTTOMLEFT", 2, -1) |
ttSBar:SetPoint("TOPRIGHT", tt, "BOTTOMRIGHT", -2, -1) |
end |
BGPosition = function() end |
TipTop:ClearAllPoints() |
TipTop:SetAllPoints(tt) |
end |
end |
local function AdjustTooltipBG() --call when unit is set to tooltip |
if db.insideBar then |
if db.topBar then |
GameTooltipTextLeft1:ClearAllPoints() |
GameTooltipTextLeft1:SetPoint("TOPLEFT", 10, -23) |
tt:SetHeight(tt:GetHeight() + 13) |
else |
tt:SetHeight(tt:GetHeight() + 10) |
end |
end |
end |
function TipTop:FactionIcon() |
if not factionIcon then |
factionIcon = ttSBar:CreateTexture(nil, "OVERLAY") |
end |
factionIcon:SetWidth(db.factionIconSize) |
factionIcon:SetHeight(db.factionIconSize) |
factionIcon:SetPoint("CENTER", TipTop, db.factionIconPosition, db.factionIconX, db.factionIconY) |
factionIcon:SetPoint("CENTER", tt, db.factionIconPosition, db.factionIconX, db.factionIconY) |
factionIcon:Hide() |
end |
function TipTop:RaidIcon() |
raidIcon:SetWidth(db.raidIconSize) |
raidIcon:SetHeight(db.raidIconSize) |
raidIcon:SetTexture("Interface\\TARGETINGFRAME\\UI-RaidTargetingIcons") |
raidIcon:SetPoint("CENTER", TipTop, db.raidIconPosition, db.raidIconX, db.raidIconY) |
raidIcon:Hide() |
end |
local function FactionIconUpdate() |
if UnitPlayerControlled("mouseover") then |
factionIcon:SetTexture(factionTable[UnitFactionGroup("mouseover")]) |
end |
end |
function TipTop:RaidIcon() |
raidIcon:SetWidth(db.raidIconSize) |
raidIcon:SetHeight(db.raidIconSize) |
raidIcon:SetTexture("Interface\\TARGETINGFRAME\\UI-RaidTargetingIcons") |
raidIcon:SetPoint("CENTER", tt, db.raidIconPosition, db.raidIconX, db.raidIconY) |
raidIcon:Hide() |
end |
local function RaidIconUpdate() |
local icon = GetRaidTargetIndex("mouseover") |
if icon and icon < 9 then |
end |
if UnitIsDead("mouseover") or tapped or not UnitIsConnected("mouseover") then |
local borderColor = db.borderColor |
TipTop:SetBackdropBorderColor(borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
SetBorderColor(tt, borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
local bgColor = db.bgColor |
TipTop:SetBackdropColor(bgColor.r + .2, bgColor.g +.2, bgColor.b + .2, db.alpha-.1) |
tt:SetBackdropColor(bgColor.r + .2, bgColor.g +.2, bgColor.b + .2, db.alpha-.1) |
end |
end |
classif = UnitClassification("mouseover") |
if db.elite then |
if not elitetexture then |
elitetexture = TipTop:CreateTexture(nil, "OVERLAY") |
elitetexture = ttSBar:CreateTexture(nil, "OVERLAY") |
elitetexture:SetHeight(70) |
elitetexture:SetWidth(70) |
elitetexture:SetPoint("CENTER", TipTop, "TOPLEFT", 8, -18) |
elitetexture:SetPoint("CENTER", tt, "TOPLEFT", 8, -18) |
end |
elitetexture:Hide() |
end |
if guild then |
local text = nil |
text = GameTooltipTextLeft2:GetText() |
if text then --I don't know how, but text returned nil for somebody at some time... |
if text then |
if realm then |
text = strsplit("-", text) |
end |
if text == guild then |
GameTooltipTextLeft2:SetFormattedText("%s (%s)", text, rank) |
tt:Show() |
AdjustTooltipBG() |
end |
end |
end |
local isNPC = not UnitIsPlayer("mouseover") |
if db.diffColor and level then --if coloring by difficulty |
if db.classColor and class and UnitIsFriend("player", "mouseover") and ((isNPC and db.npcClassColor) or not isNPC) then --if class enabled, too, use that if unit is friendly |
TipTop:SetBackdropBorderColor(color[class].r - .2, color[class].g - .2, color[class].b - .2, db.borderColor.a) |
SetBorderColor(tt, color[class].r - .2, color[class].g - .2, color[class].b - .2, db.borderColor.a) |
else --all else, color by difficulty |
if level == -1 then --where a skull might show instead of a level # (account for bosses and elites being harder) |
level = hugeLevel |
level = level + 5 |
end |
level = GetQuestDifficultyColor(level) |
TipTop:SetBackdropBorderColor(level.r, level.g, level.b, db.borderColor.a) |
SetBorderColor(tt, level.r, level.g, level.b, db.borderColor.a) |
end |
elseif db.classColor and class and ((isNPC and db.npcClassColor) or not isNPC) then --if just coloring by class |
TipTop:SetBackdropBorderColor(color[class].r - .2, color[class].g - .2, color[class].b - .2, db.borderColor.a) |
SetBorderColor(tt, color[class].r - .2, color[class].g - .2, color[class].b - .2, db.borderColor.a) |
else --default border color |
local borderColor = db.borderColor |
TipTop:SetBackdropBorderColor(borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
SetBorderColor(tt, borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
end |
if db.classIcon and class and ((isNPC and db.npcClassIcon) or not isNPC)then |
local text = nil --reset text var to maybe, hopefully quell repeating icon issue... |
local text = nil --reset text var so as to not get a repeating icon issue... |
text = GameTooltipTextLeft1:GetText() |
if text then |
local path |
local x1, x2, y1, y2 = unpack(CLASS_ICON_TCOORDS[class]) |
GameTooltipTextLeft1:SetFormattedText("|T%s:22:22:0:0:256:256:%d:%d:%d:%d|t %s", path, x1*256, x2*256, y1*256, y2*256, text) |
tt:Show() |
AdjustTooltipBG() |
end |
end |
if db.sbarclass and class then |
local function ItemQualityBorder(tip) --colors tip border by item quality |
if db.itemColor then |
local _,item = tip:GetItem() --tip is whatever tooltip called the OnTooltipSetItem script |
local _,item = tip:GetItem() |
if item then |
local _,_,quality = GetItemInfo(item) |
if quality then |
local r, g, b = qualityColor[quality].r, qualityColor[quality].g, qualityColor[quality].b |
local r, g, b = GetItemQualityColor(quality) |
if r and g and b then |
if tip == tt then |
TipTop:SetBackdropBorderColor(r - .2, g - .2, b - .2, db.borderColor.a) |
else |
tip:SetBackdropBorderColor(r - .2, g - .2, b - .2, db.borderColor.a) |
end |
SetBorderColor(tip, r - .2, g - .2, b - .2, db.borderColor.a) |
end |
end |
end |
else |
if tip == ItemRefTooltip then |
tip:SetBackdropBorderColor(db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
SetBorderColor(tip, db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end |
end |
end |
if db.healthText then |
local per, hpmult, hpdiv, maxhpmult, maxhpdiv, hpformat, maxhpformat --upvalues |
local maxhp = UnitHealthMax("mouseover") |
--if maxhp == 0 then maxhp = 1 end |
if maxhp == 0 then --mouseover unit no longer exists |
return |
end |
local hp = hp or UnitHealth("mouseover") |
if db.textformat == "100/100" then |
hp = tostring(hp) |
hp = tostring(hp) --needed to store huge health numbers as strings in WoD |
maxhp = tostring(maxhp) |
ttHealth:SetFormattedText("%s / %s", hp, maxhp) |
elseif db.textformat == "100%" then |
per = (hp/maxhp) * 100 |
if per <= 100 then --gives maxhp of 1 sometimes when tooltip fades? |
if per <= 100 then |
ttHealth:SetFormattedText("%d%%", per) |
end |
elseif db.textformat == "100/100 (100%)" then |
right:SetTextColor(color[tclass].r,color[tclass].g,color[tclass].b) |
end |
tt:Show() |
AdjustTooltipBG() |
targetLine = true |
end |
end |
tt:AddDoubleLine("Target:", "<<YOU>>", nil, nil, nil, .9, 0, .1) |
else |
local tcolor = color[tclass] |
if tcolor then --sometimes get an error about tcolor being nil - maybe from tips appearing/disappearing too fast? |
if tcolor then |
tt:AddDoubleLine("Target:", target, nil,nil,nil,tcolor.r,tcolor.g,tcolor.b) |
end |
end |
tt:Show() |
AdjustTooltipBG(true) |
else |
targetLine = false |
end |
end |
end |
if not talentline then |
--we'll leave this in until the default UI gets all the kinks out |
if InspectFrame and InspectFrame:IsShown() then --to not step on default UI's toes |
tt:AddDoubleLine(specializationText, "Inspect Frame is open", nil,nil,nil, 1,0,0) |
elseif Examiner and Examiner:IsShown() then --same thing with Examiner |
else |
talentsGUID = UnitGUID("mouseover") |
NotifyInspect("mouseover") |
TipTop:RegisterEvent("INSPECT_READY") |
evfr:RegisterEvent("INSPECT_READY") |
tt:AddDoubleLine(specializationText, "...") --adds the Talents line with a placeholder for info |
end |
tt:Show() |
AdjustTooltipBG() |
end |
end |
end |
if leftText == specializationText then --finds the Talents line and updates with info |
_G[GameTooltip:GetName().."TextRight"..i]:SetText(select(2,GetSpecializationInfoByID(maxtree))) |
tt:Show() |
AdjustTooltipBG() |
break |
end |
end |
end |
end |
TipTop:UnregisterEvent("INSPECT_READY") |
evfr:UnregisterEvent("INSPECT_READY") |
maxtree = nil --reset this variable |
end |
local ttWidth |
local function MouseoverTargetUpdate() --do this stuff whenever the mouseover unit is changed |
AdjustTooltipBG() |
Appendices() |
BorderClassColor() |
CalcHealth() |
end |
end |
local function TipShow() --do this stuff whenever the tip is shown |
if not tt:GetUnit() and not tt:GetItem() then |
local borderColor = db.borderColor |
TipTop:SetBackdropBorderColor(borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
end |
local bgColor = db.bgColor |
TipTop:SetBackdropColor(bgColor.r, bgColor.g, bgColor.b, db.alpha) |
BGPosition() |
if elitetexture then |
elitetexture:Hide() --hide this in case tip isn't showing a unit or the unit is not elite/rare atm |
end |
end |
local function PlayerLogin() |
if TipTopPCDB.charSpec then |
db = TipTopPCDB |
else |
db = TipTopDB |
end |
--set the default style to ours |
ttStyle = GAME_TOOLTIP_BACKDROP_STYLE_DEFAULT |
--totally ugly chunk of code to ensure tooltip style and colors are consistent |
tt:HookScript("OnTooltipCleared", function(self) |
if not self:GetUnit() and not self:GetItem() then |
local borderColor = db.borderColor |
SetBorderColor(self, borderColor.r, borderColor.g, borderColor.b, borderColor.a) |
end |
end) |
hooksecurefunc("GameTooltip_SetBackdropStyle", function(self) |
SetBorderColor(self, db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end) |
WorldMapTooltip:HookScript("OnShow", function(self) |
SetBorderColor(self, db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end) |
QuestScrollFrame.StoryTooltip:HookScript("OnShow", function(self) |
self:SetBackdrop(ttStyle) |
SetBorderColor(self, db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end) |
QuestScrollFrame.WarCampaignTooltip:HookScript("OnShow", function(self) |
self:SetBackdrop(ttStyle) |
SetBorderColor(self, db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
end) |
TipTop:SetBackgrounds() |
TipTop:SBarCustom() |
TipTop:SBarPosition() |
TipTop:SBPosition() |
TipTop:SetFonts() |
TipTop:RaidIcon() |
if db.factionIcon then |
if CUSTOM_CLASS_COLORS then |
CUSTOM_CLASS_COLORS:RegisterCallback(function() color = CUSTOM_CLASS_COLORS end) |
end |
--moves tooltip |
local mover = TipTop.mover |
hooksecurefunc("GameTooltip_SetDefaultAnchor", function (tooltip, parent) |
end |
end) |
TipTop:UnregisterEvent("PLAYER_LOGIN") |
TipTop:RegisterEvent("UPDATE_MOUSEOVER_UNIT") |
TipTop:SetScript("OnEvent", function(_, event, arg) |
if event == "UPDATE_MOUSEOVER_UNIT" then |
MouseoverTargetUpdate() |
elseif event == "INSPECT_READY" then |
if talentsGUID == arg then --only gather information about the unit we requested |
TalentText() |
end |
end |
end) |
--set item tooltip hook |
local moneyfontset |
for i=1,#tooltips do |
tooltips[i]:HookScript("OnTooltipSetItem", function(tip) |
if tooltips[i]:GetScript("OnTooltipSetItem") then |
tooltips[i]:HookScript("OnTooltipSetItem", function(tip) |
ItemQualityBorder(tip) |
--the vendor price strings don't exist until the first time they're needed |
if GameTooltipMoneyFrame1 and not moneyfontset then |
moneyfontset = true |
end |
end) |
end |
tooltips[i].SetBackdropBorderColor = function() end |
end |
--sb text updates |
ttSBar:HookScript("OnValueChanged", CalcHealth) |
ttSBar:HookScript("OnUpdate", TargetTextUpdate) |
local timer, hasUnit = 0, false |
tt:HookScript("OnUpdate", function(self, elapsed) --hack to fix when the background doesn't resize correctly (when the tooltip's or bg's OnShow isn't fired) |
if timer >= .5 and db.insideBar then |
if self:GetUnit() then |
if not hasUnit then --if I didn't have a unit before but do now |
BGPosition() |
hasUnit = true |
end |
else |
if hasUnit then --if I did have a unit and don't anymore |
TipTop:ClearAllPoints() |
TipTop:SetAllPoints(tt) |
TipTop:SetBackdropBorderColor(db.borderColor.r, db.borderColor.g, db.borderColor.b, db.borderColor.a) |
hasUnit = false |
end |
evfr:UnregisterEvent("PLAYER_LOGIN") |
evfr:RegisterEvent("UPDATE_MOUSEOVER_UNIT") |
evfr:SetScript("OnEvent", function(_, event, arg) |
if event == "UPDATE_MOUSEOVER_UNIT" then |
MouseoverTargetUpdate() |
elseif event == "INSPECT_READY" then |
if talentsGUID == arg then --only gather information about the unit we requested |
TalentText() |
end |
timer = 0 |
end |
timer = timer + elapsed |
end) |
PlayerLogin = nil --let this function be garbage collected |
end |
TipTop:RegisterEvent("PLAYER_LOGIN") |
TipTop:SetScript("OnEvent", PlayerLogin) |
TipTop:SetScript("OnShow", TipShow) |
## Title: TipTop |
## Author: Seerah |
## Notes: Tooltip enhancement |
## Version: 2.20 |
## Version: 3.0 |
## SavedVariables: TipTopDB |
## SavedVariablesPerCharacter: TipTopPCDB |
## OptionalDeps: Ace3, LibSharedMedia-3.0, AceGUI-3.0-SharedMediaWidgets |
end |
local function closeOnClick(this) |
PlaySound(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT |
PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT |
this.obj:Hide() |
end |
TreeGroup Container |
Container that uses a tree control to switch between groups. |
-------------------------------------------------------------------------------]] |
local Type, Version = "TreeGroup", 40 |
local Type, Version = "TreeGroup", 41 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
local WoW80 = select(4, GetBuildInfo()) >= 80000 |
-- Lua APIs |
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type |
local math_min, math_max, floor = math.min, math.max, floor |
local function FirstFrameUpdate(frame) |
local self = frame.obj |
frame:SetScript("OnUpdate", nil) |
self:RefreshTree() |
self:RefreshTree(nil, true) |
end |
local function BuildUniqueValue(...) |
["OnRelease"] = function(self) |
self.status = nil |
self.tree = nil |
self.frame:SetScript("OnUpdate", nil) |
for k, v in pairs(self.localstatus) do |
if k == "groups" then |
for k2 in pairs(v) do |
end |
end, |
["RefreshTree"] = function(self,scrollToSelection) |
local buttons = self.buttons |
["RefreshTree"] = function(self,scrollToSelection,fromOnUpdate) |
local buttons = self.buttons |
local lines = self.lines |
for i, v in ipairs(buttons) do |
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18)) |
if maxlines <= 0 then return end |
-- workaround for lag spikes on WoW 8.0 |
if WoW80 and self.frame:GetParent() == UIParent and not fromOnUpdate then |
self.frame:SetScript("OnUpdate", FirstFrameUpdate) |
return |
end |
local first, last |
scrollToSelection = status.scrollToSelection |
-------------------------------------------------------------------------------]] |
local function Button_OnClick(frame, ...) |
AceGUI:ClearFocus() |
PlaySound(PlaySoundKitID and "igMainMenuOption" or 852) -- SOUNDKIT.IG_MAINMENU_OPTION |
PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION |
frame.obj:Fire("OnClick", ...) |
end |
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]-- |
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
if self.disabled then return end |
self.value = not self.value |
if self.value then |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
else |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF |
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF |
end |
UpdateToggle(self) |
self:Fire("OnValueChanged", self.value) |
end |
if value then |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
self.slider:SetValue(value) |
self:Fire("OnMouseUp", value) |
end |
-------------------------------------------------------------------------------]] |
local function Tab_OnClick(frame) |
if not (frame.selected or frame.disabled) then |
PlaySound(PlaySoundKitID and "igCharacterInfoTab" or 841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB |
PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB |
frame.obj:SelectTab(frame.value) |
end |
end |
--[[----------------------------------------------------------------------------- |
Checkbox Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "CheckBox", 23 |
local Type, Version = "CheckBox", 24 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT") |
self.text:SetPoint("RIGHT") |
else |
self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0) |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT", self.image:GetWidth() + 2, 0) |
self.text:SetPoint("RIGHT") |
end |
end |
self:ToggleChecked() |
if self.checked then |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
else -- for both nil and false (tristate) |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF |
PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF |
end |
self:Fire("OnValueChanged", self.checked) |
desc:ClearAllPoints() |
desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21) |
desc:SetWidth(self.frame.width - 30) |
desc:SetPoint("RIGHT", self.frame, "RIGHT", -30, 0) |
desc:SetJustifyH("LEFT") |
desc:SetJustifyV("TOP") |
self.desc = desc |
Scripts |
-------------------------------------------------------------------------------]] |
local function Button_OnClick(frame) |
PlaySound(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT |
PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT |
frame.obj:Hide() |
end |
--[[ $Id: AceGUIWidget-DropDown.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]-- |
--[[ $Id: AceGUIWidget-DropDown.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
-- Lua APIs |
local function Dropdown_TogglePullout(this) |
local self = this.obj |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
if self.open then |
self.open = nil |
self.pullout:Close() |
--[[----------------------------------------------------------------------------- |
EditBox Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "EditBox", 27 |
local Type, Version = "EditBox", 28 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
local value = frame:GetText() |
local cancel = self:Fire("OnEnterPressed", value) |
if not cancel then |
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
HideButton(self) |
end |
end |
local function EditBox_OnReceiveDrag(frame) |
local self = frame.obj |
local type, id, info = GetCursorInfo() |
local name |
if type == "item" then |
self:SetText(info) |
self:Fire("OnEnterPressed", info) |
ClearCursor() |
name = info |
elseif type == "spell" then |
local name = GetSpellInfo(id, info) |
self:SetText(name) |
self:Fire("OnEnterPressed", name) |
ClearCursor() |
name = GetSpellInfo(id, info) |
elseif type == "macro" then |
local name = GetMacroInfo(id) |
name = GetMacroInfo(id) |
end |
if name then |
self:SetText(name) |
self:Fire("OnEnterPressed", name) |
ClearCursor() |
HideButton(self) |
AceGUI:ClearFocus() |
end |
HideButton(self) |
AceGUI:ClearFocus() |
end |
local function EditBox_OnTextChanged(frame) |
-- f:AddChild(btn) |
-- @class file |
-- @name AceGUI-3.0 |
-- @release $Id: AceGUI-3.0.lua 1102 2013-10-25 14:15:23Z nevcairiel $ |
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 34 |
-- @release $Id: AceGUI-3.0.lua 1177 2018-06-25 12:12:48Z nevcairiel $ |
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 36 |
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR) |
if not AceGUI then return end -- No upgrade needed |
height = height + rowheight + 3 |
safecall(content.obj.LayoutFinished, content.obj, nil, height) |
end) |
-- Get alignment method and value. Possible alignment methods are a callback, a number, "start", "middle", "end", "fill" or "TOPLEFT", "BOTTOMRIGHT" etc. |
local GetCellAlign = function (dir, tableObj, colObj, cellObj, cell, child) |
local fn = cellObj and (cellObj["align" .. dir] or cellObj.align) |
or colObj and (colObj["align" .. dir] or colObj.align) |
or tableObj["align" .. dir] or tableObj.align |
or "CENTERLEFT" |
local child, cell, val = child or 0, cell or 0, nil |
if type(fn) == "string" then |
fn = fn:lower() |
fn = dir == "V" and (fn:sub(1, 3) == "top" and "start" or fn:sub(1, 6) == "bottom" and "end" or fn:sub(1, 6) == "center" and "middle") |
or dir == "H" and (fn:sub(-4) == "left" and "start" or fn:sub(-5) == "right" and "end" or fn:sub(-6) == "center" and "middle") |
or fn |
val = (fn == "start" or fn == "fill") and 0 or fn == "end" and cell - child or (cell - child) / 2 |
elseif type(fn) == "function" then |
val = fn(child or 0, cell, dir) |
else |
val = fn |
end |
return fn, max(0, min(val, cell)) |
end |
-- Get width or height for multiple cells combined |
local GetCellDimension = function (dir, laneDim, from, to, space) |
local dim = 0 |
for cell=from,to do |
dim = dim + (laneDim[cell] or 0) |
end |
return dim + max(0, to - from) * (space or 0) |
end |
--[[ Options |
============ |
Container: |
- columns ({col, col, ...}): Column settings. "col" can be a number (<= 0: content width, <1: rel. width, <10: weight, >=10: abs. width) or a table with column setting. |
- space, spaceH, spaceV: Overall, horizontal and vertical spacing between cells. |
- align, alignH, alignV: Overall, horizontal and vertical cell alignment. See GetCellAlign() for possible values. |
Columns: |
- width: Fixed column width (nil or <=0: content width, <1: rel. width, >=1: abs. width). |
- min or 1: Min width for content based width |
- max or 2: Max width for content based width |
- weight: Flexible column width. The leftover width after accounting for fixed-width columns is distributed to weighted columns according to their weights. |
- align, alignH, alignV: Overwrites the container setting for alignment. |
Cell: |
- colspan: Makes a cell span multiple columns. |
- rowspan: Makes a cell span multiple rows. |
- align, alignH, alignV: Overwrites the container and column setting for alignment. |
]] |
AceGUI:RegisterLayout("Table", |
function (content, children) |
local obj = content.obj |
obj:PauseLayout() |
local tableObj = obj:GetUserData("table") |
local cols = tableObj.columns |
local spaceH = tableObj.spaceH or tableObj.space or 0 |
local spaceV = tableObj.spaceV or tableObj.space or 0 |
local totalH = (content:GetWidth() or content.width or 0) - spaceH * (#cols - 1) |
-- We need to reuse these because layout events can come in very frequently |
local layoutCache = obj:GetUserData("layoutCache") |
if not layoutCache then |
layoutCache = {{}, {}, {}, {}, {}, {}} |
obj:SetUserData("layoutCache", layoutCache) |
end |
local t, laneH, laneV, rowspans, rowStart, colStart = unpack(layoutCache) |
-- Create the grid |
local n, slotFound = 0 |
for i,child in ipairs(children) do |
if child:IsShown() then |
repeat |
n = n + 1 |
local col = (n - 1) % #cols + 1 |
local row = ceil(n / #cols) |
local rowspan = rowspans[col] |
local cell = rowspan and rowspan.child or child |
local cellObj = cell:GetUserData("cell") |
slotFound = not rowspan |
-- Rowspan |
if not rowspan and cellObj and cellObj.rowspan then |
rowspan = {child = child, from = row, to = row + cellObj.rowspan - 1} |
rowspans[col] = rowspan |
end |
if rowspan and i == #children then |
rowspan.to = row |
end |
-- Colspan |
local colspan = max(0, min((cellObj and cellObj.colspan or 1) - 1, #cols - col)) |
n = n + colspan |
-- Place the cell |
if not rowspan or rowspan.to == row then |
t[n] = cell |
rowStart[cell] = rowspan and rowspan.from or row |
colStart[cell] = col |
if rowspan then |
rowspans[col] = nil |
end |
end |
until slotFound |
end |
end |
local rows = ceil(n / #cols) |
-- Determine fixed size cols and collect weights |
local extantH, totalWeight = totalH, 0 |
for col,colObj in ipairs(cols) do |
laneH[col] = 0 |
if type(colObj) == "number" then |
colObj = {[colObj >= 1 and colObj < 10 and "weight" or "width"] = colObj} |
cols[col] = colObj |
end |
if colObj.weight then |
-- Weight |
totalWeight = totalWeight + (colObj.weight or 1) |
else |
if not colObj.width or colObj.width <= 0 then |
-- Content width |
for row=1,rows do |
local child = t[(row - 1) * #cols + col] |
if child then |
local f = child.frame |
f:ClearAllPoints() |
local childH = f:GetWidth() or 0 |
laneH[col] = max(laneH[col], childH - GetCellDimension("H", laneH, colStart[child], col - 1, spaceH)) |
end |
end |
laneH[col] = max(colObj.min or colObj[1] or 0, min(laneH[col], colObj.max or colObj[2] or laneH[col])) |
else |
-- Rel./Abs. width |
laneH[col] = colObj.width < 1 and colObj.width * totalH or colObj.width |
end |
extantH = max(0, extantH - laneH[col]) |
end |
end |
-- Determine sizes based on weight |
local scale = totalWeight > 0 and extantH / totalWeight or 0 |
for col,colObj in pairs(cols) do |
if colObj.weight then |
laneH[col] = scale * colObj.weight |
end |
end |
-- Arrange children |
for row=1,rows do |
local rowV = 0 |
-- Horizontal placement and sizing |
for col=1,#cols do |
local child = t[(row - 1) * #cols + col] |
if child then |
local colObj = cols[colStart[child]] |
local cellObj = child:GetUserData("cell") |
local offsetH = GetCellDimension("H", laneH, 1, colStart[child] - 1, spaceH) + (colStart[child] == 1 and 0 or spaceH) |
local cellH = GetCellDimension("H", laneH, colStart[child], col, spaceH) |
local f = child.frame |
f:ClearAllPoints() |
local childH = f:GetWidth() or 0 |
local alignFn, align = GetCellAlign("H", tableObj, colObj, cellObj, cellH, childH) |
f:SetPoint("LEFT", content, offsetH + align, 0) |
if child:IsFullWidth() or alignFn == "fill" or childH > cellH then |
f:SetPoint("RIGHT", content, "LEFT", offsetH + align + cellH, 0) |
end |
if child.DoLayout then |
child:DoLayout() |
end |
rowV = max(rowV, (f:GetHeight() or 0) - GetCellDimension("V", laneV, rowStart[child], row - 1, spaceV)) |
end |
end |
laneV[row] = rowV |
-- Vertical placement and sizing |
for col=1,#cols do |
local child = t[(row - 1) * #cols + col] |
if child then |
local colObj = cols[colStart[child]] |
local cellObj = child:GetUserData("cell") |
local offsetV = GetCellDimension("V", laneV, 1, rowStart[child] - 1, spaceV) + (rowStart[child] == 1 and 0 or spaceV) |
local cellV = GetCellDimension("V", laneV, rowStart[child], row, spaceV) |
local f = child.frame |
local childV = f:GetHeight() or 0 |
local alignFn, align = GetCellAlign("V", tableObj, colObj, cellObj, cellV, childV) |
if child:IsFullHeight() or alignFn == "fill" then |
f:SetHeight(cellV) |
end |
f:SetPoint("TOP", content, 0, -(offsetV + align)) |
end |
end |
end |
-- Calculate total height |
local totalV = GetCellDimension("V", laneV, 1, #laneV, spaceV) |
-- Cleanup |
for _,v in pairs(layoutCache) do wipe(v) end |
safecall(obj.LayoutFinished, obj, nil, totalV) |
obj:ResumeLayout() |
end) |
<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> |
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables. |
-- @class file |
-- @name AceConfigDialog-3.0 |
-- @release $Id: AceConfigDialog-3.0.lua 1163 2017-08-14 14:04:39Z nevcairiel $ |
-- @release $Id: AceConfigDialog-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $ |
local LibStub = LibStub |
local gui = LibStub("AceGUI-3.0") |
local reg = LibStub("AceConfigRegistry-3.0") |
local MAJOR, MINOR = "AceConfigDialog-3.0", 64 |
local MAJOR, MINOR = "AceConfigDialog-3.0", 66 |
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceConfigDialog then return end |
else |
validationErrorPopup(validated) |
end |
PlaySound(PlaySoundKitID and "igPlayerInviteDecline" or 882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || XXX _DECLINE is actually missing from the table |
PlaySound(882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || _DECLINE is actually missing from the table |
del(info) |
return true |
else |
entry.value = k |
entry.text = GetOptionsMemberValue("name", v, options, path, appName) |
entry.icon = GetOptionsMemberValue("icon", v, options, path, appName) |
entry.iconCoords = GetOptionsMemberValue("iconCoords", v, options, path, appName) |
entry.disabled = CheckOptionDisabled(v, options, path, appName) |
tinsert(tree,entry) |
if recurse and (v.childGroups or "tree") == "tree" then |
radio:SetWidth(width_multiplier * 2) |
elseif width == "half" then |
radio:SetWidth(width_multiplier / 2) |
elseif (type(width) == "number") then |
radio:SetWidth(width_multiplier * width) |
elseif width == "full" then |
radio.width = "fill" |
else |
control:SetWidth(width_multiplier * 2) |
elseif width == "half" then |
control:SetWidth(width_multiplier / 2) |
elseif (type(width) == "number") then |
control:SetWidth(width_multiplier * width) |
elseif width == "full" then |
control.width = "fill" |
else |
check:SetWidth(width_multiplier * 2) |
elseif width == "half" then |
check:SetWidth(width_multiplier / 2) |
elseif (type(width) == "number") then |
control:SetWidth(width_multiplier * width) |
elseif width == "full" then |
check.width = "fill" |
else |
control:SetWidth(width_multiplier * 2) |
elseif width == "half" then |
control:SetWidth(width_multiplier / 2) |
elseif (type(width) == "number") then |
control:SetWidth(width_multiplier * width) |
elseif width == "full" then |
control.width = "fill" |
else |
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName". |
-- @class file |
-- @name AceConfigRegistry-3.0 |
-- @release $Id: AceConfigRegistry-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $ |
-- @release $Id: AceConfigRegistry-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $ |
local CallbackHandler = LibStub("CallbackHandler-1.0") |
local MAJOR, MINOR = "AceConfigRegistry-3.0", 17 |
local MAJOR, MINOR = "AceConfigRegistry-3.0", 18 |
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceConfigRegistry then return end |
local opttable={["nil"]=true,["table"]=true, _="table"} |
local optbool={["nil"]=true,["boolean"]=true, _="boolean"} |
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"} |
local optstringnumber={["nil"]=true,["string"]=true,["number"]=true, _="string or number"} |
local basekeys={ |
type=isstring, |
set=optmethodfalse, |
func=optmethodfalse, |
arg={["*"]=true}, |
width=optstring, |
width=optstringnumber, |
} |
local typedkeys={ |