---------------------------------------------------------------------------------------
-- Carbonite UI code
-- Copyright 2007-2012 Carbon Based Creations, LLC
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- Carbonite - Addon for World of Warcraft(tm)
-- Copyright 2007-2012 Carbon Based Creations, LLC
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
---------------------------------------------------------------------------------------
function Nx:UIInit()
local qc = {}
self.QualityColors = qc
for n = -1, 10 do -- Blizz max is currently 7
local r, g, b, hex = GetItemQualityColor (n)
qc[n] = hex
end
qc[1] = "|cffe7e7e7" -- Dim the white
Nx.Font:Init()
Nx.Skin:Init()
Nx.Menu:Init()
Nx.Window:Init()
Nx.Button:Init()
Nx.List:Init()
Nx.DropDown:Init()
Nx.ToolBar:Init()
-- Nx.GList:Init()
end
---------------------------
function Nx.prtStack (str)
local s = debugstack (3, 3, 0)
s = gsub (s, "Interface\\AddOns\\", "")
Nx.prt ("%s: %s", str, s)
end
---------------------------
-- Chat printing
function Nx:prtGetChatFrames()
local t = {}
for n = 1, 10 do
local cfrm = _G["ChatFrame" .. n]
if cfrm and cfrm["name"] then
tinsert (t, cfrm["name"])
-- Nx.prt ("cfrm %s %s", n, cfrm["name"] or "nil")
end
end
sort (t)
-- Nx.prtVar ("", t)
return t
end
function Nx:prtSetChatFrame()
Nx.prtChatFrm = DEFAULT_CHAT_FRAME
local name = Nx:GetGlobalOpts()["ChatMsgFrm"]
for n = 1, 10 do
local cfrm = _G["ChatFrame" .. n]
if cfrm then
if cfrm["name"] == name then
Nx.prtChatFrm = cfrm
end
end
end
end
function Nx.prt (msg, ...)
local f = Nx.prtChatFrm or DEFAULT_CHAT_FRAME
f:AddMessage (Nx.TXTBLUE..NXTITLE.." |cffffffff".. (format (msg, ...) or "nil"), 1, 1, 1)
end
function Nx.prtError (msg, ...)
UIErrorsFrame:AddMessage (format (msg, ...), 1, 1, 0)
end
-- Debug print
function Nx.prtD (msg)
if Nx.DebugOn then
Nx.prt (msg)
end
end
function Nx.prtCtrl (msg, ...)
--[[
if IsControlKeyDown() then
Nx.prt (msg, ...)
end
--]]
end
function Nx.prtTable (msg, s)
Nx.prt (msg.." Table: "..type (s))
if type (s) == "table" then
for k, v in pairs (s) do
if type (v) ~= "table" then
Nx.prtVar (" "..k, v)
else
Nx.prt (" "..k.." table")
end
end
end
end
function Nx.prtVar (msg, v)
local prt = Nx.prt
if v == nil then
prt (msg.." nil")
elseif type (v) == "boolean" then
prt (msg.." "..tostring (v))
elseif type (v) == "number" then
prt (format ("%s #%d (0x%x)", msg, v, v))
elseif type (v) == "string" then
local s = gsub (v, "%%", "%%%%")
prt (msg.. " '" .. s .."'")
elseif type (v) == "table" then
Nx.prtTable (msg, v)
else
prt (msg.." ? "..tostring (v))
end
end
function Nx.prtStrHex (msg, str)
local prt = Nx.prt
prt (msg..":")
for n = 1, #str, 4 do
local s = ""
for n2 = n, min (#str, n + 3) do
s = s .. format (" %x", strbyte (str, n2))
end
prt (s)
end
end
function Nx.prtFrame (msg, frm)
local prt = Nx.prt
local parent = frm:GetParent()
-- prt (msg.." Frame: %s", frm:GetName() or "nil")
prt (msg.." Frame: %s Shown%d Vis%d P>%s", frm:GetName() or "nil",
frm:IsShown() or 0, frm:IsVisible() or 0, parent and parent:GetName() or "nil")
prt (" EScale %f, Lvl %f", frm:GetEffectiveScale(), frm:GetFrameLevel())
prt (" LR %f, %f", frm:GetLeft() or -999, frm:GetRight() or -999)
prt (" BT %f, %f", frm:GetBottom() or -999, frm:GetTop() or -999)
local reg = { frm:GetRegions() }
for n, o in ipairs (reg) do
local str = ""
if o:IsObjectType ("Texture") then
str = o:GetTexture()
end
prt (" %d %s: %s", n, o:GetObjectType(), str)
end
end
function Nx.prtFrameChildren (msg, frm, lvl)
local prt = Nx.prt
lvl = lvl or 1
if msg then
prt (format ("FrameChildren (%s)", msg))
end
local pad = ""
for n = 1, lvl do
pad = pad.." "
end
local ch = { frm:GetChildren() }
for n = 1, #ch do
local c = ch[n]
if c:IsObjectType ("Frame") then
prt ("%s#%d %s ID%s (%s) show%d l%d x%d y%d", pad, n, c:GetName() or "nil",
c:GetID() or "nil", c:GetObjectType(),
c:IsShown() or 0, frm:GetFrameLevel(),
c:GetLeft() or -99999, c:GetTop() or -99999
)
Nx.prtFrameChildren (nil, c, lvl + 1)
end
end
end
----------------------------------
--------
-- Make the first letter a cap and the rest lower case
function Nx.Util_CapStr (str)
return strupper (strsub (str, 1, 1)) .. strlower (strsub (str, 2))
end
function Nx.Util_CleanName (name)
name = Nx.Util_CapStr (name)
name = gsub (name, "[~%^]", "")
return name
end
--------
-- Count table entries
function Nx.Util_tcount (t)
local n = 0
if t then
for k, v in pairs (t) do
n = n + 1
end
end
return n
end
function Nx.Util_tcountrecurse (t)
local n = 0
if t then
for k, v in pairs (t) do
n = n + 1
if type (v) == "table" then
n = n + Nx.Util_tcountrecurse (v)
end
end
end
return n
end
--------
-- Copy table entries recursively
function Nx.Util_TCopyRecurse (t)
local tc = {}
for k, v in pairs (t) do
if type (v) == "table" then
tc[k] = Nx.Util_TCopyRecurse (v)
else
tc[k] = v
end
end
return tc
end
--------
-- Find item index in table
-- (table, search item)
function Nx.Util_TFindItemI (t, item)
for i, v in ipairs (t) do
if v == item then
return i
end
end
end
--------
-- Move a indexed table index lower or higher
-- (table, index, not nil to move to lower index)
function Nx.Util_TMoveI (t, i, low)
if low then
if i > 1 then
t[i-1], t[i] = t[i], t[i-1]
return i - 1
end
else
if i < #t then
t[i+1], t[i] = t[i], t[i+1]
return i + 1
end
end
end
--------
-- Move a indexed table item lower or higher
-- (table, match item, not nil to move to lower index)
function Nx.Util_TMoveItem (t, item, low)
for i, v in ipairs (t) do
if v == item then
if low then
if i > 1 then
t[i-1], t[i] = t[i], t[i-1]
return i - 1
end
else
if i < #t then
t[i+1], t[i] = t[i], t[i+1]
return i + 1
end
end
return
end
end
end
--------
-- Serialize a table to a string
function Nx.Util_t2strRecurse (t)
local str = ""
if t then
str = "{"
for k, v in pairs (t) do
local kStr = k
if type (k) == "string" then
kStr = format ("\"%s\"", k)
end
if type (v) == "table" then
str = str .. format ("[%s]=%s,", kStr, Nx.Util_t2strRecurse (v))
elseif type (v) == "string" then
str = str .. format ("[%s]=\"%s\",", kStr, v)
else
str = str .. format ("[%s]=%s,", kStr, v)
end
end
str = str .. "}"
end
return str
end
--------
-- Convert hex color string to R G B floats (0-1)
function Nx.Util_c2rgb (colors)
-- Replace with table lookups?
local r = tonumber (strsub (colors, 1, 2), 16) / 255
local g = tonumber (strsub (colors, 3, 4), 16) / 255
local b = tonumber (strsub (colors, 5, 6), 16) / 255
return r, g, b
end
--------
-- Convert hex color string to R G B A floats (0-1)
function Nx.Util_c2rgba (colors)
local r = tonumber (strsub (colors, 1, 2), 16) / 255
local g = tonumber (strsub (colors, 3, 4), 16) / 255
local b = tonumber (strsub (colors, 5, 6), 16) / 255
local a = tonumber (strsub (colors, 7, 8), 16) / 255
return r, g, b, a
end
--------
-- Convert hex color number to R G B A floats (0-1)
-- (RRGGBBAA number)
function Nx.Util_num2rgba (colors)
local rshift = bit.rshift
local band = bit.band
local r = rshift (colors, 24) / 255
local g = band (rshift (colors, 16), 0xff) / 255
local b = band (rshift (colors, 8), 0xff) / 255
local a = band (colors, 0xff) / 255
return r, g, b, a
end
--------
-- Convert hex color number to alpha float (0-1)
-- (RRGGBBAA number)
function Nx.Util_num2a (colors)
return bit.band (colors, 0xff) / 255
end
--------
-- Convert hex color number to color string
-- (RGBA number)
function Nx.Util_num2colstr (colors)
local rshift = bit.rshift
local band = bit.band
return format ("|c%02x%02x%02x%02x", band (colors, 0xff),
rshift (colors, 24), band (rshift (colors, 16), 0xff), band (rshift (colors, 8), 0xff))
end
--------
-- Convert color table
function Nx.Util_coltrgb2colstr (colors)
local t = {}
for k, v in pairs (colors) do
t[k] = format ("|cff%02x%02x%02x", v.r * 255, v.g * 255, v.b * 255)
end
return t
end
--------
-- Step a value to the target value by a step
-- ret new value
function Nx.Util_StepValue (value, target, step)
if value < target then
value = value + step
if value > target then
value = target
end
elseif value > target then
value = value - step
if value < target then
value = target
end
end
return value
end
--------
-- Check if mouse is over a frame
-- (frame)
-- ret XY offsets from bottom left corner or nil if not over
function Nx.Util_IsMouseOver (frm)
local x, y = GetCursorPosition()
x = x / frm:GetEffectiveScale()
local left = frm:GetLeft()
local right = frm:GetRight()
if x >= left and x <= right then
y = y / frm:GetEffectiveScale()
local top = frm:GetTop()
local bottom = frm:GetBottom()
if y >= bottom and y <= top then
return x - left, y - bottom
end
end
end
--------
-- Get mouse position relative to a frame
-- (frame)
-- ret XY offsets from bottom left corner
function Nx.Util_GetMouseClampedXY (frm)
local x, y = GetCursorPosition()
x = x / frm:GetEffectiveScale()
local left = frm:GetLeft()
local right = frm:GetRight()
x = max (x, left)
x = min (x, right)
y = y / frm:GetEffectiveScale()
local top = frm:GetTop()
local bottom = frm:GetBottom()
y = max (y, bottom)
y = min (y, top)
return x - left, y - bottom
end
--------
-- Clamp frame to screen
-- (frame)
-- ret XY offsets from bottom left corner
function Nx.Util_SnapToScreen (frm)
local sw = GetScreenWidth()
local sh = GetScreenHeight()
local atPt, relTo, relPt, x, y = frm:GetPoint()
local sc = frm:GetScale()
local l = frm:GetLeft() * sc -- Scale does not matter for left or bottom
local r = frm:GetRight() * sc
local t = frm:GetTop() * sc
local b = frm:GetBottom() * sc
local dist = 4
if abs (l - 0) < dist then
x = x - l / sc
end
if abs (r - sw) < dist then
x = x - (r - sw) / sc
end
if MultiBarLeft:IsVisible() then
local ml = MultiBarLeft:GetLeft()
if abs (r - ml) < dist then
x = x - (r - ml) / sc
end
end
if MultiBarRight:IsVisible() then
local ml = MultiBarRight:GetLeft()
if abs (r - ml) < dist then
x = x - (r - ml) / sc
end
end
if abs (b - 0) < dist then
y = y - b / sc
end
if abs (t - sh) < dist then
y = y - (t - sh) / sc
end
frm:SetPoint (atPt, x, y)
return nil
end
--------
-- Recursively set child levels
function Nx.Util_SetChildLevels (frm, lvl)
if frm:GetNumChildren() > 0 then
local ch = { frm:GetChildren() }
for n, chf in pairs (ch) do
chf:SetFrameLevel (lvl)
if chf:GetNumChildren() > 0 then
Nx.Util_SetChildLevels (chf, lvl + 1)
end
end
end
end
--------
-- Get a string from a money value
function Nx.Util_GetMoneyStr (money)
if not money then
return "|cffff4040?"
end
if money == 0 then
return "0"
end
local pre = money > 0 and "" or "-"
money = abs (money)
local str = ""
local g = floor (money / 10000)
if g > 0 then
str = format ("|cffffff00%dg", g)
end
local s = mod (floor (money / 100), 100)
if s > 0 then
str = format ("%s |cffbfbfbf%ds", str, s)
end
local c = mod (money, 100)
if c > 0 then
str = format ("%s |cff7f7f00%dc", str, c)
end
return pre .. strtrim (str)
end
--------
-- Get a string from a seconds
function Nx.Util_GetTimeElapsedStr (seconds)
local secs = seconds
local mins = secs / 60 % 60
local hours = secs / 3600
if hours > 24 then
return format ("%.1f days", hours / 24)
elseif hours >= 1 then
return format ("%.1f hours", hours)
end
return format ("%d mins", mins)
end
--------
-- Get a string from a seconds in 00:00 minute:second format
function Nx.Util_GetTimeElapsedMinSecStr (seconds)
return format ("%d:%02d", seconds / 60 % 60, seconds % 60)
end
--------
-- Parse text and set for tooltip
function Nx:SetTooltipText (str)
if strbyte (str) == 33 then -- ! (item)
-- Nx.prt ("Item %s", str)
local link, s = strsplit ("^", str)
if not s or #s < 1 or IsAltKeyDown() then
str = strsub (link, 2)
Nx.Item:ShowTooltip (str, true)
return
end
str = s
elseif strbyte (str) == 64 then -- @ (quest)
str = "quest:" .. strsub (str, 2)
Nx.Item:ShowTooltip (str, true)
return
elseif strbyte (str) == 35 then -- # (enchant)
str = strsub (str, 2)
-- Nx.prt (str)
GameTooltip:SetHyperlink (str)
GameTooltip_ShowCompareItem()
return
end
local s1, s2 = strfind (str, "\n")
if s1 then
local t = { strsplit ("\n", str) }
GameTooltip:SetText (t[1], 1, 1, 1, 1, 1) -- Wrap text
tremove (t, 1)
for _, line in ipairs (t) do
local s1, s2 = strsplit ("\t", line)
if s2 then
GameTooltip:AddDoubleLine (s1, s2, 1, 1, 1, 1, 1, 1)
else
GameTooltip:AddLine (line, 1, 1, 1, 1) -- Wrap text
end
end
--[[
local s = strsub (str, 1, s1 - 1)
-- Nx.prt ("Tool %s", s)
GameTooltip:SetText (s, 1, 1, 1, 1, 1)
s = strsub (str, s2 + 1)
GameTooltip:AddLine (s, 1, 1, 1, 1, 1)
--]]
GameTooltip:Show()
else
GameTooltip:SetText (str, 1, 1, 1, 1, 1) -- Wrap text
end
end
--------
-- Play a sound file if sounds enabled
function Nx:PlaySoundFile (file)
if GetCVar ("Sound_EnableSFX") ~= "0" then
PlaySoundFile (file)
end
end
-------------------------------------------------------------------------------
-- Font stuff
function Nx.Font:Init()
self.Inited = true
-- Some code uses the "Nx" named font directly
self.Fonts = {
["FontS"] = { "NxFontS", "GameFontNormalSmall" },
["FontM"] = { "NxFontM", "GameFontNormal" },
["FontInfo"] = { "NxFontI", "GameFontNormal" },
["FontMap"] = { "NxFontMap", "GameFontNormalSmall" },
["FontMapLoc"] = { "NxFontMapLoc", "GameFontNormalSmall" },
["FontMenu"] = { "NxFontMenu", "GameFontNormalSmall" },
["FontQuest"] = { "NxFontQ", "GameFontNormal" },
["FontWatch"] = { "NxFontW", "GameFontNormal" },
["FontWarehouseI"] = { "NxFontWHI", "GameFontNormal" },
}
self.Faces = {
{ "Arial", "Fonts\\ARIALN.TTF", },
{ "Friz", "Fonts\\FRIZQT__.TTF", },
{ "Morpheus", "Fonts\\MORPHEUS.TTF", },
{ "Skurri", "Fonts\\SKURRI.TTF", }
}
-- Predefine so we dont get dups
self.AddonFonts = {
["Arial Narrow"] = true,
["Friz Quadrata TT"] = true,
["Morpheus"] = true,
["Skurri"] = true,
}
for name, v in pairs (self.Fonts) do
local font = CreateFont (v[1])
v.Font = font
font:SetFontObject(v[2])
end
self:Update()
end
function Nx.Font:AddonLoaded()
if not self.Inited then
return
end
local ace = _G["AceLibrary"]
if ace then
-- ace ("AceAddon-2.0")
local found
found = self:FontScan (ace, "LibSharedMedia-2.0")
found = found or self:FontScan (ace, "LibSharedMedia-3.0")
if found then
self:Update()
end
end
end
function Nx.Font:FontScan (ace, libName)
local sm
if ace["HasInstance"] (ace, libName) then
sm = ace (libName)
end
if sm then
local found
local fonts = sm["List"](sm, "font")
-- Nx.prtVar ("SM", fonts)
for k, name in ipairs (fonts) do
if not self.AddonFonts[name] then
found = true
-- Nx.prtVar ("Font", name)
-- Nx.prtVar ("Fetch", sm["Fetch"] (sm, "font", name))
self.AddonFonts[name] = sm["Fetch"] (sm, "font", name)
tinsert (self.Faces, { name, self.AddonFonts[name] })
end
end
return found
end
end
function Nx.Font:GetObj (name)
return self.Fonts[name].Font
end
function Nx.Font:GetH (name)
-- Nx.prt ("Font %s", name or "nil")
return self.Fonts[name].H
end
function Nx.Font:GetIndex (name)
for k, v in ipairs (self.Faces) do
if v[1] == name then
return k
end
end
return 1
end
function Nx.Font:GetName (index)
local t = self.Faces[index]
return t and t[1]
end
function Nx.Font:GetFile (name)
for k, v in ipairs (self.Faces) do
if v[1] == name then
return v[2]
end
end
return self.Faces[2][2] -- Default to friz
end
function Nx.Font:Update()
local opts = Nx:GetGlobalOpts()
for name, v in pairs (self.Fonts) do
local font = v.Font
local fname, size, flags = font:GetFont()
-- Nx.prt ("Font %s %s %s", fname, size, flags)
local file = self:GetFile (opts[name])
local size = opts[name .. "Size"]
font:SetFont (file, size, flags)
v.H = max (size + (opts[name .. "H"] or 0), 6)
end
Nx.List:NextUpdateFull()
Nx.Window:AdjustAll()
end
-------------------------------------------------------------------------------
-- Skin stuff
function Nx.Skin:Init()
Nx.Skins = {
["Blackout"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\Addons\\Carbonite\\Gfx\\Skin\\EdgeSquare",
["tile"] = true,
["tileSize"] = 8,
["edgeSize"] = 8,
["insets"] = { ["left"] = 0, ["right"] = 0, ["top"] = 0, ["bottom"] = 0 }
},
["BdCol"] = 0xff,
["BgCol"] = 0xff,
},
["BlackoutBlues"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\Tooltips\\UI-Tooltip-Border",
["tile"] = true,
["tileSize"] = 9,
["edgeSize"] = 9,
["insets"] = { ["left"] = 1, ["right"] = 1, ["top"] = 1, ["bottom"] = 1 }
},
["BdCol"] = 0xccccffff,
["BgCol"] = 0xff,
},
["DialogBlue"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\DialogFrame\\UI-DialogBox-Border",
["tile"] = true,
["tileSize"] = 16,
["edgeSize"] = 16,
["insets"] = { ["left"] = 2, ["right"] = 2, ["top"] = 2, ["bottom"] = 2 }
},
["BdCol"] = 0xccccffff,
["BgCol"] = 0x1f1f1fe0, -- { .125, .125, .125, .88 },
},
["DialogGold"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
["tile"] = true,
["tileSize"] = 16,
["edgeSize"] = 16,
["insets"] = { ["left"] = 2, ["right"] = 2, ["top"] = 2, ["bottom"] = 2 }
},
["BdCol"] = 0xffffffff,
["BgCol"] = 0x262600e0, -- { .15, .15, 0, .88 },
},
["SimpleBlue"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\Addons\\Carbonite\\Gfx\\Skin\\EdgeSquare",
-- ["edgeFile"] = "Interface\\PVPFrame\\UI-Character-PVP-Highlight",
["tile"] = true,
["tileSize"] = 8,
["edgeSize"] = 8,
["insets"] = { ["left"] = 0, ["right"] = 0, ["top"] = 0, ["bottom"] = 0 }
},
["BdCol"] = 0xb2b2ffcc,
["BgCol"] = 0x1f1f1fe0, -- { .125, .125, .125, .88 },
},
["Stone"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\Glues\\Common\\TextPanel-Border",
-- ["tile"] = true,
["tileSize"] = 256,
["edgeSize"] = 16,
["insets"] = { ["left"] = 3, ["right"] = 2, ["top"] = 2, ["bottom"] = 2 }
},
["BdCol"] = 0xffffffff,
["BgCol"] = 0x0f0f0ff0,
},
["ToolBlue"] = {
["Folder"] = "",
["WinBrH"] = "WinBrH",
["WinBrV"] = "WinBrV",
["TabOff"] = "TabOff",
["TabOn"] = "TabOn",
["Backdrop"] = {
["bgFile"] = "Interface\\Buttons\\White8x8",
["edgeFile"] = "Interface\\Tooltips\\UI-Tooltip-Border",
-- ["edgeFile"] = "Interface\\Minimap\\TooltipBackdrop",
["tile"] = true,
["tileSize"] = 9,
["edgeSize"] = 9,
["insets"] = { ["left"] = 1, ["right"] = 1, ["top"] = 1, ["bottom"] = 1 }
},
["BdCol"] = 0xccccffff,
["BgCol"] = 0x1f1f1fe0, -- { .125, .125, .125, .88 },
},
}
local opts = Nx:GetGlobalOpts()
self.GOpts = opts
self:Set (opts["SkinName"], true)
end
function Nx.Skin:Set (skinName, init)
self.Data = Nx.Skins[skinName or ""]
if not self.Data then
skinName = "ToolBlue"
self.Data = Nx.Skins[skinName]
end
self.GOpts["SkinName"] = skinName
local data = self.Data
self.Path = "Interface\\Addons\\Carbonite\\Gfx\\Skin\\" .. data["Folder"]
if not init then
self.GOpts["SkinWinBdColor"] = data["BdCol"]
self.GOpts["SkinWinFixedBgColor"] = 0x80808080
self.GOpts["SkinWinSizedBgColor"] = data["BgCol"]
end
self:Update()
end
function Nx.Skin:Update()
local opts = self.GOpts
self.BdCol = { Nx.Util_num2rgba (opts["SkinWinBdColor"]) }
self.BgCol = { Nx.Util_num2rgba (opts["SkinWinSizedBgColor"]) }
self.FixedBgCol = { Nx.Util_num2rgba (opts["SkinWinFixedBgColor"]) }
Nx.Window:ResetBackdrops()
Nx.Menu:ResetSkins()
end
function Nx.Skin:GetBackdrop()
return self.Data["Backdrop"]
end
function Nx.Skin:GetBorderCol()
return self.BdCol
end
function Nx.Skin:GetBGCol()
return self.BgCol
end
function Nx.Skin:GetFixedSizeBGCol()
return self.FixedBgCol
end
function Nx.Skin:GetTex (txName)
return self.Path .. txName
end
-------------------------------------------------------------------------------
-- Window - A frame with a title and borders that can be moved and resized
function Nx.Window:Init()
local wd = Nx:GetData ("Win")
if not wd.Version or wd.Version < Nx.VERSIONWin then
if wd.Version then
Nx.prt ("Reset old layout data")
end
wd.Version = Nx.VERSIONWin
for k, win in pairs (wd) do
if type (win) == "table" then
-- Nx.prt (" Reset %s", k)
wd[k] = nil
end
end
end
self.Wins = {} -- All created windows
self.BORDERW = 7
self.BORDERH = 7
self.Borders = {
"TOPLEFT", "TOPRIGHT", 1, self.BORDERH, "WinBrH",
"BOTTOMLEFT", "BOTTOMRIGHT", 1, self.BORDERH, "WinBrH",
"TOPLEFT", "BOTTOMLEFT", self.BORDERW, 1, "WinBrV",
"TOPRIGHT", "BOTTOMRIGHT", self.BORDERW, 1, "WinBrV",
}
self.SideNames = {
"LEFT", "RIGHT", "", "TOP", "TOPLEFT", "TOPRIGHT", "",
"BOTTOM", "BOTTOMLEFT", "BOTTOMRIGHT"
}
self.StrataNames = {
"LOW", "MEDIUM", "HIGH", "DIALOG",
["LOW"] = 1, ["MEDIUM"] = 2, ["HIGH"] = 3, ["DIALOG"] = 4,
}
local menu = Nx.Menu:Create (UIParent)
self.Menu = menu
self.MenuIHideInCombat = menu:AddItem (0, "Hide In Combat", self.Menu_OnHideInCombat, self)
self.MenuILock = menu:AddItem (0, "Lock", self.Menu_OnLock, self)
self.MenuIFadeIn = menu:AddItem (0, "Fade In", self.Menu_OnFadeIn, self)
self.MenuIFadeOut = menu:AddItem (0, "Fade Out", self.Menu_OnFadeOut, self)
self.MenuILayer = menu:AddItem (0, "Layer", self.Menu_OnLayer, self)
self.MenuIScale = menu:AddItem (0, "Scale", self.Menu_OnScale, self)
self.MenuITrans = menu:AddItem (0, "Transparency", self.Menu_OnTrans, self)
local function func (item)
self.MenuWin:ResetLayout()
end
menu:AddItem (0, "Reset Layout", func, self)
end
--------
function Nx.Window:Menu_OnHideInCombat (item)
self.MenuWin.SaveData["HideC"] = item:GetChecked()
end
function Nx.Window:Menu_OnLock (item)
self.MenuWin:Lock (item:GetChecked())
end
function Nx.Window:Menu_OnFadeIn (item)
local v = item:GetSlider()
local svdata = self.MenuWin.SaveData
svdata["FI"] = v
self.MenuWin.BackgndFadeIn = v
end
function Nx.Window:Menu_OnFadeOut (item)
local v = item:GetSlider()
local svdata = self.MenuWin.SaveData
svdata["FO"] = v
self.MenuWin.BackgndFadeOut = v
end
function Nx.Window:Menu_OnLayer (item)
local layer = item:GetSlider()
self.MenuWin:SetFrmStrata (layer)
end
function Nx.Window:Menu_OnScale (item)
local scale = item:GetSlider()
local svdata = self.MenuWin.SaveData
svdata[self.MenuWin.LayoutMode.."S"] = scale
local f = self.MenuWin.Frm
local s = f:GetScale()
local x = f:GetLeft() * s
local y = GetScreenHeight() - f:GetTop() * s
f:ClearAllPoints()
f:SetPoint ("TOPLEFT", x / scale, -y / scale)
f:SetScale (scale)
end
function Nx.Window:Menu_OnTrans (item)
local trans = item:GetSlider()
local svdata = self.MenuWin.SaveData
svdata[self.MenuWin.LayoutMode.."T"] = trans < 1 and trans or nil
local f = self.MenuWin.Frm
f:SetAlpha (trans)
end
--------
-- Reset layouts of all created windows
function Nx.Window:ResetLayouts()
for win, v in pairs (self.Wins) do
win:ResetLayout()
end
end
--------
-- Check if ok to copy all window saved data from one character to another
function Nx.Window:CopyLayoutsCheck (swd, dwd)
if dwd.Version and (not swd.Version or swd.Version < dwd.Version) then
Nx.prt ("Window version mismatch!")
return
end
self.SaveDisabled = true
return true
end
--------
-- Clear a window's saved data
function Nx.Window:ClrSaveData (name)
local wd = Nx:GetData ("Win")
wd[name] = nil
end
--------
-- Force adjust of all created windows
function Nx.Window:AdjustAll()
if self.Wins then
for win in pairs (self.Wins) do
win:Adjust()
end
end
end
--------
-- Update hide status for combat
function Nx.Window:UpdateCombat()
local combat = UnitAffectingCombat ("player")
if self.Wins then
for win in pairs (self.Wins) do
if win.SaveData["HideC"] then
-- Nx.prt ("UCombat %s", win.Name)
if combat then
win.Frm:Hide()
else
if not win.SaveData["Hide"] and not win.RaidHid then
win.Frm:Show()
end
end
end
end
end
end
--------
-- Position
function Nx.Window:ConsolePos (str)
local name, x, y = self:ParseConsole (str)
if not (x and y) then
Nx.prt ("XY missing (%s)", str)
return
end
local win = self:FindNoCase (name)
if win then
win:SetPos (x, -y)
return
end
Nx.prt ("Window not found (%s)", str)
end
--------
-- Show
function Nx.Window:ConsoleShow (str)
local name, mode = self:ParseConsole (str)
local win = self:FindNoCase (name)
if win then
if not mode then
win:Show (not win:IsShown())
elseif mode == 0 then
win:Show (false)
else
win:Show()
end
return
end
Nx.prt ("Window not found (%s)", str)
end
--------
-- Size
function Nx.Window:ConsoleSize (str)
local name, x, y = self:ParseConsole (str)
if not (x and y) then
Nx.prt ("XY missing (%s)", str)
return
end
local win = self:FindNoCase (name)
if win then
win:SetTotalSize (x, y)
return
end
Nx.prt ("Window not found (%s)", str)
end
--------
-- Parse
function Nx.Window:ParseConsole (str)
local str = gsub (strlower (str), ",", " ")
local name
local x, y
for s in gmatch (str, "%S+") do
local i = tonumber (s)
if i then
if x then
y = y or i
else
x = i
end
else
if name then
name = name .. " " .. s
else
name = s
end
end
end
local names = {
["map"] = "NxMap1",
-- ["watch"] = "NxQuestWatch",
}
return names[name] or name, x, y
end
--------
-- Find a window by name. Case insensitive
function Nx.Window:FindNoCase (name)
if self.Wins and name then
name = strlower (name)
for win in pairs (self.Wins) do
if strlower (win.Name) == name then
return win
end
end
end
end
--------
-- Find a window by name
function Nx.Window:Find (name)
-- Use a name table?
if self.Wins then
for win in pairs (self.Wins) do
if win.Name == name then
return win
end
end
end
end
--------
-- Set fade values used for next window create
function Nx.Window:SetCreateFade (fadein, fadeout)
self.CFadeIn = fadein
self.CFadeOut = fadeout
end
----------------------------------
-- Create a Window
-- ()
-- ret: window table
function Nx.Window:Create (name, minResizeW, minResizeH, secure, titleLines, borderType, hide, noButs)
local c2rgba = Nx.Util_c2rgba
local wd = Nx:GetData ("Win")
local svdata = name and wd[name]
if not svdata then -- No data for our name?
svdata = {} -- New
if name then
wd[name] = svdata
end
svdata["Hide"] = hide
svdata["FI"] = self.CFadeIn or 1
svdata["FO"] = self.CFadeOut or .75
end
-- Debug
-- svdata["FI"] = self.CFadeIn or 1
-- svdata["FO"] = self.CFadeOut or .75
-- New
local win = {}
setmetatable (win, self)
self.__index = self
win.SaveData = svdata
if name then
assert (self.Wins[win] == nil)
self.Wins[win] = true
win.Name = name
end
win.Secure = secure -- Have secure children. Don't move in combat
win.BorderW = self.BORDERW
win.BorderH = self.BORDERH
win.TitleLineH = 10
win.TitleLines = titleLines or 1
win.TitleH = win.TitleLines * win.TitleLineH + 2
win.TopH = win.TitleH + win.BorderH
win.ButW = 0 -- Top left corner button width
win.Sizeable = true
win.Border = true
if borderType == false then
win.Sizeable = false
win.Border = false
elseif borderType == 1 then
win.Sizeable = false
end
win.MovSizing = false
win.BackgndAlphaMin = .65
win.BackgndAlphaDiff = .35 -- Max - min
win.BackgndFade = .01 -- Current
win.BackgndFadeTarget = 0 -- Target value
win.BackgndFadeIn = svdata["FI"]
win.BackgndFadeOut = svdata["FO"]
win.ChildFrms = {}
-- Create window frame
-- local f = CreateFrame ("Frame", name, UIParent, "SecureStateHeaderTemplate")
local f = CreateFrame ("Frame", name, UIParent)
win.Frm = f
f.NxWin = win
-- f:SetAttribute ("showstates", "1")
f:SetMinResize (minResizeW or 100, minResizeH or 40)
f:SetWidth (10)
f:SetHeight (win.TitleH + 50)
f:SetPoint ("TOPLEFT", 100, -100)
f:SetMovable (true)
f:SetResizable (true)
f:SetScript ("OnEvent", self.OnEvent)
f:RegisterEvent ("PLAYER_LOGIN")
f:SetScript ("OnMouseDown", self.OnMouseDown)
f:SetScript ("OnMouseUp", self.OnMouseUp)
f:SetScript ("OnMouseWheel", self.OnMouseWheel)
f:SetScript ("OnUpdate", self.OnUpdate)
if not win.Border then
local t = f:CreateTexture()
t:SetTexture (c2rgba ("202020d8"))
t:SetAllPoints (f)
f.texture = t
end
-- Create title text
win.TitleFStr = {}
for n = 1, win.TitleLines do
local fstr = f:CreateFontString()
win.TitleFStr[n] = fstr
fstr:SetFontObject ("NxFontS")
fstr:SetJustifyH ("LEFT")
fstr:SetJustifyV ("MIDDLE")
fstr:SetHeight (win.TitleLineH)
end
win:SetTitleXOff (0)
-- Create GUI elements
if win.Border then
win:CreateBorders()
end
if not noButs then
local y = win.Sizeable and -win.BorderH or -3
-- local but = Nx.Button:Create (win.Frm, "Close", nil, nil, -win.BorderW, y, "TOPRIGHT", 12, 12, win.OnCloseBut, win, "SecureAnchorButtonTemplate")
local but = Nx.Button:Create (win.Frm, "Close", nil, nil, -win.BorderW, y, "TOPRIGHT", 12, 12, win.OnCloseBut, win)
win.ButClose = but
but.Frm:Hide()
--[[
local bf = but.Frm
bf:SetAttribute ("anchorchild", "$parent")
f:SetAttribute ("addchild", bf)
bf:SetAttribute ("addchild", bf)
--]]
win.ButW = 15
else
win.NoButs = true
end
-- Init layout (start false)
win.LayoutMode = false -- "" = normal, "Max", "Min", "User"
--
win:Lock (svdata["Lk"])
win:Show (not svdata["Hide"])
-- Reset creation stuff
self:SetCreateFade()
return win
end
--------
-- Create buttons
function Nx.Window:CreateButtons (closer, maxer, miner)
-- assert (not self.NoButs)
self.Closer = closer
self.Maxer = maxer
self.Miner = miner -- No buts can be set while min is on
local x = -self.BorderW
if self.Closer then
self.ButClose.Frm:Show()
end
x = x - 15 -- Always reserve space
if self.Sizeable and self.Maxer then
self.ButMaxer = Nx.Button:Create (self.Frm, "Max", nil, nil, x, -self.BorderH, "TOPRIGHT", 12, 12, self.OnMaxBut, self)
x = x - 15
end
if self.Miner then
-- self.ButMiner = Nx.Button:Create (self.Frm, "Max", nil, nil, x, -self.BorderH, "TOPRIGHT", 12, 12, self.OnMaxBut, self)
local y = self.Sizeable and -self.BorderH or -3
self.ButMiner = Nx.Button:Create (self.Frm, "Min", nil, nil, x, y, "TOPRIGHT", 12, 12, self.OnMinBut, self)
x = x - 15
end
self.ButW = -x - self.BorderW
self:Lock (self:IsLocked()) -- Force button update
end
--------
-- Create border frames
function Nx.Window:CreateBorders()
local c2rgba = Nx.Util_c2rgba
local Skin = Nx.Skin
--[[
local winBorders = self.Borders
for n = 1, 4 do
local index = n * 5 - 4
local f = CreateFrame ("Frame", nil, self.Frm)
self["BorderFrm"..n] = f
f:SetPoint (winBorders[index], 0, 0)
f:SetPoint (winBorders[index + 1], 0, 0)
f:SetWidth (winBorders[index + 2])
f:SetHeight (winBorders[index + 3])
local t = f:CreateTexture()
local txName = Skin:GetTex (winBorders[index + 4])
t:SetTexture (txName)
-- t:SetTexture ("Interface\\Buttons\\Bluegrad64")
-- t:SetTexture (c2rgba ("507050ff"))
t:SetAllPoints (f)
f.texture = t
f:Show()
end
--]]
local bk = Nx.Skin:GetBackdrop()
self.Frm:SetBackdrop (bk)
end
function Nx.Window:SetBordersFade (fade)
if self.Border then
--[[
local f
for n = 1, 4 do
f = self["BorderFrm"..n]
f:SetAlpha (fade * .7)
end
--]]
local col = Nx.Skin:GetBorderCol()
self.Frm:SetBackdropBorderColor (col[1], col[2], col[3], col[4] * fade)
end
end
--------
-- Set backdrops of all created windows
function Nx.Window:ResetBackdrops()
if self.Wins then
local bk = Nx.Skin:GetBackdrop()
for win, v in pairs (self.Wins) do
if win.Border then
win.Frm:SetBackdrop (bk)
win.BackgndFade = win.BackgndFadeTarget + .0001 -- Cause refresh
end
end
end
end
--------
-- Attach a child frame
function Nx.Window:Attach (childFrm, posX1, posX2, posY1, posY2, width, height)
-- Nx.prt ("AttachA #%s", #self.ChildFrms)
local f = self.Frm
if not posX1 then
posX1 = 0
posX2 = 1
posY1 = 0
posY2 = 1
end
local child
for i, ch in ipairs (self.ChildFrms) do
if ch.Frm == childFrm then
child = ch
break
end
end
if not child then
child = {}
tinsert (self.ChildFrms, child)
child.Frm = childFrm
childFrm:SetParent (f) -- Triggers frame updates which can call attach again!
end
child.PosX1 = posX1
child.PosX2 = posX2
child.PosY1 = posY1
child.PosY2 = posY2
if width then
child.ScaleW = width
child.ScaleH = height
end
-- Nx.prtVar ("Attach", child)
self:Adjust()
end
--------
-- Detach a child frame
function Nx.Window:Detach (childFrm)
Nx.prt ("Detach %s", #self.ChildFrms)
for i, ch in ipairs (self.ChildFrms) do
if ch.Frm == childFrm then
tremove (self.ChildFrms, i)
Nx.prt ("Detach found %s", #self.ChildFrms)
break
end
end
end
------
-- Adjust title width and child frames to fit our client area
function Nx.Window:Adjust (skipChildren)
local f = self.Frm
local w = f:GetWidth() - self.BorderW * 2
local h = f:GetHeight() - self.TitleH - self.BorderH * 2
for _, fstr in ipairs (self.TitleFStr) do
fstr:SetWidth (w - self.ButW)
end
if not skipChildren then
local x, y
for n = 1, #self.ChildFrms do
local child = self.ChildFrms[n]
local cf = child.Frm
x = child.PosX1
if x < 0 then
x = w + x -- Offset from right edge
elseif x <= 1 then
x = w * x -- Percent
end
local x2 = child.PosX2
if x2 < 0 then
x2 = w + x2 -- Offset from right edge
elseif x2 <= 1 then
x2 = w * x2 -- Percent
end
y = child.PosY1
if y <= -10000 then
y = y + 10000
elseif y < 0 then
y = h + y
elseif y <= 1 then
y = h * y
end
local y2 = child.PosY2
if y2 <= -10000 then
y2 = y2 + 10000
elseif y2 < 0 then
y2 = h + y2
elseif y2 <= 1 then
y2 = h * y2
end
cf:SetPoint ("TOPLEFT", f, "TOPLEFT", x + self.BorderW, -y - self.TopH)
local childW = x2 - x
local childH = y2 - y
if child.ScaleW then
local sw = childW / child.ScaleW
local sh = childH / child.ScaleH
local scale = max (min (sw, sh), .001)
cf:SetScale (scale)
cf:SetPoint ("TOPLEFT", f, "TOPLEFT", (self.BorderW + w * child.PosX1) / scale, (-self.TopH - h * child.PosY1) / scale)
else
local inst = cf.NxInst
if inst and inst.SetSize then
inst:SetSize (childW, childH)
else
cf:SetWidth (childW)
cf:SetHeight (childH)
end
end
if cf.NxSetSize then
cf:NxSetSize (childW, childH)
end
-- prtFrame ("Adj"..n, cf)
end
end
end
--------
-- Get a window attribute
function Nx.Window:GetAttribute (winName, atName)
local win = self:Find (winName)
if win then
if atName == "L" then -- Locked
return "B", win:IsLocked()
elseif atName == "H" then -- Hide
return "B", not win:IsShown()
end
end
end
--------
-- Set a window attribute
function Nx.Window:SetAttribute (winName, atName, value)
local win = self:Find (winName)
if win then
if atName == "L" then -- Locked
win:Lock (value)
elseif atName == "H" then -- Hide
win:Show (not value)
end
end
end
--------
-- Show or hide window
function Nx.Window:Show (show)
local svdata = self.SaveData
if show ~= false then
self.Frm:Show()
self.Frm:Raise()
self.Frm:Raise()
svdata["Hide"] = nil
else
if self.Frm:IsShown() then -- Check first to avoid taint errors
self.Frm:Hide()
end
svdata["Hide"] = true
end
end
--------
-- Check if shown
function Nx.Window:IsShown()
local svdata = self.SaveData
local vis = self.Frm:IsShown()
if vis == nil then
vis = false
end
return vis, not svdata["Hide"]
end
--------
-- Restore saved show or hide state
--[[
function Nx.Window:ShowRestore()
if self.SaveData["Hide"] then
self.Frm:Hide()
else
self.Frm:Show()
end
end
--]]
--------
-- Check if visible (parent must also be visible)
function Nx.Window:IsVisible()
return self.Frm:IsVisible()
end
--------
-- Check if hidden from combat
function Nx.Window:IsCombatHidden()
if self.SaveData["HideC"] then
return UnitAffectingCombat ("player")
end
end
--------
-- Lock or unlock window. Cannot move, resize or scale if locked
function Nx.Window:Lock (lock, fullLockout)
-- Nx.prtVar ("Win:Lock", lock)
self.Locked = lock
self.Frm:EnableMouse (not lock)
self.Frm:EnableMouseWheel (not lock)
local svdata = self.SaveData
svdata["Lk"] = lock or nil
self:SetBordersFade (lock and 0 or self.BackgndFade)
if self.ButClose then
if lock then
if self.Closer then
self.ButClose:SetType ("CloseLock")
else
self.ButClose.Frm:Show()
self.ButClose:SetType ("Lock")
end
else
if self.Closer then
self.ButClose:SetType ("Close")
else
self.ButClose.Frm:Hide()
end
end
self.ButClose:Update()
end
if fullLockout then
self.FullLock = lock
end
end
--------
-- Get lock status of window
function Nx.Window:IsLocked()
return self.Locked
end
--------
-- Set if mouse enabled for window
function Nx.Window:EnableMouse (on)
self.FullLock = not on
if self.MovSizing then
self.OnMouseUp (self.Frm, "")
end
if self.ButClose then
if on then
self.ButClose.Frm:Show()
else
self.ButClose.Frm:Hide()
end
end
if on then
self:Lock (self.Locked) -- Restore
else
self.Frm:EnableMouse (on)
self.Frm:EnableMouseWheel (on)
end
end
--------
-- Set if we have a window menu
function Nx.Window:EnableMenu (on)
self.MenuDisable = not on
end
--------
-- Get title text width
function Nx.Window:GetTitleTextWidth()
local w = 40
for n = 1, self.TitleLines do
local fstr = self.TitleFStr[n]
fstr:SetWidth (0)
w = max (self.TitleFStr[n]:GetStringWidth(), w)
end
return w
end
--------
-- Set title text line height
function Nx.Window:SetTitleLineH (height)
self.TitleLineH = height
self.TitleH = self.TitleLines * self.TitleLineH + 2
self.TopH = self.TitleH + self.BorderH
local fname = height <= 10 and "NxFontS" or "NxFontM"
for n = 1, self.TitleLines do
local fstr = self.TitleFStr[n]
fstr:SetFontObject (fname)
fstr:SetHeight (height)
end
end
--------
-- Set the title text x offset (also y. rename!)
function Nx.Window:SetTitleXOff (x, yo)
yo = yo or 0
for n = 1, self.TitleLines do
local fstr = self.TitleFStr[n]
local y = -self.BorderH - (n - 1) * self.TitleLineH - .4 -- Fudge it so it looks better
fstr:SetPoint ("TOPLEFT", self.BorderW + x, y - yo)
fstr:SetPoint ("TOPRIGHT", self.Frm, "TOPRIGHT", -self.BorderW, y)
end
end
--------
-- Set our title text
function Nx.Window:SetTitle (text, line)
line = line or 1
if self.TitleFStr[line] then
self.TitleFStr[line]:SetText (text)
end
end
--------
-- Set all title colors
function Nx.Window:SetTitleColors (r, g, b, a)
for n = 1, self.TitleLines do
local fstr = self.TitleFStr[n]
fstr:SetTextColor (r, g, b, a)
end
end
--------
-- Set our title text
function Nx.Window:SetTitleJustify (mode, line)
line = line or 1
self.TitleFStr[line]:SetJustifyH (mode)
end
--------
-- Get our background min max alpha
function Nx.Window:GetBGAlpha()
local m = self.BackgndAlphaMin
return m, m + self.BackgndAlphaDiff
end
--------
-- Set our background min max alpha
function Nx.Window:SetBGAlpha (min, max)
self.BackgndAlphaMin = min
self.BackgndAlphaDiff = max - min
self.BackgndFade = self.BackgndFadeTarget + .0001 -- Cause refresh
end
--------
-- Get our current fade
function Nx.Window:GetFade()
return self.BackgndFade
end
--------
-- Set our background color
function Nx.Window:SetBGColor (r, g, b, a)
if self.Frm.texture then
self.Frm.texture:SetTexture (r, g, b, a or 1)
end
end
--------
-- Get win width and height
function Nx.Window:GetClientOffset()
return self.BorderW, self.TitleH + self.BorderH
end
--------
-- Set if win is sizeable
function Nx.Window:SetSizeable (on)
self.Sizeable = on
end
--------
-- Get win width and height (client size)
function Nx.Window:GetSize()
return self.Frm:GetWidth() - self.BorderW * 2,
self.Frm:GetHeight() - self.TitleH + self.BorderH * 2
end
--------
-- Set win width and height (client size)
function Nx.Window:SetSize (width, height, skipChildren)
self.Frm:SetWidth (width + self.BorderW * 2)
self.Frm:SetHeight (height + self.TitleH + self.BorderH * 2)
self:Adjust (skipChildren)
end
--------
-- Set win width and height (win size)
function Nx.Window:SetTotalSize (width, height, skipChildren)
self.Frm:SetWidth (width)
self.Frm:SetHeight (height)
self:Adjust (skipChildren)
self:RecordLayoutData()
end
--------
-- Set win pos
function Nx.Window:SetPos (x, y)
local f = self.Frm
f:ClearAllPoints()
f:SetPoint ("TOPLEFT", x, y)
self:RecordLayoutData()
end
--------
-- Offset win pos
function Nx.Window:OffsetPos (xo, yo)
local f = self.Frm
local atPt, relTo, relPt, x, y = f:GetPoint()
f:SetPoint (atPt, relTo, relPt, x + xo, y + yo)
self:RecordLayoutData()
end
--------
-- Get size of borders
function Nx.Window:GetBorderSize()
return self.BorderW, self.BorderH
end
--------
-- Set size of borders
function Nx.Window:SetBorderSize (w, h)
self.BorderW = w
self.BorderH = h
self.TopH = self.TitleH + h
end
--------
-- Reset layout to default
-- self = Win
function Nx.Window:ResetLayout()
local data = self.SaveData
if data["_X"] then
for k, v in pairs (data) do
if k ~= "_X" then
if strsub (k, -1) == "X" then
local mode = strsub (k, 1, #k - 1)
-- Nx.prt ("Reset %s '%s' %f %f %f %f, %s, %s",
-- self.Name, mode, data["_X"], data["_Y"], data["_W"], data["_H"], data["_A"] or "nil", data["_S"] or "nil")
self:SetLayoutData (mode, data["_X"], data["_Y"], data["_W"], data["_H"], data["_L"], data["_A"], data["_S"])
self:SetMaxSizeDefault()
end
end
end
self.LayoutMode = false
self:SetLayoutMode()
-- self.Frm:SetScale (1)
end
self:Lock (false)
if self.Name == "NxMap1" or self.Name == "NxQuestWatch" then
self.Frm:Show()
data["Hide"] = nil
end
end
--------
-- Set max size to default
-- self = Win
function Nx.Window:SetMaxSizeDefault()
local sw = GetScreenWidth()
local sh = GetScreenHeight()
self:SetLayoutData ("Max", sw * .1, sh * .1, sw * .8, sh * .8, 2, "TOPLEFT")
end
--------
-- Get current layout mode name
-- self = Win
function Nx.Window:GetLayoutMode()
return self.LayoutMode
end
--------
-- Switch our layout mode if different and not maximized
-- self = Win
function Nx.Window:SwitchLayoutMode (mode)
mode = mode or ""
if self.LayoutMode ~= mode then
if self.LayoutMode == "Max" then
self.LayoutModeNormal = mode -- Remember for later
else
self:SetLayoutMode (mode)
end
end
end
--------
-- Set our layout mode and change to size/position
-- (mode or 1 if first time (login))
-- self = Win
function Nx.Window:SetLayoutMode (mode)
local data = self.SaveData
if mode == 1 then
mode = data["Mode"] -- nil, "Min", "Max"
if mode == "Min" then
self:SetLayoutMode()
self:SetMinimize (true)
return
end
end
if mode == "" then
mode = nil
end
data["Mode"] = mode
mode = mode or ""
-- Nx.prt ("SetLayoutMode '%s' to '%s'", self.LayoutMode or "nil", mode)
local f = self.Frm
local oldMode = self.LayoutMode
if oldMode then
self:RecordLayoutData()
end
if self.ButMiner then
if mode == "Min" then
-- mode = ""
data["Min"] = true
self.ButMiner:SetPressed (true)
else
data["Min"] = nil
self.ButMiner:SetPressed (false)
end
end
if self.ButMaxer then
if mode == "Max" then
self.ButMaxer:SetType ("MaxOn")
else
self.ButMaxer:SetType ("Max")
end
self.ButMaxer:Update()
end
self.LayoutMode = mode
local sw = GetScreenWidth()
local sh = GetScreenHeight()
if mode == "Max" and not data["MaxX"] then
self:SetMaxSizeDefault()
-- Nx.prt ("Setting win max")
end
local x = data[mode.."X"]
if not x then
if mode == "Min" then
self:SetLayoutData (mode, sw * .9, sh * .4, 1, 1) -- Hardcoded for quest watch
else
-- Nx.prt ("SetLayoutMode %s '%s' missing!", self.Name, mode)
self:SetLayoutData (mode, sw * .4, sh * .4, sw * .2, sh * .2)
end
else
local w = data[mode.."W"]
if w < 0 then
w = sw * -w
end
local h = data[mode.."H"]
if h < 0 then
h = sh * -h
end
if x >= 999999 then -- Center
x = (sw - w) * .5
elseif x >= 300000 then -- Offset + from screen center
local s = data[mode.."S"] or 1
x = (sw * .5 + (x - 300000)) / s
elseif x >= 200000 then -- Offset - from screen center
local s = data[mode.."S"] or 1
x = (sw * -.5 - (x - 200000)) / s
-- x = sw * .5 - (x - 200000) - w
elseif x > 100000 then -- Offset from screen right
x = sw - x + 100000 - self.BorderW
elseif x < 0 and x > -1 then -- % of width
x = sw * -x
end
local y = data[mode.."Y"]
if y >= 999999 then -- Center
y = (sh - h) * .5
elseif y < 0 and y > -1 then -- % of width
y = sh * -y
end
self:SetLayoutData (mode, x, y, w, h, false, data[mode.."A"], data[mode.."S"])
end
local aPt = data[mode.."A"] or "TOPLEFT"
if aPt == "TOPLEFT" then
if data[mode.."X"] > sw - 20 then
data[mode.."X"] = sw - 20
Nx.prt ("Fix %s x", self.Name)
end
end
if aPt == "TOPRIGHT" or aPt == "RIGHT" or aPt == "BOTTOMRIGHT" then
if data[mode.."X"] > 20 then
data[mode.."X"] = 20
Nx.prt ("Fix %s x", self.Name)
end
end
-- prt ("Y "..data[mode.."Y"])
-- prt ("%s H %f", self.Name, data[mode.."H"])
self:SetFrmStrata (data[mode.."L"])
f:ClearAllPoints()
f:SetPoint (aPt, data[mode.."X"], -data[mode.."Y"])
f:SetWidth (data[mode.."W"])
f:SetHeight (data[mode.."H"])
f:SetScale (data[mode.."S"] or 1)
f:SetAlpha (data[mode.."T"] or 1)
-- prt ("SetLayoutMode %s WH %f %f", data[mode.."A"] or "nil", data[mode.."W"], data[mode.."H"])
if mode == "Max" then
f:Raise()
f:Raise()
-- prt ("Y "..sh)
end
if mode == "Min" then
f:SetWidth (125)
f:SetHeight (28)
end
self:Adjust()
end
--------
-- Set strata
-- self = Win
function Nx.Window:SetFrmStrata (layer)
local svdata = self.SaveData
svdata[self.LayoutMode.."L"] = layer
self.Frm:SetFrameStrata (self.StrataNames[layer] or "MEDIUM")
end
--------
-- Init default data for a layout mode
-- self = Win
function Nx.Window:InitLayoutData (mode, x, y, w, h, layer, scale)
local data = self.SaveData
-- w and h are client size
if w > 0 then
w = w + self.BorderW
end
if h > 0 then
h = h + self.BorderH + self.TitleH
end
-- Nx.prt ("InitLayout %s '%s' %f %f %f %f, %s",
-- self.Name, mode or "_", x, y, w, h, scale or "")
local attach
if scale then
if x >= 300000 then -- Offset + from screen center
elseif x >= 200000 then -- Offset - from screen center
attach = "TOPRIGHT"
-- x = (x - 200000) * scale + 200000
end
end
if not mode then
mode = ""
self:SetLayoutData ("_", x, y, w, h, layer, attach, scale) -- Original position for reset
end
if not data[mode.."X"] then
self:SetLayoutData (mode, x, y, w, h, layer, attach, scale)
end
if self.LoginDone then -- Already logged in?
self:SetLayoutMode (1)
end
end
--------
-- Set data for a layout mode
-- self = Win
function Nx.Window:SetLayoutData (mode, x, y, w, h, layer, attachPt, scale)
-- Nx.prt ("SetLayoutData %s %s", self.Name, mode)
if not Nx.Window.SaveDisabled then
local data = self.SaveData
-- if self.Name == "NxInfo1" and mode == "_" then
-- Nx.prt ("SetLayout %s '%s' %f %f %f %f, %s",
-- self.Name, mode, x, y, w, h, attachPt or "")
-- end
if attachPt == "TOPLEFT" then
attachPt = nil -- Don't save default
end
data[mode.."A"] = attachPt
data[mode.."X"] = x
data[mode.."Y"] = y
data[mode.."W"] = w
data[mode.."H"] = h < 0 and h or max (h, 40)
if layer ~= false then
data[mode.."L"] = layer
end
data[mode.."S"] = scale ~= 1 and scale or nil
end
end
--------
-- Record current layout
-- self = Win
function Nx.Window:RecordLayoutData()
if self.LayoutMode then
local f = self.Frm
local atPt, relTo, relPt, x, y = f:GetPoint()
local scale = f:GetScale()
-- Nx.prt ("Record %s(%s): %s %s %s %s %s %d", self.Name, self.LayoutMode, atPt, (relTo and relTo:GetName()) or "nil", relPt, x, y, scale)
assert (atPt == relPt)
if x < 0 and x >= -1 then -- Neg small numbers used for % of screen W
x = 0
end
y = -y
if y < 0 and y >= -1 then -- Neg small numbers used for % of screen H
y = 0
end
local w = f:GetWidth()
local data = self.SaveData
if self.LayoutMode == "" then
if self.Name == "NxMap1" and data["MaxW"] and w >= data["MaxW"] then
-- Nx.prt ("Window %s Normal >= Max layout. Not saving", self.Name)
return
end
elseif self.LayoutMode == "Max" then
-- Nx.prt ("Window %s %s", w, data["W"])
if self.Name == "NxMap1" and data["W"] and w <= data["W"] then
-- Nx.prt ("Window %s Max <= Normal layout. Not saving", self.Name)
return
end
end
self:SetLayoutData (self.LayoutMode, x, y, f:GetWidth(), f:GetHeight(), false, atPt, scale)
end
end
--------
-- Set user of the window (for event handlers) and generic callback function
-- (user table, function)
function Nx.Window:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Register for event and set event handler
-- (event name, handler to call)
function Nx.Window:RegisterEvent (event, handler)
self.Frm:RegisterEvent (event)
if not self.Events then
self.Events = {}
end
self.Events[event] = handler
end
--------
-- Register for hide notify
function Nx.Window:RegisterHide()
local function func (self)
self.NxWin:Notify ("Hide")
end
self.Frm:SetScript ("OnHide", func)
end
--------
-- Notfiy user of the window
-- (name)
function Nx.Window:Notify (name, ...)
if self.UserFunc then
self.UserFunc (self.User, name, ...)
end
end
--------
-- Toggle window size
function Nx.Window:ToggleSize()
if self.Sizeable then
if self.LayoutMode ~= "Max" then
self.LayoutModeNormal = self.LayoutMode
self:SetLayoutMode ("Max")
self:Notify ("SizeMax")
else
self:SetLayoutMode (self.LayoutModeNormal)
self:Notify ("SizeNorm")
end
end
end
function Nx.Window:OnMinBut (but, id, click)
self:SetMinimize (but:GetPressed())
end
function Nx.Window:ToggleMinimize()
self:SetMinimize (not self.ButMiner:GetPressed())
end
--------
-- Toggle window minimize
function Nx.Window:SetMinimize (minOn)
if self.ButMiner then
if minOn then
self.LayoutModeNormal = self.LayoutMode
self:SetLayoutMode ("Min")
self:Notify ("SizeMin")
else
self:SetLayoutMode (self.LayoutModeNormal)
self:Notify ("SizeNorm")
end
end
end
function Nx.Window:IsSizeMax()
return self.Sizeable and self.LayoutMode == "Max"
end
function Nx.Window:IsSizeMin()
return self.ButMiner and self.ButMiner:GetPressed()
end
--------
-- Check for moving or sizing
function Nx.Window:IsMovingOrSizing()
return self.MovSizing
end
--------
-- Handle events
-- self is frame
function Nx.Window:OnEvent (event, ...)
--V4 this
local win = self.NxWin
-- Nx.prt ("Win Event %s %s", win.Name, event)
if event == "PLAYER_LOGIN" then
Nx.Window.LoginDone = true
-- Fix sizes after WOW sets them from layout cache
win.LayoutMode = false
win:SetLayoutMode (1)
end
if win.Events and win.Events[event] then
win.Events[event] (win.User, event, ...)
end
end
function Nx.Window:OnMouseDown (button)
-- Nx.prt ("WinMouseDown "..tostring (button))
-- Nx.prtFrame ("Win", this)
local this = self --V4
local win = this.NxWin
local x, y = GetCursorPosition()
x = x / this:GetEffectiveScale()
y = y / this:GetEffectiveScale()
ResetCursor()
if win.Secure and InCombatLockdown() then
return
end
if button == "LeftButton" then
-- Nx.prt (" MouseDown "..x.." "..y.." "..rgt.." "..bot)
local side = win:IsOnWinUI (x, y)
if win.Sizeable then
if side > 0 then
this:StartSizing (win.SideNames[side])
win.MovSizing = true
end
end
if not win.MovSizing and side == 0 then
this:StartMoving()
win.MovSizing = true
end
if win.MovSizing then
SetCursor ("INSPECT_CURSOR")
this:SetFrameStrata ("HIGH")
end
elseif button == "MiddleButton" then
win:ToggleSize()
elseif button == "RightButton" then
if IsShiftKeyDown() and IsControlKeyDown() then
win:ResetLayout()
else
win:OpenMenu (win.NoButs)
end
end
end
--------
-- Check if xy on window UI elements
-- (x, y)
function Nx.Window:IsOnWinUI (x, y)
local f = self.Frm
local top = f:GetTop()
local bot = f:GetBottom()
-- Bits set: 1=Left, 2=Right, 3=Top, 4=Bottom
if self.Sizeable then
local left = f:GetLeft()
local rgt = f:GetRight()
local bw = self.BorderW
local bh = self.BorderH
if x >= rgt - bw then
if y >= top - bh then
return 6 -- TOPRIGHT
elseif y <= bot + bh then
return 10 -- BOTTOMRIGHT
end
return 2 -- RIGHT
elseif x < left + bw then
if y >= top - bh then
return 5 -- TOPLEFT
elseif y <= bot + bh then
return 9 -- BOTTOMLEFT
end
return 1 -- LEFT
elseif y <= bot + bh then
return 8 -- BOTTOM
elseif y >= top - bh then
return 4 -- TOP
end
else
if y <= bot + self.BorderH then
return 0 -- Header
end
end
if y >= top - self.TopH then
return 0 -- Header
end
return -1 -- None
end
--------
-- Mouse up message. Enable mouse also calls!
-- self = frame
function Nx.Window:OnMouseUp (button)
-- prt ("WinMouseUp "..tostring (button))
local this = self --V4
local win = this.NxWin
if win.MovSizing then
this:StopMovingOrSizing()
win.MovSizing = false
if win.Secure and InCombatLockdown() then
win.DeferredMouseUp = true
else
win:SetFrmStrata (win.SaveData[win.LayoutMode.."L"])
this:Raise()
end
win:RecordLayoutData()
end
ResetCursor()
win:Adjust()
end
--------
function Nx.Window:OnMouseWheel (value)
if not IsShiftKeyDown() then
return
end
if not (IsControlKeyDown() or IsAltKeyDown()) then
return
end
local this = self --V4
local win = this.NxWin
local f = win.Frm
value = value > 0 and 1 or -1
local cx, cy = GetCursorPosition()
cx = cx / UIParent:GetEffectiveScale()
cy = GetScreenHeight() - cy / UIParent:GetEffectiveScale()
local s = f:GetScale()
local top = GetScreenHeight() - f:GetTop() * s
local left = f:GetLeft() * s
-- prtFrame ("Win", this)
-- prt ("XY "..left.." "..top)
-- prt ("CXY "..cx.." "..cy)
news = max (s + value * .025, .5)
if IsAltKeyDown() then
news = 1
end
local x = ((left - cx) * news / s + cx) / news
local y = ((top - cy) * news / s + cy) / news
f:SetScale (news)
f:ClearAllPoints()
f:SetPoint ("TOPLEFT", x, -y)
win:Adjust()
win:RecordLayoutData()
end
--------
-- Win update
-- self = frame
function Nx.Window:OnUpdate (elapsed)
local this = self --V4
local win = this.NxWin
local secureOk = not (win.Secure and InCombatLockdown())
if win.DeferredMouseUp and secureOk then
win.DeferredMouseUp = nil
win:SetFrmStrata (win.SaveData[win.LayoutMode.."L"])
this:Raise()
end
if win.MovSizing and secureOk then
if IsAltKeyDown() then
Nx.Util_SnapToScreen (this)
end
end
if win.CursorIsSet then
win.CursorIsSet = false
ResetCursor()
end
local x = not win.FullLock and Nx.Util_IsMouseOver (this)
if x then
if GetMouseFocus() == this then
local x, y = GetCursorPosition()
x = x / this:GetEffectiveScale()
y = y / this:GetEffectiveScale()
local side = win:IsOnWinUI (x, y)
if side == 0 then
SetCursor ("ITEM_CURSOR")
win.CursorIsSet = true
elseif side > 0 then
SetCursor ("INTERACT_CURSOR")
win.CursorIsSet = true
end
end
end
if (x or win.Sizing) and secureOk then
win:Adjust()
win.BackgndFadeTarget = win.BackgndFadeIn
else
win.BackgndFadeTarget = win.BackgndFadeOut
end
local fade = Nx.Util_StepValue (win.BackgndFade, win.BackgndFadeTarget, elapsed * 2)
if fade ~= win.BackgndFade then
if win.UserUpdateFade then
win.UserUpdateFade (win.User, fade)
end
win.BackgndFade = fade
local a = fade * win.BackgndAlphaDiff + win.BackgndAlphaMin
if this.texture then
this.texture:SetVertexColor (1, 1, 1, a)
else
local col = Nx.Skin:GetBGCol()
if not win.Sizeable and win.Border then
col = Nx.Skin:GetFixedSizeBGCol()
end
this:SetBackdropColor (col[1], col[2], col[3], col[4] * a)
end
if not win.Locked then
win:SetBordersFade (fade)
end
if win.ButClose then
win.ButClose.Frm:SetAlpha (fade * .9 + .1)
end
if win.ButMaxer then
win.ButMaxer.Frm:SetAlpha (fade * .9 + .1)
end
if win.ButMiner then
win.ButMiner.Frm:SetAlpha (fade * .9 + .1)
end
for n = 1, #win.ChildFrms do
local child = win.ChildFrms[n]
local cf = child.Frm
local inst = cf.NxInst
if inst and inst.SetFade then
inst:SetFade (fade)
else
if cf.texture then
cf.texture:SetVertexColor (1, 1, 1, fade * .7 + .3)
end
end
end
end
end
function Nx.Window:OnCloseBut (but, id, click)
if click == "LeftButton" and self.Closer then
self:Show (false)
self:RecordLayoutData()
GameTooltip:Hide()
self:Notify ("Close")
else
if self.Locked then
self:Lock (false)
else
self:OpenMenu()
end
end
end
function Nx.Window:OnMaxBut (but, id, click)
if click == "LeftButton" then
self:ToggleSize()
else
self:OpenMenu()
end
end
function Nx.Window:OpenMenu (noLock)
-- Nx.prtVar ("LockWinOM", self)
if not self.MenuDisable then
local w = Nx.Window
w.MenuWin = self
w.MenuIHideInCombat:SetChecked (self.SaveData["HideC"])
w.MenuILock:SetChecked (self.Locked)
w.MenuILock:Show (not noLock)
w.MenuIFadeIn:SetSlider (self.BackgndFadeIn, .25, 1)
w.MenuIFadeOut:SetSlider (self.BackgndFadeOut, 0, 1)
local svdata = self.SaveData
w.MenuILayer:SetSlider (svdata[self.LayoutMode.."L"] or 2, 1, 3, 1)
w.MenuIScale:SetSlider (svdata[self.LayoutMode.."S"] or 1, .5, 2)
w.MenuITrans:SetSlider (svdata[self.LayoutMode.."T"] or 1, .01, 1)
local m = Nx.Window.Menu
m:Open()
end
end
-------------------------------------------------------------------------------
-- Button - A frame that acts like a button
Nx.Button.TypeData = {
["AAItem"] = {
Up = "$INV_Misc_QuestionMark",
Dn = "$INV_Misc_QuestionMark",
SizeUp = 16,
SizeDn = 16,
},
["Chk"] = {
Skin = true,
Bool = true,
Up = "But",
Dn = "ButChk",
},
["Close"] = {
Skin = true,
Up = "ButClose",
Dn = "ButClose",
Tip = "Close/Menu"
},
["CloseLock"] = {
Skin = true,
Up = "ButLock",
Dn = "ButLock",
Tip = "Close/Unlock"
},
["Color"] = {
Tip = "Pick Color",
SizeUp = 22, -- Temp. Make opts version?
SizeDn = 22,
},
["Lock"] = {
Skin = true,
Up = "ButLock",
Dn = "ButLock",
Tip = "Unlock"
},
["Guide"] = {
Bool = true,
Up = "$INV_Misc_QuestionMark",
Dn = "$INV_Misc_QuestionMark",
SizeUp = 24,
SizeDn = 28,
AlphaUp = .7,
AlphaDn = 1,
},
["Max"] = {
Tip = "Maximize",
Skin = true,
Up = "ButMax",
Dn = "ButMax",
VRGBAUp = "ffffffff",
},
["MaxOn"] = {
Tip = "Restore",
Skin = true,
Up = "ButMax",
Dn = "ButMax",
VRGBAUp = "7f7fffff",
},
["Min"] = {
Tip = "Minimize",
Bool = true,
Skin = true,
Up = "ButWatchShow",
Dn = "ButWatchMini",
VRGBAUp = "ffffff7f",
VRGBADn = "9f9fffff",
},
["MapAutoScale"] = {
Tip = "Auto Scale",
Bool = true,
Skin = true,
Up = "But",
Dn = "ButChk",
},
["MapCombat"] = {
Up = "$Ability_DualWield",
SizeUp = 22,
SizeDn = 22,
},
["MapEvents"] = {
Up = "$INV_Misc_Note_03",
SizeUp = 22,
SizeDn = 22,
},
["MapFav"] = {
Up = "$INV_Torch_Lit",
SizeUp = 22,
SizeDn = 22,
},
["MapGuide"] = {
Up = "$INV_Misc_QuestionMark",
SizeUp = 22,
SizeDn = 22,
},
["MapWarehouse"] = {
Up = "$INV_Misc_EngGizmos_17",
SizeUp = 22,
SizeDn = 22,
},
["MapQGivers"] = {
Up = "$INV_Misc_Note_02",
SizeUp = 22,
SizeDn = 22,
},
["MapZIn"] = {
Up = "$Spell_ChargePositive",
SizeUp = 22,
SizeDn = 22,
},
["MapZOut"] = {
Up = "$Spell_ChargeNegative",
SizeUp = 22,
SizeDn = 22,
},
["Opts"] = {
Skin = true,
Bool = true,
Up = "But",
Dn = "ButChk",
SizeUp = 22,
SizeDn = 22,
},
["Scroll"] = {
Scroll = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\ScrollUp",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\ScrollUp",
SizeUp = 14,
SizeDn = 12,
},
["Tab"] = {
Bool = true,
Skin = true,
Up = "TabOff",
Dn = "TabOn",
},
["Toggle"] = {
Bool = true,
Skin = true,
Up = "But",
Dn = "ButChk",
SizeUp = 14,
SizeDn = 14,
},
["QuestHdr"] = {
Bool = true,
Skin = true,
Up = "RoundMinus",
Dn = "RoundPlus",
SizeUp = 11,
SizeDn = 11,
VRGBAUp = "8f8f8fff",
VRGBADn = "8f8f8fff",
},
["QuestWatching"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 11,
SizeDn = 11,
VRGBAUp = "ffff3f7f",
VRGBADn = "dfdf2fef",
},
["QuestWatchMenu"] = {
Tip = "Menu",
Skin = true,
Up = "ButWatchMenu",
Dn = "ButWatchMenu",
SizeUp = 14,
SizeDn = 14,
VRGBAUp = "ffffff7f",
VRGBADn = "ffffffbf",
},
["QuestWatchPri"] = {
Tip = "Priorities",
Skin = true,
Up = "ButWatchMenu",
Dn = "ButWatchMenu",
SizeUp = 14,
SizeDn = 14,
VRGBAUp = "ffff7f7f",
VRGBADn = "ffff7fbf",
},
["QuestWatchShowOnMap"] = {
Tip = "Show Quests On Map",
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 10,
SizeDn = 13,
VRGBAUp = "3fff3f8f",
VRGBADn = "3fff3fdf",
},
["QuestWatchATrack"] = {
Tip = "Auto Track",
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 10,
SizeDn = 13,
VRGBAUp = "ff00ff8f",
VRGBADn = "ff40ffdf",
},
["QuestWatchGivers"] = {
Tip = "Quest Givers",
States = 3,
Tx = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
{
Size = 10,
VRGBA = "ffcf3f8f",
},
{
Size = 13,
VRGBA = "ffcf3fdf",
},
{
Size = 13,
VRGBA = "8f8fffdf",
}
},
["QuestWatchParty"] = {
Tip = "Show Party Quests",
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 10,
SizeDn = 13,
VRGBAUp = "cfcfcf8f",
VRGBADn = "ffffffdf",
},
["QuestWatch"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 9,
AlphaUp = .3,
AlphaDn = .85,
},
["QuestWatchAC"] = { -- Auto complete
Up = "Interface\\Addons\\Carbonite\\Gfx\\Map\\IconQuestion",
SizeUp = 15,
VRGBAUp = "bfffbfff",
},
["QuestWatchTip"] = {
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 7,
SizeDn = 7,
VRGBAUp = "00000050",
VRGBADn = "00000080",
WatchTip = 1
},
["QuestWatchTipItem"] = {
SizeUp = 11,
SizeDn = 11,
VRGBAUp = "ffffffc0",
VRGBADn = "ffffffff",
WatchTip = 1
},
["QuestWatchTarget"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 12,
SizeDn = 12,
AlphaUp = .4,
AlphaDn = 1,
},
["QuestWatchErr"] = {
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 12,
VRGBAUp = "ff80206f",
VRGBADn = "ff8020ef",
WatchError = 1
},
["QuestWatchTrial"] = {
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 12,
VRGBAUp = "ffff40af",
VRGBADn = "ffff40ff",
},
["QuestListWatch"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 9,
VRGBAUp = "ffffff4f",
VRGBADn = "ffffffd8",
},
--[[
["QuestWatchR"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 9,
VRGBAUp = "ff3f3f4f",
VRGBADn = "ff3f3fd8",
},
["QuestWatchG"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 9,
VRGBAUp = "3fff3f4f",
VRGBADn = "3fff3fd8",
},
["QuestWatchB"] = {
Bool = true,
Up = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
Dn = "Interface\\Addons\\Carbonite\\Gfx\\Buttons\\DotOn",
SizeUp = 9,
SizeDn = 9,
VRGBAUp = "8f8fff4f",
VRGBADn = "8f8fffe0",
},
--]]
["Txt"] = {
RGBUp = "604040",
RGBDn = "503030",
},
["Txt64"] = {
Skin = true,
Up = "ButEmpty64",
Dn = "ButEmpty64",
RGBUp = "604040",
RGBDn = "503030",
},
["Txt64B"] = {
Bool = true,
Skin = true,
Up = "ButEmpty64",
Dn = "ButEmpty64",
VRGBAUp = "ffffffff",
VRGBADn = "ff5f5fff",
},
["Warehouse"] = {
Bool = true,
Up = "$INV_Misc_QuestionMark",
Dn = "$INV_Misc_QuestionMark",
SizeUp = 18,
SizeDn = 11,
},
["WarehouseItem"] = {
Up = "$INV_Misc_QuestionMark",
Dn = "$INV_Misc_QuestionMark",
SizeUp = 16,
SizeDn = 16,
},
["WarehouseProf"] = {
Up = "Interface\\TradeSkillFrame\\UI-TradeSkill-LinkButton",
Dn = "Interface\\TradeSkillFrame\\UI-TradeSkill-LinkButton",
SizeUp = 16,
SizeDn = 14,
UpUV = { 0, 1, 0, .5 },
},
}
--------
--
function Nx.Button:Init()
local f = CreateFrame ("Frame", nil, UIParent)
self.OverFrm = f
f:SetFrameStrata ("MEDIUM")
f:Hide()
local t = f:CreateTexture()
t:SetTexture (Nx.Util_c2rgba ("101040ff"))
t:SetAllPoints (f)
t:SetBlendMode ("ADD")
f.texture = t
end
--------
-- Create a Button
-- ()
-- ret: button table
function Nx.Button:Create (parentFrm, typ, text, tip, bx, by, side, width, height, func, user, template)
parentFrm = parentFrm or UIParent
local but = {} -- New
setmetatable (but, self)
self.__index = self
but:SetUser (user, func)
but.Type = self.TypeData[typ]
assert (not typ or but.Type)
-- Create frame
local fType = template and "Button" or "Frame"
local fname = text and ("NxBut" .. text)
local f = CreateFrame (fType, fname, parentFrm, template)
but.Frm = f
f.NxBut = but
but.Tip = tip
f.NxTip = tip or (typ and self.TypeData[typ].Tip)
side = side or "TOPLEFT"
f:SetPoint (side, bx, by)
f:SetWidth (width)
f:SetHeight (height)
-- f:SetFrameStrata ("MEDIUM")
f:SetScript ("OnMouseDown", self.OnMouseDown)
f:SetScript ("OnMouseUp", self.OnMouseUp)
f:SetScript ("OnEnter", self.OnEnter)
f:SetScript ("OnLeave", self.OnLeave)
f:EnableMouse (true)
f:SetScript ("OnUpdate", self.OnUpdate)
local t = f:CreateTexture()
f.texture = t
t:SetAllPoints (f)
f:Show()
-- Create text
if text then
local fstr = f:CreateFontString()
but.FStr = fstr
fstr:SetFontObject ("NxFontS")
fstr:SetJustifyH ("CENTER")
fstr:SetHeight (height)
but:SetText (text, 0, 0)
fstr:Show()
end
--
but:Update()
--
if template then -- Social frame template?
-- Nx.prt ("But %s", template)
-- Nx.prtFrame ("But", f)
local reg = { f:GetRegions() }
for n, o in ipairs (reg) do
if o:IsObjectType ("Texture") and o ~= f.texture then
o:Hide() -- Hide
end
end
end
return but
end
--------
-- Set handler to notify user
function Nx.Button:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Get type
function Nx.Button:GetType()
return self.Type
end
--------
-- Set type
-- (Type string or nil)
function Nx.Button:SetType (typ)
self.Frm.NxTip = self.Tip or (typ and self.TypeData[typ].Tip)
self.Type = self.TypeData[typ]
end
--------
-- Set Id
function Nx.Button:SetId (id)
self.Id = id
end
--------
-- Get pressed state
function Nx.Button:GetPressed()
return self.Pressed
end
--------
-- Set pressed state
function Nx.Button:SetPressed (down)
self.Pressed = down
self:Update()
end
--------
-- Get state
function Nx.Button:GetState()
return self.State
end
--------
-- Set state
function Nx.Button:SetState (state)
self.State = state
self:Update()
end
--------
-- Set button text and text position
function Nx.Button:SetText (text, x, y)
local fstr = self.FStr
if strbyte (text) ~= 124 then -- |
text = "|cffffbfaf" .. text
end
fstr:SetText (text)
if x then
fstr:SetPoint ("CENTER", x, y + 1)
end
end
--------
-- Set button texture
function Nx.Button:SetAlpha (a)
self.Frm:SetAlpha (a)
end
--------
-- Set button texture
function Nx.Button:SetTexture (tex)
self.Tx = tex
end
--------
-- Set button position
function Nx.Button:SetPos (side, x, y)
self.Frm:SetPoint (side, x, y)
end
--------
-- Set button size
function Nx.Button:SetSize (w, h)
self.Frm:SetWidth (w)
self.Frm:SetHeight (h)
end
--------
function Nx.Button:OnMouseDown (button)
-- prt ("ButMouseDown "..tostring (button))
local this = self --V4
local but = this.NxBut
if button == "LeftButton" or button == "MiddleButton" then
if but.Type.Bool then
but.Pressed = not but.Pressed
-- if IsShiftKeyDown() then -- Force on. Keep?
-- but.Pressed = true
-- end
if but.UserFunc then
but.UserFunc (but.User, but, but.Id, button)
end
elseif but.Type.States then
but.State = but.State % but.Type.States + 1
if but.UserFunc then
but.UserFunc (but.User, but, but.Id, button)
end
else
but.Pressed = true
end
end
if but.Type.Scroll then
local x, y = GetCursorPosition()
but.ScrollingX = x / this:GetEffectiveScale()
but.ScrollingY = y / this:GetEffectiveScale()
but.Scrolling = true
return
elseif button == "RightButton" then
if but.UserFunc then
but.UserFunc (but.User, but, but.Id, button)
end
end
but:Update()
end
--------
function Nx.Button:OnMouseUp (button)
-- Nx.prt ("ButMouseUp "..tostring (button))
local this = self --V4
local but = this.NxBut
if button == "LeftButton" then
if not (but.Type.Bool or but.Type.States or but.Type.Scroll) then
but.Pressed = false
if Nx.Util_IsMouseOver (but.Frm) then
if but.UserFunc then
but.UserFunc (but.User, but, but.Id, button)
end
end
elseif but.Type.Scroll then
but.Pressed = false
end
end
but.Scrolling = false
but:Update()
end
--------
-- Handle mouse on button
function Nx.Button:OnEnter (motion)
local this = self --V4
local but = this.NxBut
but.Over = true
but:Update()
-- Nx.prt ("Enter %s", this.NxTip or "nil")
local owner = this.NXTipFrm or this
if GameTooltip:IsOwned (owner) then
return
end
local tip = this.NxTip
if tip then
Nx.TooltipOwner = owner
if this.NXTipFrm then
GameTooltip:SetOwner (owner, "ANCHOR_TOPLEFT", 0, 0)
else
GameTooltip:SetOwner (owner, "ANCHOR_LEFT", 0, 5)
end
Nx:SetTooltipText (tip)
end
end
--------
-- Handle mouse leaving icon
function Nx.Button:OnLeave (motion)
local this = self --V4
local but = this.NxBut
but.Over = nil
but:Update()
if not this:IsVisible() then
return
end
local owner = this.NXTipFrm or this
if GameTooltip:IsOwned (owner) then
GameTooltip:Hide()
end
end
--------
function Nx.Button:OnUpdate (elapsed)
local this = self --V4
local but = this.NxBut
if but.Scrolling then
local cx, cy = GetCursorPosition()
cx = cx / this:GetEffectiveScale()
cy = cy / this:GetEffectiveScale()
local x = cx - but.ScrollingX
local y = but.ScrollingY - cy
if x ~= 0 or y ~= 0 then
but.ScrollingX = cx
but.ScrollingY = cy
if IsShiftKeyDown() then
x = x * .1
y = y * .1
end
if but.UserFunc then
but.UserFunc (but.User, but, but.Id, "scroll", x, y)
end
end
end
end
--------
function Nx.Button:Update()
-- Nx.prt ("But Update: %s", debugstack (2, 3, 0))
local typ = self.Type
if not typ then
return
end
local Skin = Nx.Skin
local f = self.Frm
local tx = f.texture
if self.State then
local stateT = typ[self.State] or typ[1]
local txName = self.Tx or stateT.Tx or typ.Tx
if typ.Skin then
txName = Skin:GetTex (txName)
else
if txName then
if type (txName) == "string" then
txName = gsub (txName, "%$", "Interface\\Icons\\")
else
tx:SetTexture (Nx.Util_num2rgba (txName))
txName = nil
end
end
end
if txName then
tx:SetTexture (txName)
else
local rgb = stateT.RGB
if rgb then
tx:SetTexture (Nx.Util_c2rgb (rgb))
end
end
if stateT.Alpha then
tx:SetVertexColor (1, 1, 1, stateT.Alpha)
elseif stateT.VRGBA then
tx:SetVertexColor (Nx.Util_c2rgba (stateT.VRGBA))
end
local sz = stateT.Size
if sz then
f:SetWidth (sz)
f:SetHeight (sz)
end
else
if self.Pressed then
local txName = self.Tx or typ.Dn
if typ.Skin then
txName = Skin:GetTex (txName)
else
if txName then
if type (txName) == "string" then
txName = gsub (txName, "%$", "Interface\\Icons\\")
else
tx:SetTexture (Nx.Util_num2rgba (txName))
txName = nil
end
end
end
if txName then
tx:SetTexture (txName)
else
local rgb = typ.RGBDn
if rgb then
tx:SetTexture (Nx.Util_c2rgb (rgb))
end
end
if typ.AlphaDn then
tx:SetVertexColor (1, 1, 1, typ.AlphaDn)
elseif typ.VRGBADn then
tx:SetVertexColor (Nx.Util_c2rgba (typ.VRGBADn))
end
local sz = typ.SizeDn
if sz then
f:SetWidth (sz)
f:SetHeight (sz)
end
else
local txName = self.Tx or typ.Up
if typ.Skin then
txName = Skin:GetTex (txName)
else
if txName then
if type (txName) == "string" then
txName = gsub (txName, "%$", "Interface\\Icons\\")
else
-- Nx.prt ("But %s", txName)
tx:SetTexture (Nx.Util_num2rgba (txName))
txName = nil
end
end
end
if txName then
tx:SetTexture (txName)
if typ.UpUV then
local uv = typ.UpUV
tx:SetTexCoord (uv[1], uv[2], uv[3], uv[4])
end
else
local rgb = typ.RGBUp
if rgb then
tx:SetTexture (Nx.Util_c2rgb (rgb))
end
end
if typ.AlphaUp then
tx:SetVertexColor (1, 1, 1, typ.AlphaUp)
elseif typ.VRGBAUp then
tx:SetVertexColor (Nx.Util_c2rgba (typ.VRGBAUp))
end
local sz = typ.SizeUp
if sz then
f:SetWidth (sz)
f:SetHeight (sz)
end
end
end
local of = Nx.Button.OverFrm
if self.Over then
-- tx:SetBlendMode ("ADD")
-- local al = typ.AlphaOv
-- if al then
-- tx:SetVertexColor (1, 1, 1, al)
-- end
of:SetPoint ("TOPLEFT", f, -1, 1)
of:SetWidth (f:GetWidth() + 2)
of:SetHeight (f:GetHeight() + 2)
if self.Pressed then
of.texture:SetTexture (Nx.Util_c2rgba ("303080ff"))
else
of.texture:SetTexture (Nx.Util_c2rgba ("101040ff"))
end
-- local lev = f:GetFrameLevel()
-- of:SetFrameLevel (lev + 1) -- Causing glitch when button pressed
of:SetParent (f) -- Seems to make us draw in front
of:Show()
Nx.Button.OverFrmOwn = f
else
-- tx:SetBlendMode ("BLEND")
if Nx.Button.OverFrmOwn == f then
of:Hide()
end
end
if typ.Dim then
SetDesaturation (tx, not self.Pressed)
end
end
-------------------------------------------------------------------------------
-- Edit box
--------
-- Create a edit box
-- ()
-- ret: edit box table
function Nx.EditBox:Create (parentFrm, user, func, maxLetters)
local box = {} -- New
setmetatable (box, self)
self.__index = self
box:SetUser (user, func)
local f = CreateFrame ("EditBox", nil, parentFrm)
box.Frm = f
f.NxInst = box
f:SetScript ("OnEditFocusGained", self.OnEditFocusGained)
f:SetScript ("OnEditFocusLost", self.OnEditFocusLost)
f:SetScript ("OnTextChanged", self.OnTextChanged)
f:SetScript ("OnEnterPressed", self.OnEnterPressed)
f:SetScript ("OnEscapePressed", self.OnEscapePressed)
f:SetFontObject ("NxFontS")
local t = f:CreateTexture()
t:SetTexture (.1, .2, .3, 1)
t:SetAllPoints (f)
f.texture = t
f:SetAutoFocus (false)
f:ClearFocus()
box.FilterDesc = "Search: [click]"
box.FilterDescEsc = "Search: %[click%]"
-- if Nx.Free then
-- box.FilterDesc = "Search: " .. Nx.FreeMsg
-- end
box.FilterStr = ""
f:SetText (box.FilterDesc)
f:SetMaxLetters (maxLetters)
return box
end
--------
-- Set handler to notify user
function Nx.EditBox:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Get text
function Nx.EditBox:GetText()
return self.FilterStr
end
--------
function Nx.EditBox:OnEditFocusGained()
Nx.ShowMessageTrial()
local this = self --V4
local self = this.NxInst
if self.FilterStr ~= "" then
this:SetText (self.FilterStr)
else
this:SetText ("")
end
end
function Nx.EditBox:OnEditFocusLost()
local this = self --V4
local self = this.NxInst
if self.FilterStr == "" then
this:SetText (self.FilterDesc)
end
end
function Nx.EditBox:OnTextChanged()
local this = self --V4
local self = this.NxInst
self.FilterStr = gsub (this:GetText(), self.FilterDescEsc, "")
-- Nx.prt ("Filter=%s", self.FilterStr)
if self.UserFunc then
self.UserFunc (self.User, self, "Changed")
end
end
function Nx.EditBox:OnEnterPressed()
self:ClearFocus()
end
function Nx.EditBox:OnEscapePressed()
local this = self --V4
local self = this.NxInst
self.FilterStr = ""
this:ClearFocus()
end
-------------------------------------------------------------------------------
-- Scroll bar
----------------------------------
-- Create a Scroll Bar
-- ()
-- ret: table
--[[
function ScrollBar:Create (parentFrm, typ, bx, by, width, height, func, user)
local c2rgba = Nx.Util_c2rgba
parentFrm = parentFrm or UIParent
local sbar = {} -- New
setmetatable (sbar, self)
self.__index = self
sbar:SetUser (user, func)
-- Create frame
local f = CreateFrame ("Frame", nil, parentFrm)
sbar.Frm = f
f.NxSBar = but
f.NxTip = tip or (typ and Button.TypeData[typ].Tip)
side = side or "TOPLEFT"
f:SetPoint (side, bx, by)
f:SetWidth (width)
f:SetHeight (height)
f:SetFrameStrata ("MEDIUM")
f:SetScript ("OnMouseDown", self.OnMouseDown)
f:SetScript ("OnMouseUp", self.OnMouseUp)
-- f:SetScript ("OnEnter", self.OnEnter)
-- f:SetScript ("OnLeave", self.OnLeave)
f:EnableMouse (true)
f:SetScript ("OnUpdate", self.OnUpdate)
local t = f:CreateTexture()
f.texture = t
t:SetAllPoints (f)
if typ and Button.TypeData[typ] then
but.Type = Button.TypeData[typ]
t:SetTexture (but.Type.Up)
else
t:SetTexture (c2rgba ("202020c8"))
end
f:Show()
--
-- Button:Create (f, "Close", nil, nil, -Window.BORDERW, -Window.BORDERH + 4, "TOPRIGHT", 20, 20, win.OnCloseButDown, win)
--
return sbar
end
--------
function ScrollBar:OnMouseDown (button)
-- prt ("ButMouseDown "..tostring (button))
local sb = this.NxSBar
local x, y = GetCursorPosition()
sb.ScrollingX = x / this:GetEffectiveScale()
sb.ScrollingY = y / this:GetEffectiveScale()
sb.Scrolling = true
sb:Update()
end
--------
function ScrollBar:OnMouseUp (button)
-- prt ("ButMouseUp "..tostring (button))
local sb = this.NxSBar
sb.Scrolling = false
sb:Update()
end
--------
function ScrollBar:Update()
if self.Scrolling then
if self.Func then
self.Func (self.User, self)
end
end
end
--]]
-------------------------------------------------------------------------------
-- Menus
function Nx.Menu:Init()
self.Menus = {} -- All created menus
self.Item_ALPHAFADE = 0
self.NameNum = 0
self.__index = self
Nx.MenuI.__index = Nx.MenuI
end
--------
-- Check if any menus are opened
function Nx.Menu:IsAnyOpened()
-- Only one can be current
return self.Cur and self.Cur.MainFrm:IsVisible() -- Esc may have hidden
--[[
if self.Menus then
for menu in pairs (self.Menus) do
-- Nx.prt ("%s", menu.MainFrm:GetName())
-- if menu.MainFrm:IsVisible() and not menu.Closing then
if menu.MainFrm:IsVisible() then
return true
end
end
end
--]]
end
----------------------------------
-- Create a menu
function Nx.Menu:Create (parentFrm, width)
local c2rgba = Nx.Util_c2rgba
local menu = {} -- New menu
self.Menus[menu] = true
setmetatable (menu, self)
menu.Items = {}
menu.Alpha = 1
menu.CloseTimer = 0 -- In seconds
menu.Width = width or 210
self.NameNum = self.NameNum + 1
local name = format ("NxMenu%d", self.NameNum)
local f = CreateFrame ("Frame", name, UIParent)
menu.MainFrm = f
tinsert (UISpecialFrames, name)
f.NxMenu = menu
f:Hide()
-- f:SetToplevel (1)
f:SetScript ("OnUpdate", self.OnUpdate)
-- f:SetScript ("OnLeave", self.OnLeave)
f:EnableMouse (true)
--[[
local t = f:CreateTexture()
t:SetTexture (c2rgba ("202020e0"))
t:SetAllPoints (f)
f.texture = t
--]]
menu:SetSkin()
return menu
end
function Nx.Menu:ResetSkins()
if self.Menus then
for menu, v in pairs (self.Menus) do
menu:SetSkin()
end
end
end
function Nx.Menu:SetSkin()
local f = self.MainFrm
local bk = Nx.Skin:GetBackdrop()
f:SetBackdrop (bk)
local col = Nx.Skin:GetBGCol()
f:SetBackdropColor (col[1], col[2], col[3], col[4])
local col = Nx.Skin:GetBorderCol()
f:SetBackdropBorderColor (col[1], col[2], col[3], col[4])
end
function Nx.Menu:OnUpdate (elapsed)
local this = self --V4
local self = this.NxMenu
-- Nx.prt ("elapsed %f %f", elapsed, self.CloseTimer)
self.Alpha = Nx.Util_StepValue (self.Alpha, self.AlphaTarget, elapsed * 4)
this:SetAlpha (self.Alpha)
if self.Closing then
if self.Alpha <= 0 then
self.Closing = nil
this:Hide()
end
return
end
local x, y = GetCursorPosition()
x = x / this:GetEffectiveScale()
y = y / this:GetEffectiveScale()
if x < this:GetLeft() - 1 or x > this:GetRight()
or y < this:GetBottom() or y > this:GetTop() + 1 then
-- prt ("MenuC "..x.." "..y)
-- prtFrame ("Menu", this)
if not Nx.Menu.SliderMoving then
self.CloseTimer = self.CloseTimer - elapsed
if self.CloseTimer <= 0 then
self:Close()
end
end
else
self.CloseTimer = .5
end
end
--------
-- Add sub menu
function Nx.Menu:AddSubMenu (menu, text)
local item = {}
self.Items[#self.Items + 1] = item
setmetatable (item, Nx.MenuI)
item.Menu = self
item.SubMenu = menu
item.Text = text
item.ShowState = 1
return item
end
--------
-- Add menu item
function Nx.Menu:AddItem (id, text, func, user)
local item = {}
self.Items[#self.Items + 1] = item
setmetatable (item, Nx.MenuI)
item.Menu = self
-- item.Type = "Text"
item.Id = id
item.Text = text
item.Func = func
item.User = user
item.ShowState = 1
-- item.GetChecked = self.Item_GetChecked
-- item.SetChecked = self.Item_SetChecked
-- item.GetSlider = self.Item_GetSlider
-- item.SetSlider = self.Item_SetSlider
if text == "" then
item.Spacer = true
end
return item
end
function Nx.MenuI:SetText (text)
self.Text = text
end
function Nx.MenuI:GetChecked()
return self.Checked
end
function Nx.MenuI:SetChecked (checked, varName)
self.Check = true
if type (checked) == "table" then
assert (varName)
self.Table = checked
self.VarName = varName
checked = self.Table[varName]
end
self.Checked = checked
if self.Table then
self.Table[self.VarName] = checked
end
end
------
-- Get slider position
function Nx.MenuI:GetSlider()
return self.SliderPos
end
------
-- Set slider position and optionally min and max values
function Nx.MenuI:SetSlider (pos, min, max, step, varName)
if type (pos) == "table" then
assert (varName)
self.Table = pos
self.VarName = varName
pos = self.Table[varName]
end
self.Slider = true
if min then
self.SliderMin = math.min (min, max)
self.SliderMax = math.max (min, max)
end
if step then
self.Step = step
end
-- Floor to step pos
if self.Step then
pos = floor (pos / self.Step + .5) * self.Step
end
-- Clamp pos
pos = math.max (pos, self.SliderMin)
pos = math.min (pos, self.SliderMax)
self.SliderPos = pos
if self.Table then
self.Table[self.VarName] = pos
end
end
--------
-- Set menu item show state
-- (false hides. -1 shows as disabled)
function Nx.MenuI:Show (show)
-- Nx.prt ("show %s %s", self.Text, show and 1 or 0)
self.ShowState = false
if show ~= false then
self.ShowState = (type (show) == "number") and show or 1
end
-- Nx.prtVar ("show", self.ShowState)
end
------
-- Not used?
--[[
function Nx.Menu:Item_GetUser (item)
return item.User
end
function Nx.Menu:Item_SetUser (item, user)
item.User = user
end
--]]
------
-- Open a menu
-- self = menu instance
function Nx.Menu:Open()
if Nx.Menu.Cur then -- Force current menu to close
Nx.Menu.Cur:Close()
end
Nx.Menu.Cur = self
local mf = self.MainFrm
self.Closing = nil
self.CloseTimer = 60 * 1
self.Alpha = 0
self.AlphaTarget = 1
local menuW = self.Width
local menuH = self:Update() + 14
mf:SetFrameStrata ("DIALOG")
mf:SetClampedToScreen (true)
mf:SetWidth (menuW)
mf:SetHeight (menuH)
local cx, cy = GetCursorPosition()
cx = cx / UIParent:GetEffectiveScale()
cy = cy / UIParent:GetEffectiveScale()
-- prt (format ("Menu Open (%f, %f)", cx, cy))
local opts = Nx:GetGlobalOpts()
local x = cx - 4
local y = cy + 4
if opts["MenuCenterH"] then
x = cx - menuW * .5
end
if opts["MenuCenterV"] then
y = cy + menuH * .5
end
mf:SetPoint ("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
mf:Show()
mf:Raise()
end
function Nx.Menu:Update()
local mf = self.MainFrm
local menuX = 14
local menuY = 14
local menuW = self.Width
for n = 1, #self.Items do
local item = self.Items[n]
local itemF = item.Frm
-- Nx.prt ("Open %s", item.Text)
if not item.ShowState then
-- Nx.prt ("Hide %s", item.Text)
if itemF then
itemF:Hide()
end
else
local itemH = 12 -- Not counting space between items
if not item.Spacer then
item.Alpha = 0
item.AlphaTarget = self.Item_ALPHAFADE
if not itemF then
item.Frm = CreateFrame ("Frame", nil, mf)
itemF = item.Frm
itemF.NxMenuItem = item
-- itemF:SetFrameStrata ("DIALOG")
itemF:SetWidth (menuW - menuX * 2)
itemF:SetScript ("OnEnter", self.Item_OnEnter)
itemF:SetScript ("OnLeave", self.Item_OnLeave)
itemF:SetScript ("OnUpdate", self.Item_OnUpdate)
itemF:SetScript ("OnMouseDown", self.Item_OnMouseDown)
itemF:SetScript ("OnMouseUp", self.Item_OnMouseUp)
local t = itemF:CreateTexture()
t:SetTexture (1, 1, 1, 1)
t:SetAllPoints (itemF)
itemF.texture = t
end
-- if item.SubMenu then
-- item.SubMenu:Close()
-- end
if item.Text then
local fstr = item.TextFStr
if not fstr then
fstr = itemF:CreateFontString()
item.TextFStr = fstr
fstr:SetFontObject ("NxFontMenu")
fstr:SetPoint ("TOPLEFT", 20, 0)
fstr:SetWidth (menuW - 20)
fstr:SetHeight (12)
fstr:SetJustifyH ("LEFT")
end
if item.ShowState < 0 then
fstr:SetText ("|cff707070" .. item.Text)
else
fstr:SetText ("|cfff7f7f7" .. item.Text)
end
fstr:Show()
end
if item.Check then
local frm = item.CheckFrm
if not frm then
frm = CreateFrame ("Frame", nil, itemF)
item.CheckFrm = frm
frm:SetWidth (12)
frm:SetHeight (12)
frm.texture = frm:CreateTexture()
frm.texture:SetAllPoints (frm)
end
frm:SetPoint ("TOPLEFT", 1, 0)
frm:Show()
self:CheckUpdate (item)
end
if item.Slider then
itemF:SetScript ("OnMouseWheel", self.Item_OnMouseWheel)
itemF:EnableMouseWheel (true)
local h = 10
local frm = item.SliderFrm
if not frm then
frm = CreateFrame ("Frame", nil, itemF)
item.SliderFrm = frm
frm:SetWidth (102)
frm:SetHeight (h)
frm.texture = frm:CreateTexture()
frm.texture:SetAllPoints (frm)
frm.texture:SetTexture (0, 0, 0, .5)
end
local tfrm = item.SliderThumbFrm
if not tfrm then
tfrm = CreateFrame ("Frame", nil, frm)
item.SliderThumbFrm = tfrm
-- tfrm:SetFrameStrata ("DIALOG")
tfrm:SetWidth (3)
tfrm:SetHeight (h)
tfrm.texture = tfrm:CreateTexture()
tfrm.texture:SetAllPoints (tfrm)
tfrm.texture:SetTexture (.5, 1, .5, 1)
end
frm:SetPoint ("TOPLEFT", 12, -itemH - 1)
frm:Show()
self:SliderUpdate (item)
itemH = itemH + h + 2
end
itemF:SetPoint ("TOPLEFT", menuX, -menuY)
itemF:SetHeight (itemH)
itemF:Show()
itemF:EnableMouse (true)
end
menuY = menuY + itemH + 1
end
end
return menuY
end
--------
function Nx.Menu:Close()
self.Closing = true
self.AlphaTarget = 0
if Nx.Menu.Cur == self then
Nx.Menu.Cur = false
end
end
--------
-- Set all menu items show state
-- (false hides. -1 shows as disabled)
function Nx.Menu:Show (show)
for _, item in ipairs (self.Items) do
item:Show (show)
end
end
------
-- Update all items check mark
--function Nx.Menu:CheckUpdateAll()
-- for _, item in ipairs (self.Items) do
-- self:CheckUpdate (item)
-- end
--end
------
-- Update check mark
-- self = invalid
function Nx.Menu:CheckUpdate (item)
local f = item.CheckFrm
if f then
local t = f.texture
local txName
if item.Table then
item.Checked = item.Table[item.VarName]
end
if item.Checked then
txName = Nx.Skin:GetTex ("ButChk")
else
txName = Nx.Skin:GetTex ("But")
end
t:SetTexture (txName)
end
end
------
-- Update slider
-- self = invalid
function Nx.Menu:SliderUpdate (item)
if item.Table then
item.SliderPos = item.Table[item.VarName]
end
local tfrm = item.SliderThumbFrm
local per = (item.SliderPos - item.SliderMin) / (item.SliderMax - item.SliderMin)
tfrm:SetPoint ("TOPLEFT", per * 100, 0)
if item.Text then
local fstr = item.TextFStr
fstr:SetText (format ("%s (%.2f)", item.Text, item.SliderPos))
end
end
------
function Nx.Menu:Item_OnEnter (motion)
local this = self --V4
local item = this.NxMenuItem
if item.ShowState and item.ShowState < 0 then
item.AlphaTarget = .5
else
item.AlphaTarget = .9
end
end
function Nx.Menu:Item_OnLeave (motion)
local this = self --V4
local item = this.NxMenuItem
item.AlphaTarget = Nx.Menu.Item_ALPHAFADE
-- item.SliderMoving = nil
end
function Nx.Menu:Item_OnUpdate (elapsed)
local this = self --V4
local item = this.NxMenuItem
item.Alpha = Nx.Util_StepValue (item.Alpha, item.AlphaTarget, elapsed * 4)
this.texture:SetVertexColor (.2, .2, .5, item.Alpha)
if item.Slider and item == Nx.Menu.SliderMoving then
Nx.Menu:Item_HandleSlider (item)
end
end
function Nx.Menu:Item_OnMouseDown (button)
local this = self --V4
local item = this.NxMenuItem
if button == "LeftButton" then
if item.Check then
item:SetChecked (not item.Checked)
Nx.Menu:CheckUpdate (item)
if item.Func then
item.Func (item.User, item, item.User)
end
elseif item.Slider then
Nx.Menu.SliderMoving = item
Nx.Menu:Item_HandleSlider (item)
elseif item.SubMenu then
item.SubMenu:Open()
-- item.Menu:Close()
else
if item.ShowState and item.ShowState >= 0 then
if item.Func then
item.Func (item.User, item, item.User)
end
end
item.Menu:Close()
end
end
end
function Nx.Menu:Item_OnMouseUp (button)
local this = self --V4
local item = this.NxMenuItem
if button == "LeftButton" then
Nx.Menu.SliderMoving = nil
end
end
function Nx.Menu:Item_OnMouseWheel (value)
local this = self --V4
local item = this.NxMenuItem
value = (value > 0 and 1 or -1) * (item.Step or .01)
if IsShiftKeyDown() then
value = value * 10
end
local x = item:GetSlider() + value
if IsAltKeyDown() then
x = 1
end
Nx.Menu:Item_SetUpdateSlider (item, x)
end
function Nx.Menu:Item_HandleSlider (item)
local frm = item.SliderFrm
local x = Nx.Util_GetMouseClampedXY (frm)
if x then
x = (x - 1) / (frm:GetWidth() - 2) * (item.SliderMax - item.SliderMin) + item.SliderMin
if IsShiftKeyDown() then
x = floor (x * 10) / 10
end
if IsAltKeyDown() then
x = 1
end
Nx.Menu:Item_SetUpdateSlider (item, x)
end
end
function Nx.Menu:Item_SetUpdateSlider (item, x)
local old = item:GetSlider()
item:SetSlider (x)
-- Nx.prt ("Slider %f", x)
if item:GetSlider() ~= old then
Nx.Menu:SliderUpdate (item)
-- Nx.prtVar ("Slider", item.Func)
if item.Func then
item.Func (item.User, item, item.User)
end
end
end
-------------------------------------------------------------------------------
-- List
--[[
Nx.List.FontSizeConvert = {
10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 15, 15, 15, 15, 15, 15, 15, 15
}
Nx.List.FontNames = {
[10] = "FontS",
[15] = "FontM"
}
--]]
function Nx.List:Init()
local ldata = Nx:GetData ("List")
self.SaveData = ldata
if not ldata.Version or ldata.Version < Nx.VERSIONList then
if ldata.Version then
Nx.prt ("Reset old list data")
end
ldata.Version = Nx.VERSIONList
for k, list in pairs (ldata) do
if type (list) == "table" then
-- Nx.prt (" Reset %s", k)
ldata[k] = nil
end
end
end
self.Lists = {}
local frms = {}
self.Frms = frms -- Table of frame type tables
self.FrmsUniqueI = 0
local types = { "Color", "WatchItem", "Info" }
for n, s in ipairs (types) do
frms[s] = {}
end
end
--------
-- Free list frames by adding back to global list
function Nx.List:FreeFrames (list)
local frms = self.Frms
for n, f in ipairs (list.UsedFrms) do
f:Hide()
tinsert (frms[f.NXListFType], n, f) -- Insert at top in same order, so we don't have flipping
end
list.UsedFrms = wipe (list.UsedFrms or {})
end
--------
-- Reset list frames by adding back to global list
--[[
function Nx.List:FreeFrame (list, frm)
list.UsedFrms[frm] = nil
local frms = self.Frms
frm:Hide()
tinsert (frms[frm.NXListFType], frm)
end
--]]
--------
-- Get a list frame from the global list
function Nx.List:GetFrame (list, typ)
local frms = self.Frms[typ]
local f = tremove (frms, 1)
if not f then
self.FrmsUniqueI = self.FrmsUniqueI + 1
if typ == "Color" then
f = CreateFrame ("ColorSelect", nil, list.Frm)
elseif typ == "WatchItem" then
f = CreateFrame ("Button", "NxListFrms" .. self.FrmsUniqueI, list.Frm, "WatchFrameItemButtonTemplate")
elseif typ == "Info" then
f = Nx.Info:CreateFrame (list.Frm)
end
f.NXListFType = typ
end
f:Show()
f:SetParent (list.Frm)
tinsert (list.UsedFrms, f)
return f
end
--------
-- Flag next update of all lists for a full update
function Nx.List:NextUpdateFull()
if self.Lists then
for inst in pairs (self.Lists) do
inst.SSW = nil
end
end
end
--------
-- Setup creation font
function Nx.List:SetCreateFont (font, baseLineH)
--[[
if type (font) == "number" then
local h = self.FontSizeConvert[font]
self.CFont = self.FontNames[h]
self.CLineH = h
self.CBaseLineH = baseLineH or h
return
end
--]]
self.CFont = font
-- self.CLineH = nil
self.CBaseLineH = baseLineH
end
--------
-- Create
function Nx.List:Create (saveName, xpos, ypos, width, height, parentFrm, showAll, noHeader)
if not self.CFont then -- Not set?
self:SetCreateFont ("FontS") -- Default
end
local inst = {} -- New instance
setmetatable (inst, self)
self.__index = self
if saveName then
local save = self.SaveData[saveName] or {}
self.SaveData[saveName] = save
inst.Save = save
if save["ColW"] then
inst.SaveColumnWidths = { strsplit ("^", save["ColW"]) }
end
end
inst.Columns = {}
inst.Strs = {}
inst.Buts = {}
inst.Font = self.CFont
inst.FontObj = Nx.Font:GetObj (inst.Font)
-- inst.LineH = self.CLineH
inst.LineHPad = 0
inst.BaseLineH = self.CBaseLineH
inst.Top = 1
inst.Vis = 1
inst.Selected = 1
inst.ShowAll = showAll
inst:SetMinSize()
-- Add to list of lists
self.Lists[inst] = true
inst.UsedFrms = {}
-- Create list frame
local frm = CreateFrame ("Frame", nil, parentFrm)
inst.Frm = frm
frm.NxInst = inst
frm:SetScript ("OnMouseDown", self.OnMouseDown)
frm:EnableMouse (true)
frm:SetScript ("OnMouseWheel", self.OnMouseWheel)
frm:EnableMouseWheel (true)
frm.texture = frm:CreateTexture()
frm.texture:SetAllPoints (frm)
frm.texture:SetTexture (0, 0, 0, .3)
frm:SetPoint ("TOPLEFT", xpos, ypos)
frm:Show()
-- Create list header
inst.HdrH = 0
if not noHeader then
inst.HdrH = 12
local hfrm = CreateFrame ("Frame", nil, frm)
inst.HdrFrm = hfrm
hfrm.NxInst = inst
hfrm:SetScript ("OnMouseDown", self.OnHdrMouseDown)
hfrm:EnableMouse (true)
hfrm.texture = hfrm:CreateTexture()
hfrm.texture:SetAllPoints (hfrm)
hfrm.texture:SetTexture (.2, .2, .3, 1)
hfrm:SetPoint ("TOPLEFT", 0, 0)
hfrm:Show()
end
-- Create selected line frame
local sfrm = CreateFrame ("Frame", nil, frm)
inst.SelFrm = sfrm
sfrm.NxInst = inst
sfrm.texture = sfrm:CreateTexture()
sfrm.texture:SetAllPoints (sfrm)
sfrm.texture:SetTexture (.4, .4, .5, .4)
sfrm.texture:SetBlendMode ("Add")
-- sfrm:SetHeight (inst:GetLineH() + 1)
sfrm:Hide()
-- Slider
if not showAll then
inst.Slider = Nx.Slider:Create (frm, "V", 10, inst.HdrH)
inst.Slider:SetUser (inst, self.OnSlider)
end
-- Finish setup
inst:Empty()
inst:SetSize (width, height)
-- Reset creation data
self.CFont = nil
--
return inst
end
--------
-- Set user of the list (for event handlers) and generic callback function
-- (instance)
-- self = instance
function Nx.List:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Set list fade
-- self = instance
function Nx.List:SetFade (fade)
-- prt ("Fade "..fade)
if not self.NoBGFade then
self.Frm.texture:SetVertexColor (1, 1, 1, fade)
end
local hf = self.HdrFrm
if hf then
hf.texture:SetVertexColor (1, 1, 1, fade)
end
self.SelFrm:SetAlpha (fade)
if self.Slider then
self.Slider.Frm.texture:SetAlpha (fade * .6)
self.Slider.ThumbFrm.texture:SetAlpha (fade * .9)
end
end
--------
-- Set list background color
-- self = instance
function Nx.List:SetBGColor (r, g, b, a, noFade)
if self.Frm.texture then
self.Frm.texture:SetTexture (r, g, b, a or 1)
end
self.NoBGFade = noFade
end
--------
-- Set list font size
-- self = instance
--[[
function Nx.List:SetFont (fontSize)
local h = self.FontSizeConvert[fontSize]
self.Font = self.FontNames[h]
self.LineH = fontSize
for id, column in ipairs (self.Columns) do
column.Font = self.Font
end
end
--]]
--------
-- Set list line height
-- self = instance
function Nx.List:SetLineHeight (height, hdrH)
self.LineHPad = height
self.HdrH = hdrH or 12
if self.Slider then
self.Slider:SetTLOff (self.HdrH)
end
self:Update()
end
function Nx.List:GetLineH()
return Nx.Font:GetH (self.Font) + self.LineHPad
end
--------
-- Set list item frame info
function Nx.List:SetItemFrameScaleAlpha (scale, alpha)
self.ItemFrameScale = scale
self.ItemFrameAlpha = alpha
end
--------
-- Lock or unlock list
function Nx.List:Lock (lock)
self.Frm:EnableMouse (not lock)
self.Frm:EnableMouseWheel (not lock)
end
--------
-- Force a full list update
function Nx.List:FullUpdate()
local w = self.SSW
self.SSW = nil
self:SetSize (w, self.SSH)
end
--------
-- Set minimum list size (width or height can be nil)
function Nx.List:SetMinSize (width, height)
self.MinW = width or 2
self.MinH = height or 1
end
--------
-- Update list size
-- self = instance
function Nx.List:SetSize (width, height)
if width == self.SSW and height == self.SSH then
-- Nx.prt ("List SetSize SKIP %s %s", width, height)
return
end
-- Nx.prt ("List SetSize %s %s", width, height)
self.SSW = width
self.SSH = height
if not self.ShowAll then
self:Resize (width, height)
end
self:Update()
end
function Nx.List:GetSize()
return self.SSW, self.SSH
end
--------
-- Update list size
-- self = instance
function Nx.List:Resize (width, height)
-- Nx.prt ("List resize %s %s", width, height)
local f = self.Frm
local hdrH = self.HdrH
local lineH = self:GetLineH()
local padW = 1
local padH = 0
if self.ShowAll then
height = self.Num * lineH + hdrH + padH * 2
local last = self.Top + self.Vis - 1
last = min (last, self.Num)
local strNum = 1
local cNum = 1
width = padW * 2
local offX = 0
for k, column in ipairs (self.Columns) do
local maxCW = column.Width
-- Nx.prt ("colW %s %s", k, maxCW)
for line = self.Top, last do
if self.Offsets then
offX = self.Offsets[line] or 0
end
maxCW = max (maxCW, self.Strs[strNum]:GetWidth() + offX)
-- Nx.prt ("maxCW %s %f", line, maxCW)
strNum = strNum + 1
end
strNum = strNum + (self.Vis * cNum - strNum + 1)
width = width + maxCW
cNum = cNum + 1
self.SSW = width
self.SSH = height
end
-- width = min (width, 30)
end
-- prt ("List WH %d %d", width, height)
width = max (self.MinW, width)
height = max (self.MinH, height)
f:SetWidth (width)
f:SetHeight (height)
local sfrm = self.SelFrm
sfrm:SetWidth (width - 10)
height = max (height - hdrH, 1)
self.Vis = floor ((height - padH * 2) / lineH)
self.Vis = max (self.Vis, 0)
-- Nx.prt ("List resize vis %s", self.Vis)
-- Set columns
local hf = self.HdrFrm
if hf then
hf:SetWidth (width)
hf:SetHeight (hdrH)
end
local x = 0
local clipW = width - padW * 2
for k, column in ipairs (self.Columns) do
local colW = min (column.Width, clipW)
column.ClipW = colW
local hfstr = column.FStr
if hfstr then
hfstr:SetPoint ("TOPLEFT", padW + x, 0)
hfstr:SetWidth (colW)
end
x = x + column.Width
clipW = clipW - column.Width
end
self:CreateStrings()
self:CreateButtons()
end
--------
-- Create any needed list strings
-- self = instance
function Nx.List:CreateStrings()
local f = self.Frm
local hdrH = self.HdrH
local lineH = self:GetLineH()
local width = f:GetWidth()
local padW = 1
local padH = 0
local x = 0
local strNum = 1
for k, column in ipairs (self.Columns) do
local colW = column.ClipW
local offX = 0
local offY = 0
for n = 1, self.Vis do
local fstr = self.Strs[strNum]
if not fstr then
fstr = f:CreateFontString()
self.Strs[strNum] = fstr
end
fstr:SetFontObject (column.FontObj)
fstr:SetJustifyH (column.JustifyH)
if self.Offsets then
local line = self.Top + n - 1
offX = self.Offsets[line] or 0
offY = self.Offsets[-line] or 0
end
fstr:SetPoint ("TOPLEFT", padW + x + offX, -(n - 1) * lineH - hdrH - padH - offY)
if not self.ShowAll then
fstr:SetWidth (colW - offX)
end
fstr:SetHeight (lineH)
fstr:Show()
strNum = strNum + 1
end
x = x + column.Width
end
-- Hide extra strings
-- prt ("ListSetSize "..self.Vis.." "..#self.Strs)
for n = strNum, #self.Strs do
self.Strs[n]:Hide()
end
end
--------
-- Create any needed list buttons
-- self = instance
function Nx.List:CreateButtons()
local butNum = 1
if self.ButData then
local scale = self:GetLineH() / self.BaseLineH
-- Nx.prt ("list but scale %s", scale)
local f = self.Frm
local offX = 0
local offY = 0
for n = 1, self.Vis do
local but = self.Buts[butNum]
if not but then
-- Nx.prt ("List resize create but %s", butNum)
but = Nx.Button:Create (f, nil, nil, nil, 0, 0, "CENTER", 14, 14, self.OnBut, self)
self.Buts[butNum] = but
but.Frm:SetFrameLevel (f:GetFrameLevel() + 1)
end
but.Frm:SetScale (scale)
butNum = butNum + 1
end
end
-- Hide extra buttons
if self.Buts then
for n = butNum, table.maxn (self.Buts) do
if self.Buts[n] then
self.Buts[n].Frm:Hide()
end
end
end
end
function Nx.List:Update (showLast)
if self.SortColumnId and not self.Sorted then
self:Sort()
end
local lineH = self:GetLineH()
local hdrH = self.HdrH
-- Nx.prt ("List lineH %s", lineH)
if showLast then
self:ShowLast()
end
if self.ShowAll then
self:Resize (0, 0)
end
self.Top = min (self.Top, self.Num - self.Vis + 1)
self.Top = max (self.Top, 1)
self.Selected = min (self.Selected, self.Num)
local last = self.Top + self.Vis - 1
last = min (last, self.Num)
if self.Offsets or #self.Strs < self.Vis then
self:CreateStrings()
end
local strNum = 1
local cNum = 1
for k, column in ipairs (self.Columns) do
for line = self.Top, last do
local txt = column.Data[line]
self.Strs[strNum]:SetText (txt)
strNum = strNum + 1
end
-- Hide extras
for n = strNum, self.Vis * cNum do
self.Strs[n]:SetText ("")
strNum = strNum + 1
end
cNum = cNum + 1
end
-- Do final resize and size parent win
if self.ShowAll then
self:Resize (0, 0)
local f = self.Frm
local win = f:GetParent().NxWin
if win then
win:SetSize (f:GetWidth(), -7, true)
end
end
-- Slider
if not self.ShowAll then
self.Slider:Set (self.Top, 1, self.Num, self.Vis)
self.Slider:Update()
end
-- Buttons
if self.ButData then
if not self.Buts or #self.Buts < self.Vis then
self:CreateButtons()
end
-- Nx.prt ("List Update Vis %s", self.Vis)
local padW = 1
local padH = 0
local butNum = 1
local f = self.Frm
local offX = 0
local offY = 0
local adjY = hdrH + padH + lineH/2 + .5
for n = 1, self.Vis do
local line = self.Top + n - 1
local but = self.Buts[butNum]
local butType = self.ButData[line]
if butType then
if not but then
Nx.prt ("!BUT %s", #self.Buts)
end
assert (but)
-- prt ("ListResize but #%d %s", n, butType)
but:SetType (butType)
but:SetId (line)
local butTx = self.ButData[line + 1000000]
if butType == "Color" then
local t = self.ButData[line + 8000000]
butTx = t[self.ButData[line + 9000000]]
end
-- prtVar ("But Tex", butTx)
but:SetTexture (butTx)
local butTip = self.ButData[line + 2000000]
but.Frm.NxTip = butTip
but.Frm.NXTipFrm = self.ButData[line + 3000000]
-- Causes update
but:SetPressed (self.ButData[-line])
if self.Offsets then
offX = self.Offsets[line] or 0
offY = self.Offsets[-line] or 0
end
local scale = self:GetLineH() / self.BaseLineH
local y = (-(n - 1) * lineH - adjY - offY) / scale
but.Frm:SetPoint ("CENTER", f, "TOPLEFT", (padW + lineH/2 + offX) / scale, y)
but.Frm:Show()
elseif but then
but.Frm:Hide()
end
butNum = butNum + 1
end
elseif self.Buts then
self:CreateButtons() -- Hides all since we have no data
end
-- Frames
--[[ Example: (OLD)
text 1 frm 1 (color)
--------- Visible
1 text 2
2 text 3 frm 2 (color). Get frm to keep until scrolls off visible area of list
3 text 4
4 text 5 frm 3 (color). Get frm
---------
text 6
--]]
if self.FrmData then -- Only used for Info and Watch Items
Nx.List:FreeFrames (self)
local lfrm = self.Frm
local offX = 3
local offY = 3
local adjY = hdrH + .5
local doBind = true
for n = 1, self.Vis do
local line = self.Top + n - 1
local data = self.FrmData[line]
if data then
local typ, v1, v2, v3 = strsplit ("~", data)
-- Nx.prt ("%s", -(n - 1) * lineH - adjY - offY)
if typ == "Info" then
if self.UserFunc then
self.UserFunc (self.User, "update", v1, -(n - 1) * lineH - adjY)
end
elseif typ == "WatchItem" then
local f = Nx.List:GetFrame (self, typ)
f:ClearAllPoints()
local scale = self.ItemFrameScale * .07 * lineH / 13
f:SetPoint ("TOPRIGHT", lfrm, "TOPLEFT", offX, -(n - 1) * lineH / scale - adjY - offY)
f["rangeTimer"] = -1
f:SetScale (scale)
f:SetWidth (29)
f:SetHeight (30)
f:SetAlpha (self.ItemFrameAlpha)
local id = tonumber (v1)
f:SetID (id)
SetItemButtonTexture (f, v2);
SetItemButtonCount (f, tonumber (v3));
f["charges"] = tonumber (v3);
local _, dur = GetQuestLogSpecialItemCooldown (id)
if dur then
WatchFrameItem_UpdateCooldown (f)
end
if doBind then
doBind = false
local opts = Nx:GetGlobalOpts()
local key = GetBindingKey ("NxWATCHUSEITEM")
if key then
opts["QWKeyUseItem"] = key
Nx.prt ("Key %s transfered to Watch List Item", key)
end
if #opts["QWKeyUseItem"] > 0 and not InCombatLockdown() then
local s = GetBindingAction (opts["QWKeyUseItem"])
s = strmatch (s, "CLICK (.+):")
-- Nx.prt ("Key's frm %s", s or "nil")
if s ~= f:GetName() then
local ok = SetBindingClick (opts["QWKeyUseItem"], f:GetName())
Nx.prt ("Key %s %s #%s %s", opts["QWKeyUseItem"], f:GetName(), line, ok or "nil")
opts["QWKeyUseItem"] = ""
end
end
end
f:Show()
end
end
end
end
-- Position selected line
local sfrm = self.SelFrm
local selY = self.Selected - self.Top
if selY < 0 or selY >= self.Vis then
sfrm:Hide()
else
sfrm:SetHeight (lineH + 1)
sfrm:SetPoint ("TOPLEFT", 0, -selY * lineH - self.HdrH)
sfrm:Show()
end
end
--------
function Nx.List:SaveColumns()
if self.Save then
local str = ""
local sep = ""
for id, column in ipairs (self.Columns) do
str = str .. sep .. column.Width
sep = "^"
end
self.Save["ColW"] = str
end
end
function Nx.List:ColumnAdd (name, columnId, width, justifyH, font)
local colId = columnId or 1
local w = width or 9999
if self.SaveColumnWidths then
w = tonumber (self.SaveColumnWidths[colId]) or w
end
local column = {}
column.Name = name
-- column.Max = 0
column.Width = w
column.FontObj = Nx.Font:GetObj (font or self.Font)
column.JustifyH = justifyH or "LEFT"
column.Data = {}
if self.HdrFrm then
local fstr = self.HdrFrm:CreateFontString()
column.FStr = fstr
fstr:SetFontObject (self.FontObj)
fstr:SetJustifyH (column.JustifyH)
fstr:SetPoint ("TOPLEFT", 0, 0)
if w >= 0 then
fstr:SetWidth (w)
end
fstr:SetHeight (self.HdrH)
fstr:SetText (name)
fstr:SetTextColor (.8, .8, 1, 1)
fstr:Show()
end
self.Columns[colId] = column
self.SSW = nil -- Cause resize
end
function Nx.List:ColumnSetName (columnId, name)
local colId = columnId or 1
local column = self.Columns[colId]
column.Name = name
local fstr = column.FStr
if fstr then
if self.SortColumnId == columnId then
name = ">" .. name
end
fstr:SetText (name)
fstr:SetTextColor (.8, .8, 1, 1)
self.SSW = nil -- Cause resize
end
end
function Nx.List:ColumnHitTest (x)
local colX = 0
for id, column in ipairs (self.Columns) do
if x >= colX and x < colX + column.Width then
return id, column
end
colX = colX + column.Width
end
end
--------
-- Empty the list
function Nx.List:Empty()
self.Num = 0
self.Data = wipe (self.Data or {})
for k, column in pairs (self.Columns) do
column.Data = column.Data and wipe (column.Data)
end
if self.ButData then
wipe (self.ButData)
end
if self.Offsets then
wipe (self.Offsets)
end
if self.FrmData then
wipe (self.FrmData)
end
-- if self.FrmDataFrm then
-- wipe (self.FrmDataFrm)
-- end
Nx.List:FreeFrames (self)
self.Sorted = false
end
--------
function Nx.List:ColumnSort (columnId)
self.Sorted = false
if self.SortColumnId == columnId then
self.SortColumnId = nil
else
self.SortColumnId = columnId
end
for id, column in pairs (self.Columns) do
self:ColumnSetName (id, column.Name)
end
end
--------
-- Sort list by a columns contents
function Nx.List:Sort()
local column = self.Columns[self.SortColumnId]
local cData = column.Data
if not cData then --or #cData < self.Num then
return
end
self.Sorted = true
local cNameData = self.Columns[2].Data
local t = {}
for n = 1, self.Num do
local name = gsub (cNameData[n], "|cff......", "")
t[n] = gsub (cData[n] or "", "|cff......", "") .. " " .. strsub (name, 1, 1) .. "~" .. n
end
sort (t)
-- Convert sorted to number
for n = 1, #t do
local _, i = strsplit ("~", t[n])
t[n] = tonumber (i)
end
-- Reorder tables
local data = {}
for n = 1, #t do
data[n] = self.Data[t[n]]
end
self.Data = data
for k, column in pairs (self.Columns) do
if column.Data then
local data = {}
for n = 1, #t do
data[n] = column.Data[t[n]]
end
column.Data = data
end
end
if self.ButData then
local data = {}
for n = 1, #t do
local i = t[n]
data[n] = self.ButData[i]
data[-n] = self.ButData[-i]
data[n + 1000000] = self.ButData[i + 1000000]
data[n + 2000000] = self.ButData[i + 2000000]
data[n + 3000000] = self.ButData[i + 3000000]
data[n + 8000000] = self.ButData[i + 8000000]
data[n + 9000000] = self.ButData[i + 9000000]
end
self.ButData = data
end
if self.Offsets then
local data = {}
for n = 1, #t do
data[n] = self.Offsets[t[n]]
end
self.Offsets = data
end
end
--------
function Nx.List:ItemAdd (userData)
self.Num = self.Num + 1
self.Data[self.Num] = userData
end
function Nx.List:ItemGetNum()
return self.Num
end
function Nx.List:ItemSet (columnId, str, index)
local i = index or self.Num
local column = self.Columns[columnId]
column.Data[i] = str
end
--[[
function Nx.List:ItemGetButtonPressed (index)
if self.ButData then
local but = self.Buts[index]
if but then
return but:GetPressed()
end
end
return false
end
--]]
function Nx.List:ItemSetButton (typ, pressed, tex, tip)
if not self.ButData then
self.ButData = {}
end
local index = self.Num
self.ButData[index] = typ
self.ButData[-index] = pressed
if tex then
self.ButData[index + 1000000] = tex
end
if tip then
self.ButData[index + 2000000] = tip
end
end
function Nx.List:ItemGetButtonTip (index)
if self.ButData then
return self.ButData[index + 2000000]
end
end
function Nx.List:ItemSetButtonTip (tip, index, frm)
if self.ButData then
index = index or self.Num
self.ButData[index + 2000000] = tip
if frm then
self.ButData[index + 3000000] = frm
end
end
end
--------
-- Set a solid colored button used to pick colors
-- Table[key] is a "rrggbbaa" hex number
function Nx.List:ItemSetColorButton (table, key, hasAlpha)
if not self.ButData then
self.ButData = {}
end
local index = self.Num
self.ButData[index] = "Color"
self.ButData[index + 8000000] = table
self.ButData[index + 9000000] = key
if not hasAlpha then
self.ButData[index + 10000000] = true
end
end
function Nx.List:ItemSetFrame (typ)
if not self.FrmData then
self.FrmData = {}
-- self.FrmDataFrm = {}
end
self.FrmData[self.Num] = typ
end
function Nx.List:ItemSetOffset (offX, offY)
if not self.Offsets then
self.Offsets = {}
end
self.Offsets[self.Num] = offX
self.Offsets[-self.Num] = offY
end
function Nx.List:ItemGetData (index)
index = index or self.Selected
return index and self.Data[index]
end
function Nx.List:ItemSetData (index, data)
self.Data[index] = data
end
--------
-- Get extended data
-- (num >= 1)
function Nx.List:ItemGetDataEx (index, num)
index = index or self.Selected
return index and self.Data[index + num * 10000000]
end
--------
-- Set extended data
function Nx.List:ItemSetDataEx (index, data, num)
self.Data[(index or self.Num) + num * 10000000] = data
end
--------
-- Select list line
-- (index or 0)
function Nx.List:Select (index)
assert (index >= 0 and index <= self.Num)
self.Selected = index
if index < self.Top then
self.Top = max (index, 1)
elseif index >= self.Top + self.Vis then
self.Top = max (index - self.Vis + 1, 1)
end
end
--------
-- Get selected list line
function Nx.List:GetSelected()
return self.Selected
end
--------
-- Send select to user
function Nx.List:SendUserSelect()
if self.UserFunc then
self.UserFunc (self.User, "select", self.Selected, 0)
end
end
--------
-- Show last item at bottom of list view
function Nx.List:ShowLast()
self.Top = self.Num - self.Vis + 1
self.Top = max (self.Top, 1)
end
--------
-- Is the last item shown?
function Nx.List:IsShowLast()
local top = self.Num - self.Vis + 1
top = max (top, 1)
return self.Top == top
end
function Nx.List:OnHdrMouseDown (click)
local this = self --V4
local x = Nx.Util_IsMouseOver (this)
if x then
local self = this.NxInst
local id, column = self:ColumnHitTest (x)
if id then
-- Nx.prt ("OnHdrMouseDown %s", id)
if IsShiftKeyDown() then
local add = click == "LeftButton" and 10 or -10
column.Width = max (column.Width + add, 10)
self:SaveColumns()
self:FullUpdate()
else
if click == "LeftButton" then
if id and self.UserFunc then
self.UserFunc (self.User, "sort", 0, id)
end
else
Nx.prt ("shift left/right click to change size")
end
end
end
end
end
Nx.List.ClickToName = {
["LeftButton"] = "select",
["MiddleButton"] = "mid",
["RightButton"] = "menu",
["Button4"] = "back",
}
function Nx.List:OnMouseDown (click)
-- prt ("List MouseDown "..click)
local this = self --V4
local inst = this.NxInst
local x, y = Nx.Util_IsMouseOver (this)
if x then
y = this:GetHeight() - y
if y >= inst.HdrH then
y = floor ((y - inst.HdrH) / inst:GetLineH())
inst.Selected = min (y + inst.Top, inst.Num)
local id = inst:ColumnHitTest (x)
if id and inst.UserFunc then
inst.UserFunc (inst.User, Nx.List.ClickToName[click], inst.Selected, id)
end
inst:Update()
end
end
end
function Nx.List:OnMouseWheel (value)
-- prt ("List MouseWheel "..tostring (value))
if IsShiftKeyDown() then
value = value * 5
if IsControlKeyDown() then
value = value * 20
end
end
local this = self --V4
local inst = this.NxInst
inst.Top = inst.Top - value
inst:Update()
end
function Nx.List:OnBut (but, id, click)
if self.ButData[id] == "Color" then
self:OpenColorDialog (id)
return
end
self.ButData[-id] = but:GetPressed()
-- prt ("List but %d %s", id, tostring (self.ButData[-id]))
if self.UserFunc then
self.UserFunc (self.User, "button", id, self.ButData[-id], click, but)
end
end
function Nx.List:OpenColorDialog (id)
local f = ColorPickerFrame
f:SetMovable (true)
self.ColorId = id
f.NXList = self
f.NXTbl = self.ButData[id + 8000000]
f.NXVName = self.ButData[id + 9000000]
local hasAlpha = not self.ButData[id + 10000000]
f["func"] = function()
local f = ColorPickerFrame
local r, g, b = f:GetColorRGB()
local a = f["hasOpacity"] and (1 - OpacitySliderFrame:GetValue()) or 1
-- Nx.prt ("%s %s %s %s", r, g, b, a)
f.NXTbl[f.NXVName] = floor (r * 255) * 0x1000000 + floor (g * 255) * 0x10000 + floor (b * 255) * 0x100 + floor (a * 255)
local self = f.NXList
self:Update()
if self.UserFunc then
self.UserFunc (self.User, "color", self.ColorId)
end
end
f["hasOpacity"] = hasAlpha
f["opacityFunc"] = f["func"]
f["cancelFunc"] = function (old)
f.NXTbl[f.NXVName] = old
local self = f.NXList
self:Update()
if self.UserFunc then
self.UserFunc (self.User, "color", self.ColorId)
end
end
local col = f.NXTbl[f.NXVName]
f["previousValues"] = col
local r, g, b, a = Nx.Util_num2rgba (col)
f:SetColorRGB (r, g, b)
f["opacity"] = 1 - a
ShowUIPanel (f)
end
function Nx.List:OnSlider (slider, pos)
self.Top = floor (pos)
self:Update()
end
-------------------------------------------------------------------------------
-- Drop down
function Nx.DropDown:Init()
-- Create Window
local win = Nx.Window:Create ("NxDD", nil, nil, nil, 0, true, true, true)
self.Win = win
local frm = win.Frm
win:EnableMenu (false)
win:InitLayoutData (nil, 0, 0, 200, 200)
tinsert (UISpecialFrames, frm:GetName())
frm:SetClampedToScreen (true)
frm:SetToplevel (true)
-- self.Win:Show (false)
-- List
Nx.List:SetCreateFont ("FontM")
local list = Nx.List:Create (false, 0, 0, 1, 1, frm, false, true)
self.List = list
list:SetUser (self, self.OnListEvent)
list:ColumnAdd ("", 1)
-- list:SetLineHeight (0, 0)
win:Attach (list.Frm, 0, 1, 0, 1)
end
function Nx.DropDown:Start (user, func)
self.User = user
self.Func = func
local list = self.List
list:Empty()
end
function Nx.DropDown:Add (name, select)
-- Nx.prt ("DropDown Add %s", name)
local list = self.List
list:ItemAdd (name)
list:ItemSet (1, name)
if select then
list:Select (list:ItemGetNum())
end
end
function Nx.DropDown:AddT (data, selectI)
for n, name in ipairs (data) do
self:Add (name, n == selectI)
end
end
function Nx.DropDown:Show (parent, x, y)
local uiparent = UIParent
if not x then
x, y = GetCursorPosition()
x = x / uiparent:GetEffectiveScale() - 80
y = y / uiparent:GetEffectiveScale() - GetScreenHeight() + 10
end
-- Nx.prt ("DropDown Show %s %s", x, y)
local win = self.Win
local f = win.Frm
local list = self.List
win:SetFrmStrata (4)
f:SetParent (parent)
f:SetPoint ("TOPLEFT", uiparent, "TOPLEFT", x, y)
win:Show()
list:FullUpdate()
end
--------
-- On list control updates
function Nx.DropDown:OnListEvent (eventName, sel, val2, click)
local name = self.List:ItemGetData (sel)
if name then
-- Nx.prt ("DropDown %s, %s", eventName, name)
if eventName == "select" or eventName == "mid" then
self.Func (self.User, name, sel)
end
end
self.Win:Show (false)
end
-------------------------------------------------------------------------------
-- Tab Bar
function Nx.TabBar:GetHeight()
return 22
end
----------------------------------
-- Create a Tab Bar
-- ()
-- ret: tab bar table
function Nx.TabBar:Create (name, parentFrm, width, height)
local c2rgba = Nx.Util_c2rgba
parentFrm = parentFrm or UIParent
-- New
local bar = {}
setmetatable (bar, self)
self.__index = self
bar.Name = name
bar.Tabs = {}
-- Create window frame
local f = CreateFrame ("Frame", name, parentFrm)
bar.Frm = f
f.NxInst = bar
-- f:SetMinResize (100, 40)
f:SetWidth (width)
f:SetHeight (height)
f:SetPoint ("TOPLEFT", 100, -100)
-- f:SetFrameStrata ("MEDIUM")
-- f:SetScript ("OnEvent", self.OnEvent)
-- f:RegisterEvent ("PLAYER_LOGIN")
-- f:SetScript ("OnUpdate", self.OnUpdate)
local t = f:CreateTexture()
t:SetTexture (c2rgba ("00000080"))
t:SetAllPoints (f)
f.texture = t
f:Show()
-- Create GUI elements
bar:CreateBorders()
return bar
end
------
-- Create border frames
function Nx.TabBar:CreateBorders()
local c2rgba = Nx.Util_c2rgba
local f = CreateFrame ("Frame", nil, self.Frm)
self.TopFrm = f
f:SetPoint ("TOPLEFT", 0, 0)
f:SetPoint ("TOPRIGHT", 0, 0)
-- f:SetWidth (1)
f:SetHeight (4)
local t = f:CreateTexture()
t:SetTexture (c2rgba ("505050ff"))
t:SetAllPoints (f)
f.texture = t
f:Show()
end
--------
-- Set user for notify
function Nx.TabBar:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Add a tab to bar
function Nx.TabBar:AddTab (name, index, width, press, template, butId)
local tab = {}
self.Tabs[index] = tab
tab.Name = name
-- (parentFrm, typ, text, tip, bx, by, side, width, height, func, user)
local w = width or 66
local x = 1 + (index - 1) * (w + 2)
tab.W = w
local but = Nx.Button:Create (self.TopFrm, "Tab", name, nil, x, -1, "TOPLEFT", w, 20, self.OnBut, self, template)
tab.But = but
if butId then
but.Frm:SetID (butId)
end
but:SetId (index)
if press then
but:SetPressed (true)
local txt = "|cffffffff" .. name
but:SetText (txt, 0, 2)
end
end
--------
-- Select tab button
function Nx.TabBar:Select (index, force)
local selTab = self.Tabs[index]
if not selTab then
return
end
local but = selTab.But
if not force and but:GetPressed() then
return
end
local x = 1
for i, tab in pairs (self.Tabs) do
if i ~= index then
tab.But:SetPressed (false)
tab.But:SetText (tab.Name, 0, 0)
end
tab.But:SetPos ("TOPLEFT", x, -1)
tab.But:SetSize (tab.W, 20)
x = x + tab.W + 2
end
but:SetPressed (true)
local txt = "|cffffffff" .. selTab.Name
but:SetText (txt, 0, 2)
if self.UserFunc then
self.UserFunc (self.User, index)
end
end
--------
-- Enable tab button
function Nx.TabBar:Enable (index, enable)
local tab = self.Tabs[index]
tab.But.Frm:EnableMouse (enable ~= false)
end
--------
-- Set our fade
function Nx.TabBar:SetFade (fade)
local f = self.Frm
f.texture:SetVertexColor (1, 1, 1, fade * .5)
local tf = self.TopFrm
tf.texture:SetVertexColor (1, 1, 1, fade)
for i, tab in pairs (self.Tabs) do
local f = tab.But.Frm
f.texture:SetVertexColor (1, 1, 1, fade)
end
end
--------
-- Handle tab button press
function Nx.TabBar:OnBut (but, id, click)
-- Nx.prt ("TabBar but %d %s", id, click)
if not but:GetPressed() then
-- Keep it pressed
but:SetPressed (true)
return
end
-- if but.Frm:GetID() ~= 0 then
-- Nx.prt ("TabBar but id %s", but.Frm:GetID())
-- return
-- end
self:Select (id, true)
end
-------------------------------------------------------------------------------
-- Tool Bar
function Nx.ToolBar:Init()
local data = Nx:GetDataToolBar()
if not data.Version or data.Version < Nx.VERSIONTOOLBAR then
if data.Version then
Nx.prt ("Reset old tool bar data")
end
data.Version = Nx.VERSIONTOOLBAR
for k, bar in pairs (data) do
if type (bar) == "table" then
-- Nx.prt (" Reset %s", k)
data[k] = nil
end
end
end
self.TBs = {} -- All created tool bars
self.BORDERW = 5
self.BORDERH = 5
self.Borders = {
"TOPLEFT", "TOPRIGHT", 1, self.BORDERH, "WinBrH",
"BOTTOMLEFT", "BOTTOMRIGHT", 1, self.BORDERH, "WinBrH",
"TOPLEFT", "BOTTOMLEFT", self.BORDERW, 1, "WinBrV",
"TOPRIGHT", "BOTTOMRIGHT", self.BORDERW, 1, "WinBrV",
}
local menu = Nx.Menu:Create (UIParent)
self.Menu = menu
-- self.MenuIUp = menu:AddItem (0, "Move Up", self.Menu_OnUp, self)
-- self.MenuIDn = menu:AddItem (0, "Move Down", self.Menu_OnDn, self)
-- self.MenuIRemove = menu:AddItem (0, "Remove", self.Menu_OnRemove, self)
self.MenuISize = menu:AddItem (0, "Size", self.Menu_OnSize, self)
self.MenuISize:SetSlider (8, 8, 32)
self.MenuISpace = menu:AddItem (0, "Spacing", self.Menu_OnSpace, self)
self.MenuISpace:SetSlider (0, 0, 15)
self.MenuIAlignR = menu:AddItem (0, "Align Right", self.Menu_OnAlignR, self)
self.MenuIAlignR:SetChecked (true)
self.MenuIAlignB = menu:AddItem (0, "Align Bottom", self.Menu_OnAlignB, self)
self.MenuIAlignB:SetChecked (true)
self.MenuIVert = menu:AddItem (0, "Vertical", self.Menu_OnVertical, self)
self.MenuIVert:SetChecked (true)
end
--function Nx.ToolBar:Menu_OnUp (item)
--end
--function Nx.ToolBar:Menu_OnDn (item)
--end
--function Nx.ToolBar:Menu_OnRemove (item)
--end
function Nx.ToolBar:Menu_OnSize (item)
self:MenuDoUpdate ("Size", item:GetSlider())
end
function Nx.ToolBar:Menu_OnSpace (item)
self:MenuDoUpdate ("Space", item:GetSlider())
end
function Nx.ToolBar:Menu_OnAlignR (item)
self:MenuDoUpdate ("AlignR", item:GetChecked())
end
function Nx.ToolBar:Menu_OnAlignB (item)
self:MenuDoUpdate ("AlignB", item:GetChecked())
end
function Nx.ToolBar:Menu_OnVertical (item)
self:MenuDoUpdate ("Vert", item:GetChecked())
end
function Nx.ToolBar:MenuDoUpdate (varName, value)
local bar = self.Active
local data = Nx:GetDataToolBar()
local svdata = data[bar.Name]
svdata[varName] = value
bar:Update()
end
function Nx.ToolBar:OpenMenu (bar)
local data = Nx:GetDataToolBar()
local svdata = data[bar.Name]
self.MenuISize:SetSlider (svdata["Size"])
self.MenuISpace:SetSlider (svdata["Space"] or 3)
self.MenuIAlignR:SetChecked (svdata["AlignR"])
self.MenuIAlignB:SetChecked (svdata["AlignB"])
self.MenuIVert:SetChecked (svdata["Vert"])
self.Active = bar
self.Menu:Open()
end
--function Nx.ToolBar:GetHeight()
-- return 22
--end
----------------------------------
-- Create a Tool Bar
-- ()
-- ret: tool bar table
function Nx.ToolBar:Create (name, parentFrm, size, alignR, alignB)
local c2rgba = Nx.Util_c2rgba
parentFrm = parentFrm or UIParent
local data = Nx:GetDataToolBar()
local svdata = data[name]
-- svdata = nil
if not svdata then -- No data for our name?
svdata = {} -- New
data[name] = svdata
svdata["Size"] = size
svdata["Space"] = 1
svdata["AlignR"] = alignR
svdata["AlignB"] = alignB
-- svdata["Vert"] = nil
end
-- New
local bar = {}
setmetatable (bar, self)
self.__index = self
assert (self.TBs[bar] == nil)
self.TBs[bar] = true
bar.Name = name
bar.Tools = {}
bar.Size = size -- Default
-- Create window frame
local f = CreateFrame ("Frame", name, parentFrm)
bar.Frm = f
f.NxInst = bar
-- f:SetMinResize (100, 40)
f:SetWidth (size)
f:SetHeight (10)
f:SetPoint ("TOPRIGHT", 0, 0)
-- f:SetScript ("OnEvent", self.OnEvent)
-- f:RegisterEvent ("PLAYER_LOGIN")
-- f:SetScript ("OnUpdate", self.OnUpdate)
-- local t = f:CreateTexture()
-- t:SetTexture (c2rgba ("00000080"))
-- t:SetAllPoints (f)
-- f.texture = t
f:Show()
--
return bar
end
--------
-- Set user for notify
function Nx.ToolBar:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
-- Add a button to bar
function Nx.ToolBar:AddButton (typ, name, index, func, press)
local tool = {}
tinsert (self.Tools, tool)
tool.Name = name
tool.Func = func
-- (parentFrm, typ, text, tip, bx, by, side, width, height, func, user)
local but = Nx.Button:Create (self.Frm, typ, nil, name, 0, 0, "TOPLEFT", 1, 1, self.OnBut, self)
tool.But = but
but:SetId (func)
but:SetPressed (press)
end
--------
-- Handle toolbar button press
function Nx.ToolBar:OnBut (but, id, click, x, y)
-- prt ("ToolBar but %d %s", id, click)
if click == "RightButton" then
Nx.ToolBar:OpenMenu (self)
else
local func = id
if func then
func (self.User, but, click, x, y)
end
end
end
--------
-- Update toolbar
function Nx.ToolBar:Update()
local data = Nx:GetDataToolBar()
local svdata = data[self.Name]
local f = self.Frm
-- Nx.prtVar ("AlignR", svdata["AlignR"])
f:ClearAllPoints()
local align = "TOPRIGHT"
if not svdata["AlignR"] then
align = "TOPLEFT"
if svdata["AlignB"] then
align = "BOTTOMLEFT"
end
else
if svdata["AlignB"] then
align = "BOTTOMRIGHT"
end
end
f:SetPoint (align, 0, 0)
local scale = svdata["Size"] / self.Size
local space = (svdata["Space"] or 0) / scale
local step = self.Size + space
local xstep = step
local ystep = 0
if svdata["Vert"] then
xstep = 0
ystep = step
end
local xoff = 0
local yoff = 0
for n, tool in ipairs (self.Tools) do
local but = tool.But
if but then
but:SetPos ("TOPLEFT", xoff, -yoff)
end
xoff = xoff + xstep
yoff = yoff + ystep
end
if not svdata["Vert"] then
xoff = xoff - space
else
yoff = yoff - space
end
-- Nx.prt ("scale %f, w %f, xoff %f", scale, self.Size, xoff)
f:SetWidth (max (xoff, self.Size))
f:SetHeight (max (yoff, self.Size))
f:SetScale (scale)
end
--------
-- Set fade level of toolbar and tools
-- (0-1)
function Nx.ToolBar:SetFade (fade)
-- Nx.prtVar ("TB Fade", fade)
self.Frm:SetAlpha (fade)
end
--------
-- Set level of toolbar and tools
function Nx.ToolBar:SetLevels (level)
self.Frm:SetFrameLevel (level)
for n, tool in ipairs (self.Tools) do
local but = tool.But
if but then
but.Frm:SetFrameLevel (level + 1)
end
end
end
-------------------------------------------------------------------------------
-- Sliders
--------
-- Create
-- (parent, "H" or "V", bar size, top or left offset of bar)
function Nx.Slider:Create (parentFrm, typ, size, tlOff)
-- if 1 then return end
local inst = {} -- New instance
setmetatable (inst, self)
self.__index = self
local w = size
local h = size
inst.TypeH = typ == "H"
if inst.TypeH then
w = 10
else
h = 10
end
local frm = CreateFrame ("Frame", nil, parentFrm)
inst.Frm = frm
frm.NxInst = inst
frm:SetScript ("OnUpdate", self.OnUpdate)
frm:SetScript ("OnMouseDown", self.OnMouseDown)
frm:SetScript ("OnMouseUp", self.OnMouseUp)
frm:EnableMouse (true)
frm:SetWidth (w)
frm:SetHeight (h)
frm.texture = frm:CreateTexture()
frm.texture:SetAllPoints (frm)
frm.texture:SetTexture (.3, .3, .4, .6)
frm:SetPoint ("TOPRIGHT", parentFrm, "TOPRIGHT", 0, -tlOff)
frm:SetPoint ("BOTTOMRIGHT", parentFrm, "BOTTOMRIGHT", 0, 0)
frm:Show()
-- Thumb
local tfrm = CreateFrame ("Frame", nil, frm)
inst.ThumbFrm = tfrm
tfrm:SetWidth (w)
tfrm:SetHeight (h)
tfrm.texture = tfrm:CreateTexture()
tfrm.texture:SetAllPoints (tfrm)
tfrm.texture:SetTexture (.3, .3, .7, .9)
tfrm:SetPoint ("TOPLEFT", 1, 1)
tfrm:Show()
--
inst:Set (0, 0, 9, 1)
inst:Update()
return inst
end
--------
-- Set user of the slider for callback function
-- (user table, function)
function Nx.Slider:SetUser (user, func)
self.User = user
self.UserFunc = func
end
--------
--
function Nx.Slider:SetTLOff (tlOff)
local par = self.Frm:GetParent()
self.Frm:SetPoint ("TOPRIGHT", par, "TOPRIGHT", 0, -tlOff)
end
--------
-- Get slider position
-- self = instance
function Nx.Slider:Get()
return self.Pos
end
--------
-- Set slider position and optionally min and max values
-- self = instance
function Nx.Slider:Set (pos, min, max, visSize)
if min then
self.Min = math.min (min, max)
self.Max = math.max (min, max)
end
if visSize then
self.VisSz = math.max (visSize, 1)
end
-- Clamp pos
pos = math.max (pos, self.Min)
pos = math.min (pos, self.Max - self.VisSz + 1)
self.Pos = pos
-- Nx.prt ("Slider Set %f (%f %f) %f", pos, self.Min, self.Max, self.VisSz)
end
function Nx.Slider:OnMouseDown (button)
local this = self --V4
local self = this.NxInst
if button == "LeftButton" then
local frm = self.Frm
local x, y = Nx.Util_IsMouseOver (frm)
if x and x >= 0 then
local tfrm = self.ThumbFrm
local tx, ty = Nx.Util_IsMouseOver (tfrm)
if self.TypeH then
local w = (frm:GetRight() or 0) - (frm:GetLeft() or 0)
x = (x - 1) / (frm:GetWidth() - 2) * (self.Max - self.Min) + self.Min
self:Set (x)
else
if tx then
self.DragX = x
self.DragY = y
self.DragPos = self.Pos
else
local h = (frm:GetTop() or 0) - (frm:GetBottom() or 0)
y = h - y
-- Nx.prt ("Slider XY %f %f", x, y)
local pos = self.Pos
if y < -self.TPt then
pos = pos - self.VisSz
else
pos = pos + self.VisSz
end
self:Set (pos)
end
end
self:Update()
if self.UserFunc then
self.UserFunc (self.User, self, self.Pos)
end
end
end
end
function Nx.Slider:OnMouseUp (button)
local inst = self.NxInst
inst.DragX = nil
end
function Nx.Slider:OnUpdate (elapsed)
local this = self --V4
local self = this.NxInst
self:Drag()
if self.NeedUpdate then
self.NeedUpdate = false
self:DoUpdate()
end
end
function Nx.Slider:Drag()
if self.DragX then
local frm = self.Frm
local x, y = Nx.Util_GetMouseClampedXY (frm)
if x then
local tfrm = self.ThumbFrm
if self.TypeH then
local dx = self.DragX - x
else
local dy = self.DragY - y
local h = (frm:GetTop() or 0) - (frm:GetBottom() or 0)
y = h - y
if dy ~= 0 then
-- h = h - tfrm:GetHeight()
local i = dy / h * (self.Max - self.Min + 1)
self:Set (self.DragPos + i)
self:Update()
if self.UserFunc then
self.UserFunc (self.User, self, self.Pos)
end
-- Nx.prt ("Slider Drag %f %f pos %f", dy, i, self.Pos)
end
end
else
-- self.DragX = nil
end
end
end
function Nx.Slider:Update()
self.NeedUpdate = true
end
--------
-- Update slider
-- self = instance
function Nx.Slider:DoUpdate()
local frm = self.Frm
local tfrm = self.ThumbFrm
local range = self.Max - self.Min + 1
local per = (self.Pos - self.Min) / (max (range - self.VisSz, 1))
-- Nx.prt ("Slider Update per %f", per)
if self.TypeH then
local w = (frm:GetRight() or 0) - (frm:GetLeft() or 0) -- Attached, so GetWidth is wrong
tfrm:SetPoint ("TOPLEFT", per * w, 0)
else
local h = (frm:GetTop() or 0) - (frm:GetBottom() or 0) -- Attached, so GetHeight is wrong
local tper = min (self.VisSz / range, 1)
if tper >= 1 or h < 6 then
self.TPt = 0
frm:SetAlpha (.3)
tfrm:Hide()
else
frm:SetAlpha (1)
tfrm:Show()
local clip = 0
local th = tper * h
if th < 5 then
clip = 5 - th
th = 5
end
-- Nx.prt ("Slider Update tper %f h %f th %f", tper, h, th)
tfrm:SetHeight (th)
h = h - tper * h
self.TPt = -per * h
tfrm:SetPoint ("TOPLEFT", 0, self.TPt)
end
end
end
-------------------------------------------------------------------------------
----------------------------------
-- Create graph
function Nx.Graph:Create (width, height, parentFrm)
local c2rgba = Nx.Util_c2rgba
-- prt ("Graph "..width)
local g = {} -- New graph
g.Clear = self.Clear
g.SetLine = self.SetLine
g.UpdateLine = self.UpdateLine
g.SetPeak = self.SetPeak
g.UpdateFrames = self.UpdateFrames
g.ResetFrames = self.ResetFrames
g.GetFrame = self.GetFrame
local f = CreateFrame ("Frame", nil, parentFrm)
g.MainFrm = f
f.NxGraph = g
f.NxSetSize = self.OnSetSize
f:EnableMouse (true)
f:SetFrameStrata ("MEDIUM")
f:SetWidth (width + 2)
f:SetHeight (height + 2)
f:SetPoint ("TOPLEFT", 0, 0)
local t = f:CreateTexture()
t:SetTexture (c2rgba ("202020a0"))
t:SetAllPoints (f)
f.texture = t
f:Show()
g.Width = width
g.Height = height
g.ScaleX = 8
g.Frms = {}
g:Clear()
local sf = CreateFrame ("Slider", nil, f, "NxSliderFrame")
g.SliderFrm = sf
sf.NxGraph = g
local bd = {
["bgFile"] = "Interface\Buttons\UI-SliderBar-Background",
["edgeFile"] = "Interface\Buttons\UI-SliderBar-Border",
["tile"] = true,
["tileSize"] = 8,
["edgeSize"] = 8,
["insets"] = { ["left"] = 3, ["right"] = 3, ["top"] = 6, ["bottom"] = 6 }}
sf:SetBackdrop (bd)
sf:SetOrientation ("HORIZONTAL")
-- sf:SetThumbTexture ("Interface\Buttons\UI-SliderBar-Button-Horizontal")
sf:SetFrameStrata ("MEDIUM")
sf:SetWidth (100)
sf:SetHeight (10)
sf:ClearAllPoints()
sf:SetPoint ("BOTTOMLEFT", 0, -11)
sf:SetMinMaxValues (1, 25)
sf:SetValueStep (.5)
sf:SetValue (g.ScaleX)
sf:SetScript ("OnValueChanged", Nx.Graph.ScaleSlider_OnValueChanged)
--[[
local st = sf:CreateTexture()
st:SetTexture (c2rgba ("202020ff"))
st:SetAllPoints (sf)
sf.texture = st
--]]
sf:Show()
return g
end
-- Scale slider value changed
-- self = frm
function Nx.Graph:ScaleSlider_OnValueChanged()
self.NxGraph.ScaleX = self:GetValue()
self.NxGraph:UpdateFrames()
-- prt ("Slider "..self.NxGraph.ScaleX)
end
-- Clear graph
-- self = graph
function Nx.Graph:Clear()
-- Clear values
self.Values = {}
self.Values.Next = 1
self.Peak = 1
-- Hide frames
self:ResetFrames()
end
-- Set a graph line
-- self = graph
function Nx.Graph:SetLine (time, value, colorStr, infoStr)
local pos = self.Values.Next
assert (pos ~= 0)
self.Values[-pos] = time
self.Values[pos] = value
self.Values[pos + 0x1000000] = colorStr
self.Values[pos + 0x2000000] = infoStr
self.Values.Next = pos + 1
self:UpdateLine (pos)
end
------
-- Set a graph line
-- self = graph
function Nx.Graph:UpdateLine (pos)
local c2rgb = Nx.Util_c2rgb
assert (pos ~= 0)
local time = self.Values[-pos]
local x = time * self.ScaleX
if x >= 0 and x < self.Width - 1 then
local value = self.Values[pos]
local h = value / self.Peak
if h > 1 or h < 0 then
h = 1
end
h = h * self.Height
if h >= .1 then
h = max (h, 4)
local f = self:GetFrame()
f.NxGraphPos = pos
f:SetHeight (h)
f:SetWidth (self.ScaleX * .25)
f:SetPoint ("BOTTOMLEFT", x, 1)
local colorStr = self.Values[pos + 0x1000000]
f.texture:SetTexture (c2rgb (colorStr))
f:Show()
end
end
end
------
-- Set peak value of graph
-- self = graph
function Nx.Graph:SetPeak (peak)
if peak < 1 then
peak = 1
end
if peak > self.Peak then
-- prt ("Peak: "..peak)
self.Peak = peak
self:UpdateFrames()
end
end
------
-- Update all graph frames
-- self = graph
function Nx.Graph:UpdateFrames()
self:ResetFrames()
for n = 1, self.Values.Next - 1 do
self:UpdateLine (n)
end
end
------
-- Reset frames
-- self = graph
function Nx.Graph:ResetFrames()
local n = 1
local f
while true do
f = self.Frms[n]
if not f then
break
end
f:Hide()
n = n + 1
end
self.Frms.Next = 1
end
------
-- Get next available frame or create one
-- self = graph
function Nx.Graph:GetFrame()
local pos = self.Frms.Next
if pos > 1000 then
pos = 1 -- Reset. Too many used
end
local f = self.Frms[pos]
if not f then
f = CreateFrame ("Frame", nil, self.MainFrm)
self.Frms[pos] = f
f.NxGraph = self
f:SetFrameStrata ("MEDIUM")
local t = f:CreateTexture()
t:SetAllPoints (f)
f.texture = t
f:SetScript ("OnEnter", Nx.Graph.OnEnter)
f:SetScript ("OnLeave", Nx.Graph.OnLeave)
f:EnableMouse (true)
end
self.Frms.Next = pos + 1
return f
end
--------
-- Called when frame size changes
function Nx.Graph:OnSetSize (w, h)
local g = self.NxGraph
if g.Width ~= w or g.Height ~= h then
g.Width = w
g.Height = h
g:UpdateFrames()
end
end
--------
-- Handle mouse on graph line
function Nx.Graph:OnEnter (motion)
local this = self --V4
if not GameTooltip:IsOwned (this) and this.NxGraphPos then
local self = this.NxGraph
Nx.TooltipOwner = this
GameTooltip:SetOwner (this, "ANCHOR_CURSOR")
local v = self.Values
local str = format ("%.2f: %s", v[-this.NxGraphPos], v[this.NxGraphPos + 0x2000000])
-- Nx.prt (str)
GameTooltip:SetText (str)
GameTooltip:Show()
end
end
--------
-- Handle mouse leaving graph line
function Nx.Graph:OnLeave (motion)
--V4 this
if GameTooltip:IsOwned (self) then
GameTooltip:Hide()
end
end
-----------------------------------------------------------------------------
--EOF