20e276a042
Les flèches de page gardaient les retraits de zone cliquable du client 3.3.5 (6 et 7 px pour un bouton de 32 x 32) sur un bouton de 17 x 14 : aucune zone ne restait cliquable. Elles n'en ont plus, comme celles de camelot. Le niveau d'une cible attaquable prend la couleur de sa difficulté (GetQuestDifficultyColor, comme TargetFrame_CheckLevel), doré sinon ; « ?? » prend la couleur la plus difficile. Recalculé sur UNIT_FACTION de la cible et du joueur. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
492 lines
17 KiB
Lua
492 lines
17 KiB
Lua
-- Main action bar: the client's secure action buttons, kept and reskinned (camelot
|
|
-- ActionButtonTemplate, MainActionBar), with the bar border, page arrows and gryphon end caps.
|
|
-- Recreating the buttons would mean rewriting spells, macros and drag and drop, and risk taint.
|
|
-- Nothing is resized or moved in combat, where the client forbids it.
|
|
|
|
-- camelot ActionButtonTemplate: 45 x 45; shared/ActionBar.lua minButtonPadding = 2
|
|
local BUTTON_SIZE = 45
|
|
local BUTTON_PADDING = 2
|
|
local BUTTON_PITCH = BUTTON_SIZE + BUTTON_PADDING
|
|
local FRAME_WIDTH, FRAME_HEIGHT = 46, 45 -- size of the four state textures
|
|
local BUTTON_COUNT = 12
|
|
local END_CAP_WIDTH, END_CAP_HEIGHT = 154, 95
|
|
local END_CAP_DROP = -2 -- measured on screen: the art bottom drops 2 px below the bar
|
|
local L = ForeverUI.L
|
|
|
|
local ATLAS = {
|
|
normal = "ui-hud-actionbar-iconframe",
|
|
pushed = "ui-hud-actionbar-iconframe-down",
|
|
highlight = "ui-hud-actionbar-iconframe-mouseover",
|
|
border = "ui-hud-actionbar-iconframe-border",
|
|
slot = "ui-hud-actionbar-iconframe-slot",
|
|
background = "ui-hud-actionbar-iconframe-background",
|
|
flash = "ui-hud-actionbar-iconframe-flash",
|
|
}
|
|
|
|
local BARS = {
|
|
"ActionButton", "MultiBarBottomLeftButton", "MultiBarBottomRightButton",
|
|
"MultiBarRightButton", "MultiBarLeftButton", "BonusActionButton",
|
|
}
|
|
|
|
-- The frame is not the button's NormalTexture: ActionButton_Update sets UI-Quickslot2 on
|
|
-- every refresh and ActionButton_ShowGrid recolors it, erasing any skin. So the client's
|
|
-- texture is silenced and we draw our own frame. add: use the ADD blend mode.
|
|
local function setStateTexture(texture, atlas, add)
|
|
if not texture then
|
|
return
|
|
end
|
|
|
|
ForeverUI.SetAtlas(texture, atlas, true)
|
|
texture:SetWidth(FRAME_WIDTH)
|
|
texture:SetHeight(FRAME_HEIGHT)
|
|
texture:ClearAllPoints()
|
|
texture:SetPoint("TOPLEFT", 0, 0)
|
|
texture:SetBlendMode(add and "ADD" or "BLEND")
|
|
end
|
|
|
|
-- Hide again what the client just rewrote.
|
|
local function silenceNormalTexture(button)
|
|
local normal = button:GetNormalTexture()
|
|
if normal then
|
|
normal:SetAlpha(0)
|
|
normal:SetVertexColor(1, 1, 1, 0)
|
|
end
|
|
end
|
|
|
|
-- 3.3.5 trap: ActionButton_Update and ActionButton_HideGrid hide the WHOLE empty button while
|
|
-- its "showgrid" ATTRIBUTE is 0, and it only rises during a drag, so empty slots vanish, in
|
|
-- combat too (a stance change updates every button). Keeping the attribute at 1 makes the
|
|
-- client keep empty buttons shown. A secure frame changes only out of combat;
|
|
-- PLAYER_REGEN_ENABLED brings back anything hidden meanwhile.
|
|
local function keepGrid(button)
|
|
if not button or InCombatLockdown() or button:GetAttribute("statehidden") then
|
|
return
|
|
end
|
|
|
|
if (button:GetAttribute("showgrid") or 0) < 1 then
|
|
button:SetAttribute("showgrid", 1)
|
|
end
|
|
if not button:IsShown() then
|
|
button:Show()
|
|
end
|
|
end
|
|
|
|
local function skinButton(button)
|
|
if not button or button.foreverSkinned then
|
|
return
|
|
end
|
|
|
|
local name = button:GetName()
|
|
if not name then
|
|
return
|
|
end
|
|
|
|
local icon = _G[name .. "Icon"]
|
|
local border = _G[name .. "Border"]
|
|
local hotkey = _G[name .. "HotKey"]
|
|
local count = _G[name .. "Count"]
|
|
local macro = _G[name .. "Name"]
|
|
local cooldown = _G[name .. "Cooldown"]
|
|
local flash = _G[name .. "Flash"]
|
|
local floatingBG = _G[name .. "FloatingBG"]
|
|
|
|
button:SetWidth(BUTTON_SIZE)
|
|
button:SetHeight(BUTTON_SIZE)
|
|
|
|
-- Empty slot, under the icon.
|
|
local background = button:CreateTexture(nil, "BACKGROUND")
|
|
ForeverUI.SetAtlas(background, ATLAS.background, true)
|
|
background:SetAllPoints(button)
|
|
|
|
local slot = button:CreateTexture(nil, "BACKGROUND")
|
|
ForeverUI.SetAtlas(slot, ATLAS.slot, true)
|
|
slot:SetAllPoints(button)
|
|
|
|
button.foreverBackground = background
|
|
button.foreverSlot = slot
|
|
|
|
if icon then
|
|
-- The icon fills the button, as in camelot; 3.3.5 has no MaskTexture, so the frame's
|
|
-- solid corners cover the icon's corners.
|
|
icon:ClearAllPoints()
|
|
icon:SetAllPoints(button)
|
|
icon:SetTexCoord(0, 1, 0, 1)
|
|
icon:SetDrawLayer("BORDER")
|
|
end
|
|
|
|
-- Our frame, above the icon and out of the client's reach.
|
|
local frame = button:CreateTexture(nil, "ARTWORK")
|
|
setStateTexture(frame, ATLAS.normal)
|
|
button.foreverFrame = frame
|
|
|
|
silenceNormalTexture(button)
|
|
setStateTexture(button:GetPushedTexture(), ATLAS.pushed)
|
|
setStateTexture(button:GetHighlightTexture(), ATLAS.highlight)
|
|
setStateTexture(button:GetCheckedTexture(), ATLAS.highlight, true)
|
|
|
|
if flash then
|
|
ForeverUI.SetAtlas(flash, ATLAS.flash)
|
|
flash:ClearAllPoints()
|
|
flash:SetPoint("TOPLEFT", 0, 0)
|
|
end
|
|
|
|
if border then
|
|
-- The client's equipped border is green and square; camelot uses its own, hidden by default.
|
|
ForeverUI.SetAtlas(border, ATLAS.border)
|
|
border:ClearAllPoints()
|
|
border:SetPoint("TOPLEFT", 0, 0)
|
|
end
|
|
|
|
if floatingBG then
|
|
floatingBG:SetAlpha(0)
|
|
end
|
|
|
|
-- SetFontObject RESETS the justification, so set it AFTER. The number fonts have no
|
|
-- justifyH (client FontStyles.xml), so they are centered by default.
|
|
if hotkey then
|
|
hotkey:SetWidth(32)
|
|
hotkey:SetHeight(10)
|
|
hotkey:ClearAllPoints()
|
|
hotkey:SetPoint("TOPRIGHT", -5, -5)
|
|
hotkey:SetFontObject(NumberFontNormalSmallGray)
|
|
hotkey:SetJustifyH("RIGHT")
|
|
end
|
|
|
|
if count then
|
|
count:ClearAllPoints()
|
|
count:SetPoint("BOTTOMRIGHT", -5, 5)
|
|
count:SetFontObject(NumberFontNormal)
|
|
count:SetJustifyH("RIGHT")
|
|
end
|
|
|
|
if macro then
|
|
macro:SetWidth(36)
|
|
macro:SetHeight(10)
|
|
macro:ClearAllPoints()
|
|
macro:SetPoint("BOTTOM", 0, 2)
|
|
macro:SetFontObject(GameFontHighlightSmallOutline)
|
|
end
|
|
|
|
if cooldown and icon then
|
|
cooldown:ClearAllPoints()
|
|
cooldown:SetPoint("TOPLEFT", icon, "TOPLEFT", 3, -3)
|
|
cooldown:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -3, 3)
|
|
end
|
|
|
|
keepGrid(button)
|
|
button.foreverSkinned = true
|
|
end
|
|
|
|
-- ---------- Bar
|
|
local holder = CreateFrame("Frame", "ForeverUIActionBarHolder", UIParent)
|
|
holder:SetWidth(BUTTON_COUNT * BUTTON_SIZE + (BUTTON_COUNT - 1) * BUTTON_PADDING)
|
|
holder:SetHeight(BUTTON_SIZE)
|
|
|
|
-- Bar border: camelot's UI-HUD-ActionBar-Frame, one octagonal image, from TOPLEFT (-6, 6)
|
|
-- to BOTTOMRIGHT (4, -5). Nine-sliced so the corner bevels keep their size.
|
|
local border = CreateFrame("Frame", nil, holder)
|
|
border:SetPoint("TOPLEFT", -6, 6)
|
|
border:SetPoint("BOTTOMRIGHT", 4, -5)
|
|
border:SetFrameLevel(holder:GetFrameLevel())
|
|
ForeverUI.SetBarFrameArt(border)
|
|
|
|
-- Page block (mainline/MainActionBar.xml ActionBarPageNumber): BOTTOMRIGHT on the bar's
|
|
-- BOTTOMLEFT at (-4, 9); number 17 x 10 centered at -1, two 17 x 14 arrows at +10 and -10;
|
|
-- sized by its children: 17 x 34.
|
|
local page = CreateFrame("Frame", "ForeverUIActionBarPage", holder)
|
|
page:SetWidth(17)
|
|
page:SetHeight(34)
|
|
page:SetPoint("BOTTOMRIGHT", holder, "BOTTOMLEFT", -4, 9)
|
|
page:SetFrameLevel(holder:GetFrameLevel() + 11)
|
|
|
|
-- Dividers between buttons: RIGHT on the button's LEFT, offset 5.
|
|
local dividers = {}
|
|
|
|
-- End caps (gryphons): two 154 x 95 frames filled by their texture, movable on their own
|
|
-- (Customize UI); BottomBar.lua gives their default positions.
|
|
local END_CAP_INSET = 30 -- each cap overlaps its bar by 30 px
|
|
local function createEndCap(name, atlas)
|
|
local cap = CreateFrame("Frame", name, UIParent)
|
|
cap:SetWidth(END_CAP_WIDTH)
|
|
cap:SetHeight(END_CAP_HEIGHT)
|
|
-- Behind every element of the playing screen (levels 1 and up of the same strata): a cap
|
|
-- never covers anything.
|
|
cap:SetFrameStrata(holder:GetFrameStrata())
|
|
cap:SetFrameLevel(0)
|
|
|
|
local texture = cap:CreateTexture(nil, "OVERLAY")
|
|
texture:SetAllPoints(cap)
|
|
if not ForeverUI.SetAtlas(texture, atlas, true) then
|
|
cap:Hide()
|
|
end
|
|
cap.texture = texture
|
|
return cap
|
|
end
|
|
|
|
-- mainline/EditModePresetLayouts.lua: the left cap sits on the bar's LEFT edge, the right
|
|
-- cap on the bag bar's RIGHT edge, each 30 px inward (BottomBar.lua re-anchors it to the
|
|
-- bags). Camelot drops the cap 20 px below the bar, off screen for a bar 2 px above the
|
|
-- screen bottom, so the art bottom is aligned on the bar bottom, then 2 px lower.
|
|
local leftCap = createEndCap("ForeverUIActionBarLeftCap", "ui-hud-actionbar-gryphon-left")
|
|
local rightCap = createEndCap("ForeverUIActionBarRightCap", "ui-hud-actionbar-gryphon-right")
|
|
|
|
-- The bonus bar takes the same place. On a stance change 3.3.5 shows BonusActionBarFrame
|
|
-- over the main bar at its own position, so its buttons are anchored like the main ones and
|
|
-- follow the holder. Nothing is reparented: buttons follow the client bar's visibility.
|
|
-- 3.3.5 slides this bar in, but secure buttons cannot move every frame in combat, where
|
|
-- stances change: they are anchored ONCE to a track (our frame), and the track slides, out
|
|
-- of combat only (see below).
|
|
local PLACED_BARS = { "ActionButton", "BonusActionButton" }
|
|
|
|
-- The track covers the holder and shifts vertically while sliding. The duration comes from
|
|
-- the client when it declares it.
|
|
local track = CreateFrame("Frame", "ForeverUIBonusSlide", holder)
|
|
local SLIDE_DURATION = BONUSACTIONBAR_SLIDETIME or 0.2
|
|
local SLIDE_DISTANCE = BUTTON_SIZE
|
|
|
|
local function placeTrack(progress)
|
|
local offset = -SLIDE_DISTANCE * (1 - progress)
|
|
track:ClearAllPoints()
|
|
track:SetPoint("TOPLEFT", holder, "TOPLEFT", 0, offset)
|
|
track:SetPoint("BOTTOMRIGHT", holder, "BOTTOMRIGHT", 0, offset)
|
|
end
|
|
placeTrack(1)
|
|
|
|
-- The slide goes both ways. When hiding, the client sets mode = "hide" and keeps the bar
|
|
-- shown until the move ends, so the mode is read rather than the visibility alone. Without
|
|
-- that field the hide is instant: hidden buttons cannot be animated.
|
|
-- The bonus buttons are anchored to the track, which makes it protected (as the crafting page,
|
|
-- ProfessionsBook.lua): it never moves in combat. It waits at rest while the bar is hidden and
|
|
-- goes back to rest when combat starts, so a bar shown in combat appears in place, unslid.
|
|
track.progress = 1
|
|
track.target = 1
|
|
track:SetScript("OnUpdate", function(self, elapse)
|
|
local bar = BonusActionBarFrame
|
|
local visible = bar and bar:IsShown()
|
|
|
|
if InCombatLockdown() then
|
|
self.visible = visible
|
|
return
|
|
end
|
|
|
|
if visible and not self.visible then
|
|
self.progress, self.target = 0, 1 -- shown: slides up
|
|
elseif visible then
|
|
-- the client is hiding it, or shows it again before the end of its own slide
|
|
self.target = (bar.mode == "hide") and 0 or 1
|
|
else
|
|
if self.progress ~= 1 then
|
|
placeTrack(1) -- hidden: back at rest
|
|
end
|
|
self.progress, self.target = 1, 1
|
|
end
|
|
self.visible = visible
|
|
|
|
if self.progress ~= self.target then
|
|
local step = (elapse or 0) / SLIDE_DURATION
|
|
if self.target > self.progress then
|
|
self.progress = math.min(self.target, self.progress + step)
|
|
else
|
|
self.progress = math.max(self.target, self.progress - step)
|
|
end
|
|
placeTrack(self.progress)
|
|
end
|
|
end)
|
|
-- PLAYER_REGEN_DISABLED fires before the lockdown: last moment to put the track at rest
|
|
track:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
track:SetScript("OnEvent", function(self)
|
|
self.progress, self.target = 1, 1
|
|
placeTrack(1)
|
|
end)
|
|
ForeverUI.ActionBarSlide = track
|
|
|
|
local function layoutButtons()
|
|
if InCombatLockdown() then
|
|
return
|
|
end
|
|
|
|
for _, prefix in ipairs(PLACED_BARS) do
|
|
local anchor = (prefix == "BonusActionButton") and track or holder
|
|
for index = 1, BUTTON_COUNT do
|
|
local button = _G[prefix .. index]
|
|
if button then
|
|
button:ClearAllPoints()
|
|
button:SetPoint("LEFT", anchor, "LEFT", (index - 1) * BUTTON_PITCH, 0)
|
|
|
|
-- Dividers belong to the holder: one set, placed on the main bar.
|
|
if prefix == "ActionButton" and index > 1 and not dividers[index] then
|
|
local divider = ForeverUI.CreateDivider(holder, holder:GetFrameLevel() + 1)
|
|
divider:SetPoint("TOP", button, "TOP", 0, 0)
|
|
divider:SetPoint("BOTTOM", button, "BOTTOM", 0, 0)
|
|
divider:SetPoint("RIGHT", button, "LEFT", 5, 0)
|
|
dividers[index] = divider
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Hide the client's bar art. 3.3.5 MainMenuBar.xml has FOUR sets of pieces, and missing one
|
|
-- leaves the old dwarf bar behind ours: MainMenuBarTexture0..3 (bar body),
|
|
-- MainMenuXPBarTexture0..3 (XP bar frame), MainMenuMaxLevelBar0..3 (shown at 80), the
|
|
-- MainMenuBarLeftEndCap / RightEndCap end caps, and MainMenuBarExpText.
|
|
local OLD_ART = {
|
|
"MainMenuBarTexture%d", "MainMenuXPBarTexture%d", "MainMenuMaxLevelBar%d",
|
|
}
|
|
|
|
-- Bonus bar art: all the frame's own texture regions are hidden (buttons are child frames,
|
|
-- not regions). The frame also stops taking the mouse: BonusActionBarFrame is 505 x 43, HIGH
|
|
-- strata, toplevel, enableMouse; invisible, it would still swallow clicks on the micro-menu
|
|
-- below it. Its buttons keep their own mouse, being child frames.
|
|
local function clearBonusArt()
|
|
local bar = BonusActionBarFrame
|
|
if not bar or not bar.GetRegions then
|
|
return
|
|
end
|
|
|
|
if bar.EnableMouse then
|
|
bar:EnableMouse(false)
|
|
end
|
|
|
|
local regions = { bar:GetRegions() }
|
|
for _, region in ipairs(regions) do
|
|
if region and region.GetObjectType and region:GetObjectType() == "Texture" then
|
|
region:SetAlpha(0)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function hideOldBarArt()
|
|
clearBonusArt()
|
|
|
|
for _, model in ipairs(OLD_ART) do
|
|
for index = 0, 3 do
|
|
local texture = _G[string.format(model, index)]
|
|
if texture then
|
|
texture:SetAlpha(0)
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, name in ipairs({ "MainMenuBarLeftEndCap", "MainMenuBarRightEndCap", "MainMenuBarExpText" }) do
|
|
local region = _G[name]
|
|
if region then
|
|
region:SetAlpha(0)
|
|
end
|
|
end
|
|
|
|
if MainMenuBarPageNumber then
|
|
MainMenuBarPageNumber:SetAlpha(1)
|
|
MainMenuBarPageNumber:SetWidth(17)
|
|
MainMenuBarPageNumber:SetHeight(10)
|
|
MainMenuBarPageNumber:SetJustifyH("CENTER")
|
|
MainMenuBarPageNumber:ClearAllPoints()
|
|
MainMenuBarPageNumber:SetPoint("CENTER", page, "CENTER", -1, 0)
|
|
end
|
|
|
|
-- Page arrows: camelot has its own in the bar atlas.
|
|
local arrows = {
|
|
{ button = ActionBarUpButton, prefix = "ui-hud-actionbar-pageuparrow", y = 10 },
|
|
{ button = ActionBarDownButton, prefix = "ui-hud-actionbar-pagedownarrow", y = -10 },
|
|
}
|
|
for _, entry in ipairs(arrows) do
|
|
local button = entry.button
|
|
if button and not button.foreverSkinned then
|
|
ForeverUI.SetAtlas(button:GetNormalTexture(), entry.prefix .. "-up")
|
|
ForeverUI.SetAtlas(button:GetPushedTexture(), entry.prefix .. "-down")
|
|
ForeverUI.SetAtlas(button:GetHighlightTexture(), entry.prefix .. "-mouseover")
|
|
if button.GetDisabledTexture and button:GetDisabledTexture() then
|
|
ForeverUI.SetAtlas(button:GetDisabledTexture(), entry.prefix .. "-disabled")
|
|
end
|
|
button:SetWidth(17)
|
|
button:SetHeight(14)
|
|
-- 3.3.5 insets the 32 x 32 arrows by 6 and 7 px: kept on 17 x 14, they leave no
|
|
-- clickable area. Camelot's arrows have none.
|
|
button:SetHitRectInsets(0, 0, 0, 0)
|
|
button:ClearAllPoints()
|
|
button:SetPoint("CENTER", page, "CENTER", 0, entry.y)
|
|
button.foreverSkinned = true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function skinAll()
|
|
for _, prefix in ipairs(BARS) do
|
|
for index = 1, BUTTON_COUNT do
|
|
local button = _G[prefix .. index]
|
|
skinButton(button)
|
|
keepGrid(button)
|
|
end
|
|
end
|
|
hideOldBarArt()
|
|
end
|
|
|
|
-- The client rewrites the normal texture on every button update: silence it again after.
|
|
if hooksecurefunc then
|
|
hooksecurefunc("ActionButton_Update", function(self)
|
|
if self and self.foreverSkinned then
|
|
silenceNormalTexture(self)
|
|
keepGrid(self)
|
|
end
|
|
end)
|
|
|
|
hooksecurefunc("ActionButton_ShowGrid", function(self)
|
|
if self and self.foreverSkinned then
|
|
silenceNormalTexture(self)
|
|
end
|
|
end)
|
|
|
|
-- Here the client hides empty buttons.
|
|
hooksecurefunc("ActionButton_HideGrid", function(self)
|
|
if self and self.foreverSkinned then
|
|
silenceNormalTexture(self)
|
|
keepGrid(self)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local watcher = CreateFrame("Frame")
|
|
watcher:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
watcher:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
watcher:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
|
|
watcher:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
|
|
watcher:SetScript("OnEvent", function()
|
|
skinAll()
|
|
layoutButtons()
|
|
end)
|
|
|
|
skinAll()
|
|
layoutButtons()
|
|
|
|
ForeverUI.ActionBarDebug = function()
|
|
local button = _G["ActionButton1"]
|
|
if not button then
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff66ccffForeverUI|r : " .. L.ACTIONBAR_BUTTON1_MISSING)
|
|
return
|
|
end
|
|
|
|
local point, relativeTo, _, x, y = button:GetPoint(1)
|
|
local normal = button:GetNormalTexture()
|
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
|
"|cff66ccffForeverUI|r " .. L.ACTIONBAR_DEBUG,
|
|
button:GetWidth(), button:GetHeight(),
|
|
tostring(button:GetParent() and button:GetParent():GetName() or "?"),
|
|
tostring(point), tostring(relativeTo and relativeTo:GetName() or "?"), x or 0, y or 0,
|
|
tostring(button:IsShown()),
|
|
tostring(button.foreverFrame and button.foreverFrame:GetTexture() or NONE),
|
|
normal and normal:GetAlpha() or -1))
|
|
end
|
|
|
|
ForeverUI.ActionBarHolder = holder
|
|
ForeverUI.ActionBarBorder = border
|
|
ForeverUI.ActionBarEndCaps = { left = leftCap, right = rightCap, inset = END_CAP_INSET, drop = END_CAP_DROP }
|
|
-- camelot/EditModePresetLayoutConstants.lua: BOTTOMRIGHT on the micro-menu's BOTTOMLEFT at
|
|
-- (-4.5, -4); the micro-menu at BOTTOM (116.5, 6), 275 wide, puts the bar's right edge at
|
|
-- -25.5 from the screen center, 2 from the bottom. BottomBar.lua redoes this with the real
|
|
-- micro-menu width.
|
|
ForeverUI.Layout.Register(holder, "actionbar", L.ACTIONBAR_EDIT_LABEL, "BOTTOMRIGHT", "BOTTOM", -25.5, 2)
|
|
ForeverUI.Layout.Register(leftCap, "leftgryphon", L.ACTIONBAR_EDIT_LABEL_LEFT_GRYPHON, "BOTTOMRIGHT", "BOTTOM",
|
|
-25.5 - holder:GetWidth() + END_CAP_INSET, 2 + END_CAP_DROP)
|
|
ForeverUI.Layout.Register(rightCap, "rightgryphon", L.ACTIONBAR_EDIT_LABEL_RIGHT_GRYPHON, "BOTTOMLEFT", "BOTTOM",
|
|
0, 2 + END_CAP_DROP)
|