965e8589c9
I implemented a QuestHelper_GetTime function for the next time Blizzard decides to fiddle with the time functions. It returns debugprofilestop() / 1000, to exactly match the precision of GetTime(). I also re-removed references to Cartographer from the rollback.
566 lignes
15 Kio
Lua
566 lignes
15 Kio
Lua
|
|
local GetTime = QuestHelper_GetTime
|
|
|
|
QuestHelper_File["menu.lua"] = "4.0.1.$svnversion$"
|
|
QuestHelper_Loadtime["menu.lua"] = GetTime()
|
|
|
|
QuestHelper.active_menu = nil
|
|
|
|
local menuBorderInset = 4
|
|
local menuBackdrop = {
|
|
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
|
|
edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
|
|
edgeSize = 16,
|
|
tile = true,
|
|
tileSize = 16,
|
|
insets = { left = menuBorderInset, right = menuBorderInset, top = menuBorderInset, bottom = menuBorderInset }}
|
|
local menuBackdropColor = { 0, 0, 0, 0.65 }
|
|
local menuBackdropBorderColor = { 1, 1, 1, 0.7 }
|
|
|
|
local function Menu_AddItem(self, item)
|
|
item:ClearAllPoints()
|
|
item:SetParent(self)
|
|
item:SetPoint("TOPLEFT", self, "TOPLEFT")
|
|
item.parent = self
|
|
table.insert(self.items, item)
|
|
end
|
|
|
|
local function Menu_SetCloseFunction(self, ...)
|
|
self.func_arg = {...}
|
|
self.func = table.remove(self.func_arg, 1)
|
|
end
|
|
|
|
local function Menu_OnUpdate(self, elapsed)
|
|
if self.showing then
|
|
self.show_phase = self.show_phase + elapsed * 5.0
|
|
if self.show_phase > 1 then
|
|
self.show_phase = 1
|
|
QH_Hook(self, "OnUpdate", nil)
|
|
end
|
|
else
|
|
self.show_phase = self.show_phase - elapsed * 3.0
|
|
if self.show_phase < 0 then
|
|
self.show_phase = 0
|
|
QH_Hook(self, "OnUpdate", nil)
|
|
self:Hide()
|
|
if self.func then
|
|
self.func(unpack(self.func_arg))
|
|
end
|
|
if self.auto_release then
|
|
QuestHelper:ReleaseMenu(self)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
self:SetAlpha(self.show_phase)
|
|
end
|
|
|
|
local function Menu_DoShow(self)
|
|
self.showing = true
|
|
|
|
local w, h = 0, 0
|
|
|
|
for i, c in ipairs(self.items) do
|
|
local cw, ch = c:GetSize()
|
|
w = math.max(w, cw)
|
|
h = h + ch
|
|
end
|
|
|
|
local y = menuBorderInset
|
|
|
|
self:SetWidth(w+2*menuBorderInset)
|
|
self:SetHeight(h+2*menuBorderInset)
|
|
self:Show()
|
|
QH_Hook(self, "OnUpdate", self.OnUpdate)
|
|
|
|
for i, c in ipairs(self.items) do
|
|
local cw, ch = c:GetSize()
|
|
c:ClearAllPoints()
|
|
c:SetSize(w, ch)
|
|
c:SetPoint("TOPLEFT", self, "TOPLEFT", menuBorderInset, -y)
|
|
y = y + ch
|
|
end
|
|
|
|
if self.parent then
|
|
self.level = self.parent.parent.level + #self.parent.parent.items + 1
|
|
self:SetFrameStrata(self.parent:GetFrameStrata()) -- It should be sufficient to just set all to "TOOLTIP", but this seemed more versatile...
|
|
else
|
|
-- When there's no world map, or the world map is in a window, the menus
|
|
-- are un-parented. So make sure they're at a sufficient strata to be seen.
|
|
self:SetFrameStrata("TOOLTIP")
|
|
end
|
|
|
|
self:SetFrameLevel(self.level)
|
|
|
|
for i, n in ipairs(self.items) do
|
|
n.level = self.level+i
|
|
n:SetFrameLevel(n.level)
|
|
n:SetFrameStrata(self:GetFrameStrata())
|
|
n:DoShow()
|
|
end
|
|
end
|
|
|
|
local function Menu_DoHide(self)
|
|
self.showing = false
|
|
QH_Hook(self, "OnUpdate", self.OnUpdate)
|
|
|
|
if self.active_item then
|
|
self.active_item.highlighting = false
|
|
QH_Hook(self.active_item, "OnUpdate", self.active_item.OnUpdate)
|
|
end
|
|
|
|
for i, n in ipairs(self.items) do
|
|
n:DoHide()
|
|
end
|
|
end
|
|
|
|
local function Menu_ShowAtCursor(self, auto_release)
|
|
auto_release = (auto_release == nil) and true or auto_release
|
|
self.auto_release = auto_release
|
|
|
|
-- Add a 'Close Menu' item to the end of the menu, if it's not there already
|
|
if not self.close_item then
|
|
self.close_item = QuestHelper:CreateMenuItem(self, QHText("MENU_CLOSE"))
|
|
self.close_item:SetFunction( function() self:DoHide() end )
|
|
end
|
|
|
|
-- Set up the menu position, parentage, etc
|
|
local x, y = GetCursorPosition()
|
|
|
|
local parent = not UIParent:IsVisible() and QuestHelper.map_overlay_uncropped or UIParent
|
|
self:SetParent(parent)
|
|
self.level = (parent or UIParent):GetFrameLevel()+10
|
|
self:ClearAllPoints()
|
|
|
|
-- Need to call DoShow before setting the position so that the width and height will have been calculated.
|
|
self:DoShow()
|
|
|
|
-- I declare this math horrible and convoluted.
|
|
local scale = parent and parent:GetEffectiveScale() or 1
|
|
x, y = math.max(0, math.min(x-self:GetWidth()/2*scale, UIParent:GetRight()*UIParent:GetEffectiveScale()-self:GetWidth()*scale)) / scale,
|
|
math.min(UIParent:GetTop()*UIParent:GetEffectiveScale(), math.max(self:GetHeight(), y+5)) / scale
|
|
|
|
self:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
|
|
|
|
if QuestHelper.active_menu and QuestHelper.active_menu ~= self then
|
|
QuestHelper.active_menu:DoHide()
|
|
end
|
|
|
|
QuestHelper.active_menu = self
|
|
end
|
|
|
|
|
|
function QuestHelper:CreateMenu()
|
|
local menu = self:CreateFrame(UIParent)
|
|
menu:Hide()
|
|
|
|
menu.items = self:CreateTable()
|
|
menu:SetMovable(true)
|
|
menu:SetFrameStrata("TOOLTIP") -- A good default, but we usually re-parent the menus, which clobbers this.
|
|
menu:SetBackdrop(menuBackdrop)
|
|
menu:SetBackdropColor(unpack(menuBackdropColor))
|
|
menu:SetBackdropBorderColor(unpack(menuBackdropBorderColor))
|
|
|
|
menu.AddItem = Menu_AddItem
|
|
menu.SetCloseFunction = Menu_SetCloseFunction
|
|
menu.OnUpdate = Menu_OnUpdate
|
|
menu.DoShow = Menu_DoShow
|
|
menu.DoHide = Menu_DoHide
|
|
menu.ShowAtCursor = Menu_ShowAtCursor
|
|
|
|
menu.show_phase = 0
|
|
menu.showing = false
|
|
menu.level = 2
|
|
menu:SetFrameLevel(menu.level)
|
|
|
|
return menu
|
|
end
|
|
|
|
function QuestHelper:ReleaseMenu(menu)
|
|
while #menu.items > 0 do
|
|
local item = table.remove(menu.items)
|
|
self:ReleaseMenuItem(item)
|
|
end
|
|
|
|
if self.active_menu == menu then
|
|
self.active_menu = nil
|
|
end
|
|
|
|
self:ReleaseTable(menu.items)
|
|
self:ReleaseFrame(menu)
|
|
end
|
|
|
|
local function MenuItem_AddTexture(self, tex, before)
|
|
if before then
|
|
table.insert(self.lchildren, 1, tex)
|
|
else
|
|
table.insert(self.rchildren, tex)
|
|
end
|
|
end
|
|
|
|
local function MenuItem_DoShow(self)
|
|
self.showing = true
|
|
QH_Hook(self, "OnUpdate", self.OnUpdate)
|
|
self:Show()
|
|
end
|
|
|
|
local function MenuItem_DoHide(self)
|
|
if self.submenu then
|
|
self.submenu:DoHide()
|
|
end
|
|
|
|
self.showing = false
|
|
QH_Hook(self, "OnUpdate", self.OnUpdate)
|
|
end
|
|
|
|
local function MenuItem_OnUpdate(self, elapsed)
|
|
local done_update = true
|
|
|
|
if self.highlighting then
|
|
self.highlight_phase = self.highlight_phase + elapsed * 3.0
|
|
if self.highlight_phase > 1 then
|
|
self.highlight_phase = 1
|
|
else
|
|
done_update = false
|
|
end
|
|
else
|
|
self.highlight_phase = self.highlight_phase - elapsed
|
|
if self.highlight_phase < 0 then
|
|
self.highlight_phase = 0
|
|
else
|
|
done_update = false
|
|
end
|
|
end
|
|
|
|
if self.showing then
|
|
self.show_phase = self.show_phase + elapsed * 5.0
|
|
if self.show_phase > 1 then
|
|
self.show_phase = 1
|
|
else
|
|
done_update = false
|
|
end
|
|
else
|
|
self.show_phase = self.show_phase - elapsed * 5.0
|
|
if self.show_phase < 0 then
|
|
self.show_phase = 0
|
|
self.highlight_phase = 0
|
|
self:Hide()
|
|
done_update = true
|
|
else
|
|
done_update = false
|
|
end
|
|
end
|
|
|
|
self:Shade(self.show_phase, self.highlight_phase)
|
|
|
|
if done_update then
|
|
QH_Hook(self, "OnUpdate", nil)
|
|
end
|
|
end
|
|
|
|
local function MenuItem_Shade(self, s, h)
|
|
local theme = QuestHelper:GetColourTheme()
|
|
|
|
local ih = 1-h
|
|
|
|
self.text:SetTextColor(ih*theme.menu_text[1]+h*theme.menu_text_highlight[1],
|
|
ih*theme.menu_text[2]+h*theme.menu_text_highlight[2],
|
|
ih*theme.menu_text[3]+h*theme.menu_text_highlight[3], 1)
|
|
|
|
self.text:SetShadowColor(0, 0, 0, ih)
|
|
self.text:SetShadowOffset(1, -1)
|
|
|
|
self.background:SetVertexColor(ih*theme.menu[1]+h*theme.menu_highlight[1],
|
|
ih*theme.menu[2]+h*theme.menu_highlight[2],
|
|
ih*theme.menu[3]+h*theme.menu_highlight[3], h*0.3+0.4)
|
|
|
|
self:SetAlpha(s)
|
|
end
|
|
|
|
local function MenuItem_SetFunction(self, ...)
|
|
self.func_arg = {...}
|
|
self.func = table.remove(self.func_arg, 1)
|
|
end
|
|
|
|
local function MenuItem_SetSubmenu(self, menu)
|
|
--[[ assert(not self.submenu and menu) ]]
|
|
menu:ClearAllPoints()
|
|
menu:SetParent(self)
|
|
menu:SetPoint("TOPLEFT", self, "TOPLEFT")
|
|
menu.parent = self
|
|
self.submenu = menu
|
|
self:AddTexture(QuestHelper:CreateIconTexture(self, 9))
|
|
end
|
|
|
|
local function MenuItem_OnEnter(self)
|
|
self.highlighting = true
|
|
QH_Hook(self, "OnUpdate", self.OnUpdate)
|
|
|
|
if self.parent.active_item and self.parent.active_item ~= self then
|
|
self.parent.active_item.highlighting = false
|
|
QH_Hook(self.parent.active_item, "OnUpdate", self.parent.active_item.OnUpdate)
|
|
end
|
|
|
|
self.parent.active_item = self
|
|
|
|
if self.parent.submenu and self.parent.submenu ~= self.submenu then
|
|
self.parent.submenu:DoHide()
|
|
self.parent.submenu = nil
|
|
end
|
|
|
|
if self.submenu then
|
|
self.parent.submenu = self.submenu
|
|
self.submenu:ClearAllPoints()
|
|
|
|
local v, h1, h2 = "TOP", "LEFT", "RIGHT"
|
|
|
|
self.submenu:DoShow()
|
|
|
|
if self:GetRight()+self.submenu:GetWidth() > UIParent:GetRight()*UIParent:GetEffectiveScale() then
|
|
h1, h2 = h2, h1
|
|
end
|
|
|
|
if self:GetBottom()-self.submenu:GetHeight() < 0 then
|
|
v = "BOTTOM"
|
|
end
|
|
|
|
self.submenu:SetPoint(v..h1, self, v..h2)
|
|
self.submenu:DoShow()
|
|
end
|
|
end
|
|
|
|
local function MenuItem_GetSize(self)
|
|
self.text:SetParent(UIParent) -- Remove the text's parent so that it doesn't inherit scaling and mess up the dimensions.
|
|
self.text:ClearAllPoints()
|
|
self.text:SetWidth(0)
|
|
self.text:SetHeight(0)
|
|
|
|
self.text_w = self.text:GetStringWidth()+20
|
|
if self.text_w >= 320 then
|
|
-- Clamp width to 320, then ballance the two rows (using a binary search)
|
|
self.text:SetWidth(320)
|
|
self.text_h = self.text:GetHeight()+1
|
|
local mn, mx = 100, 321
|
|
while mn ~= mx do
|
|
local w = math.floor((mn+mx)*0.5)
|
|
self.text:SetWidth(w-1)
|
|
if self.text:GetHeight() <= self.text_h then
|
|
mx = w
|
|
else
|
|
mn = w+1
|
|
end
|
|
end
|
|
|
|
self.text_w = mn+1
|
|
self.text:SetWidth(self.text_w)
|
|
else
|
|
self.text:SetWidth(self.text_w)
|
|
self.text_h = self.text:GetHeight()+1
|
|
end
|
|
|
|
self.text:SetParent(self)
|
|
|
|
local w, h = self.text_w+4, self.text_h+4
|
|
|
|
for i, f in ipairs(self.lchildren) do
|
|
w = w + f:GetWidth() + 4
|
|
h = math.max(h, f:GetHeight() + 4)
|
|
end
|
|
|
|
for i, f in ipairs(self.rchildren) do
|
|
w = w + f:GetWidth() + 4
|
|
h = math.max(h, f:GetHeight() + 4)
|
|
end
|
|
|
|
self.needed_width = w
|
|
|
|
return w, h
|
|
end
|
|
|
|
local function MenuItem_SetSize(self, w, h)
|
|
self:SetWidth(w)
|
|
self:SetHeight(h)
|
|
|
|
local x = 0
|
|
|
|
for i, f in ipairs(self.lchildren) do
|
|
local cw, ch = f:GetWidth(), f:GetHeight()
|
|
|
|
f:ClearAllPoints()
|
|
f:SetPoint("TOPLEFT", self, "TOPLEFT", x+2, -(h-ch)*0.5)
|
|
x = x + cw + 4
|
|
end
|
|
|
|
local x1 = x
|
|
x = w
|
|
|
|
for i, f in ipairs(self.rchildren) do
|
|
local cw, ch = f:GetWidth(), f:GetHeight()
|
|
f:ClearAllPoints()
|
|
x = x - cw - 4
|
|
f:SetPoint("TOPLEFT", self, "TOPLEFT", x+2, -(h-ch)*0.5)
|
|
end
|
|
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("TOPLEFT", self, "TOPLEFT", x1+((x-x1)-self.text_w)*0.5, -(h-self.text_h)*0.5)
|
|
end
|
|
|
|
local function MenuItem_OnClick(self, btn)
|
|
if btn == "RightButton" then
|
|
local parent = self.parent
|
|
while parent.parent do
|
|
parent = parent.parent
|
|
end
|
|
parent:DoHide()
|
|
elseif btn == "LeftButton" and self.func then
|
|
self.func(unpack(self.func_arg))
|
|
local parent = self.parent
|
|
while parent.parent do
|
|
parent = parent.parent
|
|
end
|
|
parent:DoHide()
|
|
end
|
|
end
|
|
|
|
function QuestHelper:CreateMenuItem(menu, text)
|
|
item = self:CreateFrame(menu)
|
|
item:Hide()
|
|
|
|
item.lchildren = self:CreateTable()
|
|
item.rchildren = self:CreateTable()
|
|
item.text = self:CreateText(item, text)
|
|
item.background = self:CreateTexture(item, 1, 1, 1, 1)
|
|
item.background:SetDrawLayer("BACKGROUND")
|
|
item.background:SetAllPoints()
|
|
item.background:SetVertexColor(0, 0, 0, 0)
|
|
|
|
item.showing = false
|
|
item.highlighting = false
|
|
item.show_phase = 0
|
|
item.highlight_phase = 0
|
|
|
|
item.AddTexture = MenuItem_AddTexture
|
|
item.DoShow = MenuItem_DoShow
|
|
item.DoHide = MenuItem_DoHide
|
|
item.OnUpdate = MenuItem_OnUpdate
|
|
item.Shade = MenuItem_Shade
|
|
item.SetFunction = MenuItem_SetFunction
|
|
item.SetSubmenu = MenuItem_SetSubmenu
|
|
item.OnEnter = MenuItem_OnEnter
|
|
item.GetSize = MenuItem_GetSize
|
|
item.SetSize = MenuItem_SetSize
|
|
item.OnClick = MenuItem_OnClick
|
|
|
|
item:RegisterForClicks("LeftButtonUp", "RightButtonDown")
|
|
QH_Hook(item, "OnEnter", item.OnEnter)
|
|
QH_Hook(item, "OnClick", item.OnClick)
|
|
|
|
menu:AddItem(item)
|
|
|
|
return item
|
|
end
|
|
|
|
function QuestHelper:ReleaseMenuItem(item)
|
|
item:Hide()
|
|
|
|
while #item.lchildren > 0 do
|
|
local child = table.remove(item.lchildren)
|
|
self:ReleaseTexture(child)
|
|
end
|
|
|
|
while #item.rchildren > 0 do
|
|
local child = table.remove(item.rchildren)
|
|
self:ReleaseTexture(child)
|
|
end
|
|
|
|
if item.submenu then
|
|
self:ReleaseMenu(item.submenu)
|
|
item.submenu = nil
|
|
end
|
|
|
|
self:ReleaseTable(item.lchildren)
|
|
self:ReleaseTable(item.rchildren)
|
|
self:ReleaseText(item.text)
|
|
self:ReleaseTexture(item.background)
|
|
self:ReleaseFrame(item)
|
|
end
|
|
|
|
local function MenuTitle_OnDragStart(self)
|
|
local parent = self.parent
|
|
|
|
while parent.parent do
|
|
parent = parent.parent
|
|
end
|
|
|
|
parent:StartMoving()
|
|
end
|
|
|
|
local function MenuTitle_OnDragStop(self)
|
|
local parent = self.parent
|
|
|
|
while parent.parent do
|
|
parent = parent.parent
|
|
end
|
|
|
|
parent:StopMovingOrSizing()
|
|
end
|
|
|
|
local function MenuTitle_Shade(self, s, h)
|
|
local theme = QuestHelper:GetColourTheme()
|
|
|
|
local ih = 1-h
|
|
|
|
self.text:SetTextColor(ih*theme.menu_title_text[1]+h*theme.menu_title_text_highlight[1],
|
|
ih*theme.menu_title_text[2]+h*theme.menu_title_text_highlight[2],
|
|
ih*theme.menu_title_text[3]+h*theme.menu_title_text_highlight[3], 1)
|
|
|
|
self.background:SetVertexColor(ih*theme.menu_title[1]+h*theme.menu_title_highlight[1],
|
|
ih*theme.menu_title[2]+h*theme.menu_title_highlight[2],
|
|
ih*theme.menu_title[3]+h*theme.menu_title_highlight[3], h*0.3+0.4)
|
|
|
|
self.text:SetShadowColor(0, 0, 0, 1)
|
|
self.text:SetShadowOffset(1, -1)
|
|
|
|
self:SetAlpha(s)
|
|
end
|
|
|
|
local function MenuTitle_OnClick(self)
|
|
local parent = self.parent
|
|
|
|
while parent.parent do
|
|
parent = parent.parent
|
|
end
|
|
|
|
parent:DoHide()
|
|
end
|
|
|
|
function QuestHelper:CreateMenuTitle(menu, title)
|
|
local item = self:CreateMenuItem(menu, title)
|
|
|
|
local f1, f2 = self:CreateTexture(item, "Interface\\AddOns\\QuestHelper\\Art\\Fluff.tga"),
|
|
self:CreateTexture(item, "Interface\\AddOns\\QuestHelper\\Art\\Fluff.tga")
|
|
|
|
f1:SetTexCoord(0, 1, 0, .5)
|
|
f1:SetWidth(20)
|
|
f1:SetHeight(10)
|
|
f2:SetTexCoord(0, 1, .5, 1)
|
|
f2:SetWidth(20)
|
|
f2:SetHeight(10)
|
|
|
|
item:AddTexture(f1, true)
|
|
item:AddTexture(f2, false)
|
|
|
|
item.OnDragStart = MenuTitle_OnDragStart
|
|
item.OnDragStop = MenuTitle_OnDragStop
|
|
item.Shade = MenuTitle_Shade
|
|
item.OnClick = MenuTitle_OnClick
|
|
|
|
item:RegisterForClicks("RightButtonDown")
|
|
QH_Hook(item, "OnClick", item.OnClick)
|
|
QH_Hook(item, "OnDragStart", item.OnDragStart)
|
|
QH_Hook(item, "OnDragStop", item.OnDragStop)
|
|
item:RegisterForDrag("LeftButton")
|
|
|
|
item.text:SetFont(QuestHelper.font.fancy, 11)
|
|
end
|