--------------------------------------------------------------------------------------- -- 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