--[[ Slidebar AddOn for World of Warcraft (tm) Version: 5.9.4961 (WhackyWallaby) Revision: $Id: SlideMain.lua 272 2010-09-19 03:14:25Z kandoko $ URL: http://auctioneeraddon.com/dl/ License: 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 2 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(see GPL.txt); if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Note: This AddOn's source code is specifically designed to work with World of Warcraft's interpreted AddOn system. You have an implicit license to use this AddOn with these facilities since that is its designated purpose as per: http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat ]] local LIBRARY_VERSION_MAJOR = "SlideBar" local LIBRARY_VERSION_MINOR = 10 --[[----------------------------------------------------------------- LibStub is a simple versioning stub meant for use in Libraries. See for more info. LibStub is hereby placed in the Public Domain. Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke --]]----------------------------------------------------------------- do local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 local LibStub = _G[LIBSTUB_MAJOR] if not LibStub or LibStub.minor < LIBSTUB_MINOR then LibStub = LibStub or {libs = {}, minors = {} } _G[LIBSTUB_MAJOR] = LibStub LibStub.minor = LIBSTUB_MINOR function LibStub:NewLibrary(major, minor) assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") local oldminor = self.minors[major] if oldminor and oldminor >= minor then return nil end self.minors[major], self.libs[major] = minor, self.libs[major] or {} return self.libs[major], oldminor end function LibStub:GetLibrary(major, silent) if not self.libs[major] and not silent then error(("Cannot find a library instance of %q."):format(tostring(major)), 2) end return self.libs[major], self.minors[major] end function LibStub:IterateLibraries() return pairs(self.libs) end setmetatable(LibStub, { __call = LibStub.GetLibrary }) end end --[End of LibStub]--------------------------------------------------- local lib = LibStub:NewLibrary(LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR) if not lib then return end LibStub("LibRevision"):Set("$URL: http://svn.norganna.org/libs/trunk/SlideBar/SlideMain.lua $","$Rev: 272 $","5.1.DEV.", 'auctioneer', 'libs') -- Autoconvert existing nSideBar instances to SlideBar if LibStub.libs.nSideBar then for k,v in pairs(LibStub.libs.nSideBar) do lib[k] = v end LibStub.libs.nSideBar = lib LibStub.minors.nSideBar = LIBRARY_VERSION_MINOR end if not lib.private then lib.private = {} end local private = lib.private local frame local ldb = LibStub("LibDataBroker-1.1") --[[ API FUNCTIONS ]]-- -- Return the version of the current bar library function lib.GetVersion() return LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR; end -- Capture the bar and stop it from closing (must release!) function lib.Capture() frame.PopTimer = 0.01 frame.PopDirection = 1 frame.captured = true end -- Release the bar if you have captured it function lib.Release() if not frame.captured then return end frame.PopTimer = 0.75 frame.PopDirection = -1 frame.captured = nil end -- Capture the bar and stop it from closing before object function lib.WaitFor(object) frame.PopTimer = 0.01 frame.PopDirection = 1 frame.captured = object end -- Add a button to the bar, where: -- id = the id for this button (you will use this to reference the button). -- texture = the path to your button's texture. -- priority = determines your button's position in the list (lower numbers = earlier). -- globalname = if specified, sets your button's "frame name". -- quiet = stops nsidebar from popping open to let the user know there's a new button. function lib.AddButton(id, texture, priority, globalname, quiet, dataobj) assert(type(id)=="string", "ButtonId must be a string") local button if not frame.buttons[id] then button = CreateFrame("Button", globalname, frame) button.frame = frame button.dataobj = dataobj button:SetPoint("TOPLEFT", frame, "TOPLEFT", 0,0) button:SetWidth(30) button:SetHeight(30) button:RegisterForClicks("LeftButtonUp","RightButtonUp") button:SetScript("OnMouseDown", function (self, ...) private.MouseDown(self.frame, self, ...) end) button:SetScript("OnMouseUp", function (self, ...) private.MouseUp(self.frame, self, ...) end) button:SetScript("OnEnter", function (self, ...) private.PopOut(self.frame, self, ...) if dataobj and dataobj.OnEnter then dataobj.OnEnter(self) GameTooltip:Hide() end end) --LDB dataobjects can have possible on enter/leave scripts to execute as well button:SetScript("OnLeave", function (self, ...) private.PopBack(self.frame, self, ...) if dataobj and dataobj.OnLeave then dataobj.OnLeave(self) end end) button.icon = button:CreateTexture("", "BACKGROUND") button.icon:SetTexCoord(0.025, 0.975, 0.025, 0.975) button.icon:SetPoint("TOPLEFT", button, "TOPLEFT", 0,0) button.icon:SetWidth(30) button.icon:SetHeight(30) button.id = id frame.buttons[id] = button else button = frame.buttons[id] end if texture then button.icon:SetTexture(texture) end --LDB textures if dataobj then dataobj.button = button if dataobj.OnClick then button:SetScript("OnClick", dataobj.OnClick) end if dataobj.icon then button.icon:SetTexture(dataobj.icon) --check the desaturated method. true if icon starts in a desaturated state if dataobj.iconDesaturated then button.icon:SetDesaturated(true) end end end if priority or not button.priority then button.priority = priority or 200 end button.removed = nil button:Show() if quiet then lib.ApplyLayout() else -- Show people that the button has popped in lib.FlashOpen(1.5) end return button end -- Returns an iterator over the button list (id, button) function lib.IterateButtons() return pairs(frame.buttons) end -- Gets the button with the associated id (if it exists) function lib.GetButton(id) return frame.buttons[id] end -- Removes the button with the associated id from the bar function lib.RemoveButton(id) local button = frame.buttons[id] if not button then return end button:Hide() frame.buttons[id].removed = true lib.ApplyLayout() end -- Causes the button to be displayed (persists across sessions) function lib.ShowButton(id) local button = frame.buttons[id] assert(button, "ButtonId "..id.." does not exist") SlideBarConfig[id..".hide"] = nil lib.ApplyLayout() end -- Causes the button to be hidden (persists across sessions) function lib.HideButton(id) local button = frame.buttons[id] assert(button, "ButtonId "..id.." does not exist") SlideBarConfig[id..".hide"] = 1 lib.ApplyLayout() end -- Causes the bar to flash open for a given number of seconds function lib.FlashOpen(delay) private:PerformOpen() -- Schedule a close in 1.5 seconds frame.PopTimer = delay or 1.5 frame.PopDirection = -1 end -- Updates the bar's buttons and position, where -- useLayout = if set, uses the cached layout, otherwise regenerates it; -- if you hide, show, add or remove buttons, you should regenerate. function lib.ApplyLayout(useLayout) local vis = SlideBarConfig.visibility or "0" local wide = SlideBarConfig.maxWidth or 12 local side = SlideBarConfig.anchor or "right" local position = SlideBarConfig.position or "180" local active = SlideBarConfig.enabled or "1" for k,v in pairs(SlideBarConfig) do if not private.lastConfig[k] or private.lastConfig[k] ~= v then useLayout = false end private.lastConfig[k] = v end position = tonumber(position) or 180 wide = tonumber(wide) side = side:lower() if not active or active == "0" or active == 0 then active = false else active = true end if not active then frame:Hide() return end if not lib.private.layout then lib.private.layout = {} useLayout = false end local layout = lib.private.layout if not useLayout then for i = 1, #layout do table.remove(layout) end for id, button in pairs(frame.buttons) do if not button.removed and not SlideBarConfig[id..".hide"] then table.insert(layout, button) elseif button:IsShown() then button:Hide() end end if (#layout == 0) then frame:Hide() return end table.sort(layout, private.buttonSort) end if (#layout == 0) then frame:Hide() return end local width = wide if (#layout < wide) then width = #layout end local height = math.floor((#layout - 1) / wide) + 1 local distance = 9 if (frame.isOpen) then distance = width * 32 + 10 if (frame:GetAlpha() < 1) then UIFrameFadeIn(frame, 0.25, frame:GetAlpha(), 1) end elseif (vis == "1") then if (frame:GetAlpha() > 0.2) then UIFrameFadeOut(frame, 1.5, frame:GetAlpha(), 0.2) end end frame:ClearAllPoints() if (side == "top") then frame:SetPoint("BOTTOMLEFT", UIParent, "TOPLEFT", position, -1*distance) elseif (side == "bottom") then frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", position, distance) elseif (side == "left") then frame:SetPoint("TOPRIGHT", UIParent, "TOPLEFT", distance, -1*position) elseif (side == "right") then frame:SetPoint("TOPLEFT", UIParent, "TOPRIGHT", -1*distance, -1*position) end if (useLayout) then return end frame.Tab:ClearAllPoints() if (side == "top" or side == "bottom") then frame:SetWidth(height * 32 + 10) frame:SetHeight(width * 32 + 18) if (side == "top") then frame.Tab:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 5, 5) frame.Tab:SetPoint("RIGHT", frame, "RIGHT", -5, 0) else frame.Tab:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -5) frame.Tab:SetPoint("RIGHT", frame, "RIGHT", -5, 0) end frame.Tab:SetHeight(3) else frame:SetWidth(width * 32 + 18) frame:SetHeight(height * 32 + 10) if (side == "right") then frame.Tab:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -5) frame.Tab:SetPoint("BOTTOM", frame, "BOTTOM", 0, 5) else frame.Tab:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -5, -5) frame.Tab:SetPoint("BOTTOM", frame, "BOTTOM", 0, 5) end frame.Tab:SetWidth(3) end frame:Show() local button for pos = 1, #layout do button = layout[pos] pos = pos - 1 local row = math.floor(pos / wide) local col = pos % wide if (row == 0) then width = col end button:ClearAllPoints() if (side == "right") then button:SetPoint("TOPLEFT", frame, "TOPLEFT", col*32+10, 0-(row*32+5)) elseif (side == "left") then button:SetPoint("TOPLEFT", frame, "TOPLEFT", col*32+10, 0-(row*32+5)) elseif (side == "bottom") then button:SetPoint("TOPLEFT", frame, "TOPLEFT", row*32+5, 0-(col*32+10)) elseif (side == "top") then button:SetPoint("TOPLEFT", frame, "TOPLEFT", row*32+5, 0-(col*32+10)) end if not button:IsShown() then button:Show() end end end --[[ END OF API FUNCTIONS ]]-- -- Private functions and variables follow, you shouldn't need to fiddle with these. -- Setup our main frame (or reuse the old one) if lib.frame then frame = lib.frame else frame = CreateFrame("Frame", "", UIParent) frame:SetToplevel(true) --frame:SetClampedToScreen(true) frame:SetFrameStrata("TOOLTIP") frame:SetHitRectInsets(-3, -3, -3, -3) frame:SetBackdrop({ bgFile = "Interface/Tooltips/UI-Tooltip-Background", edgeFile = "Interface/Tooltips/UI-Tooltip-Border", tile = true, tileSize = 32, edgeSize = 16, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) frame:SetBackdropColor(0,0,0, 0.5) frame:EnableMouse(true) frame:SetScript("OnEnter", function(...) private.PopOut(...) end) frame:SetScript("OnLeave", function(...) private.PopBack(...) end) frame:SetScript("OnMouseDown", function(...) private.BeginMove(...) end) frame:SetScript("OnMouseUp", function(...) private.EndMove(...) end) frame:SetScript("OnUpdate", function(...) private.Popper(...) end) frame:SetScript("OnEvent", function(self, event, arg, ...) if event == "PLAYER_LOGIN" then private.startCounter = 10 private.GUI() --create the configuration GUI private.RescanLDBObjects() --scan LibDataBroker objects for any additions or changes. frame:UnregisterEvent("PLAYER_LOGIN") elseif event == "ADDON_LOADED" and arg == "SlideBar" then --removed the needlessly complex string variable system. Were not using Cvar or embeded anymore if not SlideBarConfig or type(SlideBarConfig) == "string" then SlideBarConfig = {} end frame:UnregisterEvent("ADDON_LOADED") end end) frame:RegisterEvent("PLAYER_LOGIN") frame:RegisterEvent("ADDON_LOADED") frame.Tab = frame:CreateTexture() frame.Tab:SetTexture(0.98, 0.78, 0) frame.buttons = {} SLASH_NSIDEBAR1 = "/sbar" SLASH_NSIDEBAR2 = "/slidebar" SLASH_NSIDEBAR3 = "/nsb" SlashCmdList["NSIDEBAR"] = function(msg) private.CommandHandler(msg) end lib.frame = frame end -- Create a special tooltip just for us if not lib.tooltip then lib.tooltip = CreateFrame("GameTooltip", "SlidebarTooltip", UIParent, "GameTooltipTemplate") local function hide_tip() lib.tooltip:Hide() end lib.tooltip.fadeInfo = {} function lib:SetTip(frame, ...) local n = select("#", ...) if n == 1 then -- Allow passing of tip lines as a single table local tip = select(1, ...) if type(tip) == "table" then lib:SetTip(frame, unpack(tip)) return end end if not frame or n == 0 then lib.tooltip.fadeInfo.finishedFunc = hide_tip local curAlpha = lib.tooltip:GetAlpha() UIFrameFadeOut(lib.tooltip, 0.25, curAlpha, 0) lib.tooltip:SetAlpha(curAlpha) lib.tooltip.schedule = nil return end if lib.tooltip:GetAlpha() > 0 then -- Speed up this fade UIFrameFadeOut(lib.tooltip, 0.01, 0, 0) lib.tooltip:SetAlpha(0) end lib.tooltip:SetOwner(frame, "ANCHOR_NONE") lib.tooltip:ClearLines() local tip for i=1, n do tip = select(i, ...) tip = tostring(tip):gsub("{{", "|cff1fb3ff"):gsub("}}", "|r") lib.tooltip:AddLine(tostring(tip) or "", 1,1,0.5, 1) end lib.tooltip:Show() lib.tooltip:SetAlpha(0) lib.tooltip:SetBackdropColor(0,0,0, 1) --corrects tooltip overlaps local _, _, _, X, Y = frame:GetPoint("BOTTOM") --Offset of button local side = SlideBarConfig.anchor or "right" if side == "right" or side == "left" then lib.tooltip:SetPoint("TOP", frame.frame, "BOTTOMLEFT", X + 10, -5) else lib.tooltip:SetPoint("LEFT", frame.frame, "TOPRIGHT", 0, Y + -10) end lib.tooltip.schedule = GetTime() + 1 end lib.tooltip:SetScript("OnUpdate", function() if lib.tooltip.schedule and GetTime() > lib.tooltip.schedule then local curAlpha = lib.tooltip:GetAlpha() UIFrameFadeIn(lib.tooltip, 0.33, curAlpha, 1) lib.tooltip:SetAlpha(curAlpha) -- Tooltips set alpha when they are shown, and UIFrameFadeIn does a :Show() lib.tooltip.schedule = nil end end) lib.tooltip:SetBackdrop({ bgFile = "Interface/Tooltips/UI-Tooltip-Background", edgeFile = "Interface/Tooltips/UI-Tooltip-Border", tile = true, tileSize = 32, edgeSize = 16, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) lib.tooltip:SetBackdropColor(0,0,0.3, 1) --lib.tooltip:SetClampedToScreen(true) --no easy way to make our old and LDB tooltips play togather so created a new function function lib:SetTipLDB(frame, ...) if not frame then lib.tooltip.fadeInfo.finishedFunc = hide_tip local curAlpha = lib.tooltip:GetAlpha() UIFrameFadeOut(lib.tooltip, 0.25, curAlpha, 0) lib.tooltip:SetAlpha(curAlpha) lib.tooltip.schedule = nil return end if not frame.dataobj then return end if lib.tooltip:GetAlpha() > 0 then -- Speed up this fade UIFrameFadeOut(lib.tooltip, 0.01, 0, 0) lib.tooltip:SetAlpha(0) end lib.tooltip:SetOwner(frame, "ANCHOR_NONE") lib.tooltip:ClearLines() if not frame.dataobj.OnTooltipShow then --fake TT lib.tooltip:AddLine(frame.dataobj.name) else frame.dataobj.OnTooltipShow(lib.tooltip) end lib.tooltip:Show() lib.tooltip:SetAlpha(0) lib.tooltip:SetBackdropColor(0,0,0, 1) local _, _, _, X, Y = frame:GetPoint("BOTTOM") --Offset of button local side = SlideBarConfig.anchor or "right" if side == "right" or side == "left" then lib.tooltip:SetPoint("TOP", frame.frame, "BOTTOMLEFT", X + 10, -5) else lib.tooltip:SetPoint("LEFT", frame.frame, "TOPRIGHT", 0, Y + -10) end lib.tooltip.schedule = GetTime() + .25 -- reduced show delay to .25 from 1 this is nicer IMO that "lag" like 1 sec delay end end private.lastConfig = {} -- Functions to start and stop the sidebar drag function private:BeginMove(...) if SlideBarConfig.locked == "1" then return end local button = ... if button == "LeftButton" then private.moving = true end end function private:EndMove(...) if private.moving then private.moving = nil end end -- Checks to see if the argument is a button function private.IsButton(button) if not button then return end if type(button) ~= "table" then return end if button.id and button.icon then return true end end -- Functions to control the popping in and out of the bar function private:PopOut(...) local button = ... self.PopTimer = 0.15 self.PopDirection = 1 if private.IsButton(button) then -- this is a button button.icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) if (button.tip) then lib:SetTip(button, button.tip) else lib:SetTipLDB(button) --LDB buttons use this tip method end if button.OnEnter then button:OnEnter(select(2, ...)) end end end function private:PopBack(...) local button = ... self.PopTimer = 0.75 self.PopDirection = -1 if private.IsButton(button) then -- this is a button lib:SetTip() button.icon:SetTexCoord(0.025, 0.975, 0.025, 0.975) if button.OnLeave then button:OnLeave(select(2, ...)) end end end function private:PerformOpen(useLayout) -- Pop Out frame.PopDirection = nil frame:ClearAllPoints() frame.isOpen = true lib.ApplyLayout(useLayout) for _,button in ipairs(frame.buttons) do if button.OnOpen then button:OnOpen() end end end function private:PerformClose(useLayout) -- Pop Back frame.PopDirection = nil frame:ClearAllPoints() frame.isOpen = false lib.ApplyLayout(useLayout) for _,button in ipairs(frame.buttons) do if button.OnOpen then button:OnClose() end end end function private:Popper(...) local duration = ... if private.moving then local side, pos = private.boxMover() SlideBarConfig.anchor = side SlideBarConfig.position = pos lib.ApplyLayout(true) return end if self.PopDirection then self.PopTimer = self.PopTimer - duration if self.PopTimer < 0 then if self.PopDirection > 0 then private:PerformOpen(true) else if frame.captured and type(frame.captured) == "table" and frame.captured:IsShown() then frame.captured = nil end if not frame.captured then private:PerformClose(true) end end end end if private.startCounter then private.startCounter = private.startCounter - 1 if private.startCounter == 0 then lib.FlashOpen(5) private.startCounter = nil end end end -- Functions to make the icon enlarge/shrink when the mouse moves over it function private:MouseDown(...) local button = ... if button then button.icon:SetTexCoord(0, 1, 0, 1) end if self.MouseDown then self:MouseDown(...) end end function private:MouseUp(...) local button = ... if button then button.icon:SetTexCoord(0.025, 0.975, 0.025, 0.975) end if self.MouseUp then self:MouseUp(...) end end -- Command processor function private.CommandHandler(msg) local vis = SlideBarConfig.visibility or "0" local wide = SlideBarConfig.maxWidth or 12 local side = SlideBarConfig.anchor or "right" local position = SlideBarConfig.position or "180" local active = SlideBarConfig.enabled or "1" if not active or active=="0" or active=="" then active = false else active = true end local save = false if (not msg or msg == "") then msg = "help" end local a, b, c = strsplit(" ", msg:lower()) if (a == "help") then DEFAULT_CHAT_FRAME:AddMessage("/nsb top | left | bottom | right |cff1020ff Set the anchor for the sidebar |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb config |cff1020ff Display the GUI to show or hide buttons|r") DEFAULT_CHAT_FRAME:AddMessage("/nsb |cff1020ff Set the position for the sidebar |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb fadeout | nofade |cff1020ff Set whether the sidebar fades or not |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb size |cff1020ff Set the number of icons before the bar wraps |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb lock | unlock |cff1020ff enab |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb reset |cff1020ff Reset the bar to factory defaults |r") DEFAULT_CHAT_FRAME:AddMessage("/nsb off | on | toggle |cff1020ff Disable/Enable/Toggle bar's visibility |r") return end if a == "lock" then SlideBarConfig.locked = "1" save = true elseif a == "unlock" then SlideBarConfig.locked = "0" save = true end if a == "reset" then SlideBarConfig = {} save = true end if (a == "top") or (a == "left") or (a == "bottom") or (a == "right") then SlideBarConfig.anchor = a save = true if (tonumber(b)) then a, b, c = b, nil, nil end end if (tonumber(a)) then SlideBarConfig.position = math.min(math.abs(tonumber(a)), 1200) save = true end if (a == "fadeout" or a == "fade") then SlideBarConfig.visibility = "1" save = true elseif (a == "nofade") then SlideBarConfig.visibility = "0" save = true end if (a == "size") then if (tonumber(b)) then wide = math.floor(tonumber(b)) if (wide < 1) then wide = 1 end SlideBarConfig.maxWidth = wide save = true end end if (a == "on") then SlideBarConfig.enabled = "1" save = true elseif (a == "off") then SlideBarConfig.enabled = "0" save = true elseif (a == "toggle") then if active then SlideBarConfig.enabled = "0" else SlideBarConfig.enabled = "1" end save = true end if (a == "config") then InterfaceOptionsFrame_OpenToCategory(frame.config) end if (save) then lib.ApplyLayout() end end -- Function to sort the buttons by priority during the layout phase function private.buttonSort(a, b) if (a.priority ~= b.priority) then return a.priority < b.priority end return a.id < b.id end -- Function to work out where along the edge of the screen to position the bar local SWITCH_TEXELS = 100 -- number of texels to do edge switches at function private.boxMover() local curX, curY = GetCursorPosition() local uiScale = UIParent:GetEffectiveScale() local uiWidth, uiHeight = UIParent:GetWidth(), UIParent:GetHeight() curX, curY = curX / uiScale, curY / uiScale local anchor = SlideBarConfig.anchor or "right" if anchor == "top" and curY < uiHeight - SWITCH_TEXELS or anchor == "bottom" and curY > SWITCH_TEXELS then if curX < SWITCH_TEXELS then anchor = "left" elseif curX > uiWidth - SWITCH_TEXELS then anchor = "right" end elseif anchor == "left" and curX > SWITCH_TEXELS or anchor == "right" and curX < uiWidth - SWITCH_TEXELS then if curY < SWITCH_TEXELS then anchor = "bottom" elseif curY > uiHeight - SWITCH_TEXELS then anchor = "top" end end local pos if anchor == "top" or anchor == "bottom" then pos = curX else pos = uiHeight - curY end return anchor, pos - 16 end --[[Use Blizzards config frame. We do not use the Configator lib]] function private.GUI() if frame.config then return end frame.config = CreateFrame("Frame", nil, UIParent) frame.config:SetWidth(420) frame.config:SetHeight(400) frame.config:SetToplevel(true) frame.config:Hide() frame.config.name = "Norganna SlideBar" --add to Blizzards addon configuration menu InterfaceOptions_AddCategory(frame.config) frame.config.help = frame.config:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") frame.config.help:SetText("Click on a button above to Show or Hide it from the Slidebar addon") frame.config.help:SetPoint("TOPLEFT", frame.config,"LEFT" , 15, 150) frame.config.help:SetPoint("BOTTOMRIGHT", frame.config,"BOTTOMRIGHT" , -15, 0) frame.config.enableCheck = CreateFrame("CheckButton", "nSlideBarenableCheck", frame.config, "InterfaceOptionsCheckButtonTemplate") nSlideBarenableCheckText:SetText("Enable SlideBar") frame.config.enableCheck:SetPoint("LEFT", frame.config, "LEFT", 10, -80) frame.config.enableCheck:SetChecked(SlideBarConfig.enabled or "1") function frame.config.enableCheck.setFunc(state) SlideBarConfig.enabled = state lib.ApplyLayout() end frame.config.searchBox = CreateFrame("EditBox", "nSlideBarLengthEditBox", frame.config, "InputBoxTemplate") --has to have a name or the template bugs frame.config.searchBox:SetMaxLetters(2) frame.config.searchBox:SetNumeric(true) local wide = SlideBarConfig.maxWidth or 12 frame.config.searchBox:SetNumber(wide) frame.config.searchBox:SetAutoFocus(false) frame.config.searchBox:SetPoint("TOP", frame.config.enableCheck, "BOTTOM", 40,-10) frame.config.searchBox:SetWidth(22) frame.config.searchBox:SetHeight(15) frame.config.searchBox:SetScript("OnEnterPressed", function(self) EditBox_ClearFocus(self) local wide = self:GetNumber() if (wide < 1) then wide = 1 end SlideBarConfig.maxWidth = wide lib.ApplyLayout() lib.FlashOpen(5) end) frame.config.searchBox.help = frame.config:CreateFontString(nil, "OVERLAY", "GameFontNormal") frame.config.searchBox.help:SetPoint("LEFT", frame.config.searchBox, "RIGHT", 5, 0) frame.config.searchBox.help:SetText("Number of buttons before a new row is started.") frame.config.lockCheck = CreateFrame("CheckButton", "nSlideBarlockCheck", frame.config, "InterfaceOptionsCheckButtonTemplate") nSlideBarlockCheckText:SetText("Lock the Bar's location") frame.config.lockCheck:SetPoint("TOP", frame.config.searchBox, "BOTTOM", 0, -10) function frame.config.lockCheck.setFunc(state) SlideBarConfig.locked = state lib.ApplyLayout() end frame.config.lockCheck:SetChecked(SlideBarConfig.locked) frame.config.fadeCheck = CreateFrame("CheckButton", "nSlideBarfadeCheck", frame.config, "InterfaceOptionsCheckButtonTemplate") nSlideBarfadeCheckText:SetText("Fade the slidebar when not in use.") frame.config.fadeCheck:SetPoint("TOP",frame.config.lockCheck, "BOTTOM") function frame.config.fadeCheck.setFunc(state) SlideBarConfig.visibility = state lib.ApplyLayout() end frame.config.fadeCheck:SetChecked(SlideBarConfig.visibility) frame.config.reset = CreateFrame("Button", nil, frame.config, "OptionsButtonTemplate") frame.config.reset:SetWidth(160) frame.config.reset:SetPoint("TOPLEFT",frame.config.fadeCheck, "BOTTOM", -50,-5) frame.config.reset:SetText("RESET ALL SETTINGS") frame.config.reset:SetScript("OnClick", function() SlideBarConfig = {} lib.ApplyLayout() end) frame.config.buttons = {} function private.createIconGUI() local pos = #frame.config.buttons + 1 local button = CreateFrame("Button", nil, frame.config, "PopupButtonTemplate") button:SetScript("OnClick", function(self) lib.FlashOpen(5) if self:GetNormalTexture():IsDesaturated() then self:GetNormalTexture():SetDesaturated(false) self.tex:Hide() lib.ShowButton(self.name) elseif self:GetNormalTexture() then self:GetNormalTexture():SetDesaturated(true) self.tex:Show() lib.HideButton(self.name) end end) button.pos = pos button:SetScale(.8) --should we use a X texture button.tex = button:CreateTexture() button.tex:SetTexture("Interface\\WorldMap\\X_Mark_64") button.tex:SetPoint("TOPLEFT", button, "TOPLEFT",-5,5) button.tex:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -20, 10) button.tex:SetTexCoord(0,0.5,0.5,1) button.tex:SetDrawLayer("OVERLAY") button.tex:Hide() frame.config.buttons[pos] = button return button end --Was gonna make this dynamic depending on how user resized window. Decided on static for now do for pos = 1, 50 do private.createIconGUI() end local width = frame.config:GetWidth() local height = frame.config:GetHeight() local spacer = 5 local row = 0 local column = 0 local total = 0 local button = frame.config.buttons --create 50 slots for our button icons for pos = 1, #button do if total + 45 > width then column = 0 row = row + 45 + spacer total = 0 end --button[pos]:ClearAllPoints() if column == 0 then button[pos]:SetPoint("TOPLEFT", frame.config, "TOPLEFT", column+20, -row - 20) else button[pos]:SetPoint("TOPLEFT", button[pos-1], "TOPLEFT", 45 + spacer, 0) end column = column + 36 + spacer total = total + 36 + spacer end end --apply GUI layout to match slidebars button order --Blizzards frame calls this when options are opened function frame.config.refresh() local layout = {} for id, button in pairs(frame.buttons) do table.insert(layout, button) end table.sort(layout, private.buttonSort) local GUI = frame.config.buttons for pos = 1, #GUI do local button = layout[pos] if button then if GUI[pos] and button.icon then GUI[pos]:Enable() GUI[pos]:SetNormalTexture(button.icon:GetTexture()) GUI[pos].name = button.id if SlideBarConfig[button.id..".hide"] then GUI[pos]:GetNormalTexture():SetDesaturated(true) if GUI[pos].tex then GUI[pos].tex:Hide() end end else GUI[pos]:Disable() end else GUI[pos]:Disable() end end end --[[LibDataBroker setup Functions]] --core function adds LDB objects to our bar function private:LibDataBroker_DataObjectCreated(event, name, dataobj) if not name or not dataobj or not dataobj.type then return end if dataobj.type == "launcher" then lib.AddButton(name, nil, nil, nil, nil, dataobj) end end ldb.RegisterCallback(private, "LibDataBroker_DataObjectCreated") --add any LDB objects created before we loaded. Not all LDB objects initialize everything when they create themselves. So we need to recan after all are loded to get all methods function private.RescanLDBObjects() for name, dataobj in ldb:DataObjectIterator() do private:LibDataBroker_DataObjectCreated(nil, name, dataobj) end end end --[[not used atm. Will allow buttons to me dragged when we add user ordering to the button layout function private.dragButton(event, self) if event == "start" then frame.config.start = self else --switch textures local tex1 = frame.config.start:GetNormalTexture():GetTexture() --gets texture ref then texture path :GetNormalTexture():GetTexture() local tex2 = self:GetNormalTexture():GetTexture() self:SetNormalTexture(tex1) frame.config.start:SetNormalTexture(tex2) end end]]