389 lines
11 KiB
Lua
389 lines
11 KiB
Lua
|
|
--[[
|
||
|
|
SelectBox
|
||
|
|
Version: 5.9.4961 (WhackyWallaby)
|
||
|
|
Revision: $Id: SelectBox.lua 268 2010-09-02 23:31:55Z kandoko $
|
||
|
|
URL: http://auctioneeraddon.com/dl/
|
||
|
|
|
||
|
|
License:
|
||
|
|
This library is free software; you can redistribute it and/or
|
||
|
|
modify it under the terms of the GNU Lesser General Public
|
||
|
|
License as published by the Free Software Foundation; either
|
||
|
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
|
||
|
|
This library 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
|
||
|
|
Lesser General Public License for more details.
|
||
|
|
|
||
|
|
You should have received a copy of the GNU Lesser General Public
|
||
|
|
License along with this library; if not, write to the Free Software
|
||
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
|
Boston, MA 02110-1301 USA
|
||
|
|
|
||
|
|
Additional:
|
||
|
|
Regardless of any other conditions, you may freely use this code
|
||
|
|
within the World of Warcraft game client.
|
||
|
|
--]]
|
||
|
|
|
||
|
|
local LIBRARY_VERSION_MAJOR = "SelectBox"
|
||
|
|
local LIBRARY_VERSION_MINOR = 4
|
||
|
|
|
||
|
|
do -- LibStub
|
||
|
|
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
|
||
|
|
-- LibStub is hereby placed in the Public Domain
|
||
|
|
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
|
||
|
|
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
|
||
|
|
local LibStub = _G[LIBSTUB_MAJOR]
|
||
|
|
|
||
|
|
-- Check to see is this version of the stub is obsolete
|
||
|
|
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
|
||
|
|
LibStub = LibStub or {libs = {}, minors = {} }
|
||
|
|
_G[LIBSTUB_MAJOR] = LibStub
|
||
|
|
LibStub.minor = LIBSTUB_MINOR
|
||
|
|
|
||
|
|
-- LibStub:NewLibrary(major, minor)
|
||
|
|
-- major (string) - the major version of the library
|
||
|
|
-- minor (string or number ) - the minor version of the library
|
||
|
|
--
|
||
|
|
-- returns nil if a newer or same version of the lib is already present
|
||
|
|
-- returns empty library object or old library object if upgrade is needed
|
||
|
|
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
|
||
|
|
|
||
|
|
-- LibStub:GetLibrary(major, [silent])
|
||
|
|
-- major (string) - the major version of the library
|
||
|
|
-- silent (boolean) - if true, library is optional, silently return nil if its not found
|
||
|
|
--
|
||
|
|
-- throws an error if the library can not be found (except silent is set)
|
||
|
|
-- returns the library object if found
|
||
|
|
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
|
||
|
|
|
||
|
|
-- LibStub:IterateLibraries()
|
||
|
|
--
|
||
|
|
-- Returns an iterator for the currently registered libraries
|
||
|
|
function LibStub:IterateLibraries()
|
||
|
|
return pairs(self.libs)
|
||
|
|
end
|
||
|
|
|
||
|
|
setmetatable(LibStub, { __call = LibStub.GetLibrary })
|
||
|
|
end
|
||
|
|
end -- 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/Configator/SelectBox.lua $","$Rev: 268 $","5.1.DEV.", 'auctioneer', 'libs')
|
||
|
|
|
||
|
|
local NUM_MENU_ITEMS = 15
|
||
|
|
|
||
|
|
local kit = {}
|
||
|
|
local buttonKit = {}
|
||
|
|
|
||
|
|
local keys = {}
|
||
|
|
local values = {}
|
||
|
|
|
||
|
|
function kit:GetItems()
|
||
|
|
for pos in pairs(keys) do keys[pos] = nil end
|
||
|
|
for pos in pairs(values) do values[pos] = nil end
|
||
|
|
|
||
|
|
local curpos
|
||
|
|
local current = self.value
|
||
|
|
|
||
|
|
local items
|
||
|
|
if type(self.items) == "function" then
|
||
|
|
items = self.items()
|
||
|
|
else
|
||
|
|
items = self.items
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not items) then items = {} end
|
||
|
|
|
||
|
|
local key, value
|
||
|
|
for pos, item in ipairs(items) do
|
||
|
|
if type(item) == "table" then
|
||
|
|
key = item[1]
|
||
|
|
value = item[2]
|
||
|
|
else
|
||
|
|
key = item
|
||
|
|
value = item
|
||
|
|
end
|
||
|
|
if (key) then
|
||
|
|
table.insert(keys, key)
|
||
|
|
table.insert(values, value)
|
||
|
|
if (not curpos and type(key)==type(current) and key==current) then
|
||
|
|
curpos = table.getn(keys)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return curpos or 1
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:SetWidth(width)
|
||
|
|
local fname = self:GetName()
|
||
|
|
self:origSetWidth(width + 50)
|
||
|
|
self.curWidth = width
|
||
|
|
_G[fname.."Middle"]:SetWidth(width)
|
||
|
|
_G[fname.."Text"]:SetWidth(width - 25)
|
||
|
|
self:UpdateInset()
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:UpdateInset()
|
||
|
|
local leftInset = -2
|
||
|
|
if not self.hiddenInput then
|
||
|
|
leftInset = 5-self.curWidth
|
||
|
|
end
|
||
|
|
local fname = self:GetName()
|
||
|
|
_G[fname.."Button"]:SetHitRectInsets(leftInset, -2,-2,-2)
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:SetInputHidden(hide)
|
||
|
|
local fname = self:GetName()
|
||
|
|
if hide then
|
||
|
|
self.hiddenInput = true
|
||
|
|
_G[fname.."Left"]:Hide()
|
||
|
|
_G[fname.."Middle"]:Hide()
|
||
|
|
_G[fname.."Right"]:Hide()
|
||
|
|
_G[fname.."Text"]:Hide()
|
||
|
|
else
|
||
|
|
self.hiddenInput = nil
|
||
|
|
_G[fname.."Left"]:Show()
|
||
|
|
_G[fname.."Middle"]:Show()
|
||
|
|
_G[fname.."Right"]:Show()
|
||
|
|
_G[fname.."Text"]:Show()
|
||
|
|
end
|
||
|
|
self:UpdateInset()
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:GetHeight()
|
||
|
|
local minx,miny,width,height = self:GetBoundsRect()
|
||
|
|
return height
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:GetWidth()
|
||
|
|
local minx,miny,width,height = self:GetBoundsRect()
|
||
|
|
return width
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:SetText(text)
|
||
|
|
local fname = self:GetName()
|
||
|
|
_G[fname.."Text"]:SetText(text)
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:UpdateValue()
|
||
|
|
local pos = self:GetItems()
|
||
|
|
self:SetText(values[pos])
|
||
|
|
end
|
||
|
|
|
||
|
|
function kit:OnClose()
|
||
|
|
if (lib.menu.currentBox == self) then
|
||
|
|
lib:DoHide()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
function buttonKit:Open()
|
||
|
|
local box = self
|
||
|
|
if not box.items then box = self:GetParent() end
|
||
|
|
if not box.items then box = this:GetParent() end
|
||
|
|
if not box.items then error("Unable to open menu") end
|
||
|
|
|
||
|
|
PlaySound("igMainMenuOptionCheckBoxOn")
|
||
|
|
lib.menu:ClearAllPoints()
|
||
|
|
lib.menu:SetPoint("TOPLEFT", box, "TOPLEFT", 0, 0)
|
||
|
|
lib.menu:SetWidth(box:GetWidth())
|
||
|
|
|
||
|
|
lib.menu.currentBox = box
|
||
|
|
lib.menu.cp = nil
|
||
|
|
lib.menu.ts = nil
|
||
|
|
lib.menu.position = box:GetItems()
|
||
|
|
lib:DoUpdate()
|
||
|
|
lib:DoShow()
|
||
|
|
end
|
||
|
|
|
||
|
|
function lib:Create(name, parent, width, callback, list, current)
|
||
|
|
local frame = CreateFrame("Frame", name, parent, "SelectBoxTemplate_v1")
|
||
|
|
if (not width) then width = 100 end
|
||
|
|
frame.items = list
|
||
|
|
frame.value = current
|
||
|
|
frame.onsel = callback
|
||
|
|
frame.origSetWidth = frame.SetWidth
|
||
|
|
frame.button = _G[name.."Button"]
|
||
|
|
|
||
|
|
for k,v in pairs(kit) do
|
||
|
|
frame[k] = v
|
||
|
|
end
|
||
|
|
for k,v in pairs(buttonKit) do
|
||
|
|
_G[name.."Button"][k] = v
|
||
|
|
end
|
||
|
|
|
||
|
|
frame:SetWidth(width)
|
||
|
|
return frame
|
||
|
|
end
|
||
|
|
|
||
|
|
function lib:DoUpdate()
|
||
|
|
local key, value, pos, j
|
||
|
|
|
||
|
|
local ts, cp
|
||
|
|
if (lib.menu.cp) then
|
||
|
|
cp = lib.menu.cp
|
||
|
|
ts = lib.menu.ts
|
||
|
|
else
|
||
|
|
ts = table.getn(keys)
|
||
|
|
cp = lib.menu.position
|
||
|
|
cp = math.max(1, math.min(cp-7, ts-10))
|
||
|
|
lib.menu.cp = cp
|
||
|
|
lib.menu.ts = ts
|
||
|
|
end
|
||
|
|
|
||
|
|
j = 0
|
||
|
|
for i = 1, NUM_MENU_ITEMS do
|
||
|
|
pos = cp + i - 1
|
||
|
|
if (i==1 and pos > 1) then
|
||
|
|
j = j + 1
|
||
|
|
lib.menu.buttons[j].index = "prev"
|
||
|
|
lib.menu.buttons[j]:SetText("...")
|
||
|
|
lib.menu.buttons[j]:Show()
|
||
|
|
elseif (i == NUM_MENU_ITEMS and pos < ts) then
|
||
|
|
j = j + 1
|
||
|
|
lib.menu.buttons[j].index = "next"
|
||
|
|
lib.menu.buttons[j]:SetText("...")
|
||
|
|
lib.menu.buttons[j]:Show()
|
||
|
|
else
|
||
|
|
key = keys[pos]
|
||
|
|
value = values[pos]
|
||
|
|
if (key) then
|
||
|
|
j = j + 1
|
||
|
|
lib.menu.buttons[j].index = pos
|
||
|
|
lib.menu.buttons[j]:SetText(value)
|
||
|
|
lib.menu.buttons[j]:Show()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local total = j
|
||
|
|
for i = j+1, NUM_MENU_ITEMS do
|
||
|
|
lib.menu.buttons[i]:SetText("")
|
||
|
|
lib.menu.buttons[i]:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
local height = 50
|
||
|
|
height = max(height, 42 + (total * 12))
|
||
|
|
|
||
|
|
lib.menu:SetHeight(height)
|
||
|
|
end
|
||
|
|
|
||
|
|
function lib:DoShow()
|
||
|
|
lib.menu:SetAlpha(0)
|
||
|
|
lib.menu:Show()
|
||
|
|
UIFrameFadeIn(lib.menu, 0.15, 0, 1)
|
||
|
|
end
|
||
|
|
function lib:DoHide()
|
||
|
|
lib.menu:Hide()
|
||
|
|
end
|
||
|
|
function lib:DoFade()
|
||
|
|
UIFrameFadeOut(lib.menu, 0.25, 1, 0)
|
||
|
|
lib.menu.fadeInfo.finishedFunc = lib.DoHide
|
||
|
|
end
|
||
|
|
|
||
|
|
local scrollTime = 0.2
|
||
|
|
function lib:MouseIn()
|
||
|
|
if (self.index == 'prev') then
|
||
|
|
lib.menu.scrollTimer = scrollTime
|
||
|
|
lib.menu.scrollDir = -1
|
||
|
|
elseif (self.index == 'next') then
|
||
|
|
lib.menu.scrollTimer = scrollTime
|
||
|
|
lib.menu.scrollDir = 1
|
||
|
|
end
|
||
|
|
lib.menu.outTimer = nil
|
||
|
|
end
|
||
|
|
function lib:MouseOut()
|
||
|
|
lib.menu.scrollTimer = nil
|
||
|
|
lib.menu.outTimer = 0.5
|
||
|
|
end
|
||
|
|
function lib:OnUpdate(delay)
|
||
|
|
if (not delay) then return end
|
||
|
|
if (lib.menu.scrollTimer ~= nil) then
|
||
|
|
lib.menu.scrollTimer = lib.menu.scrollTimer - delay
|
||
|
|
if lib.menu.scrollTimer <= 0 then
|
||
|
|
lib.menu.scrollTimer = lib.menu.scrollTimer + scrollTime
|
||
|
|
lib.menu.cp = math.max(1, math.min(lib.menu.ts-9, lib.menu.cp + lib.menu.scrollDir))
|
||
|
|
lib:DoUpdate()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not lib.menu.outTimer) then return end
|
||
|
|
lib.menu.outTimer = lib.menu.outTimer - delay
|
||
|
|
if (lib.menu.outTimer <= 0) then
|
||
|
|
lib.menu.outTimer = nil
|
||
|
|
lib:DoFade()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function lib:OnClick()
|
||
|
|
local pos = self.index
|
||
|
|
if (type(pos) == 'string') then return end
|
||
|
|
lib.menu.currentBox.value = keys[pos] -- the value for setter callback
|
||
|
|
lib.menu.currentBox:SetText(values[pos]) -- the string shown in the UI
|
||
|
|
lib.menu.currentBox:onsel(pos, keys[pos], values[pos])
|
||
|
|
lib:DoHide()
|
||
|
|
end
|
||
|
|
|
||
|
|
if not lib.menu then
|
||
|
|
lib.menu = CreateFrame("Frame", "SelectBoxMenu", UIParent)
|
||
|
|
lib.menu:Hide()
|
||
|
|
lib.menu:SetWidth(120)
|
||
|
|
lib.menu:SetHeight(16 * NUM_MENU_ITEMS + 5)
|
||
|
|
lib.menu:EnableMouse(true)
|
||
|
|
lib.menu:SetFrameStrata("TOOLTIP")
|
||
|
|
lib.menu:SetScript("OnEnter", lib.MouseIn)
|
||
|
|
lib.menu:SetScript("OnLeave", lib.MouseOut)
|
||
|
|
lib.menu:SetScript("OnMouseDown", lib.DoHide)
|
||
|
|
lib.menu:SetScript("OnUpdate", lib.OnUpdate)
|
||
|
|
|
||
|
|
lib.menu.back = CreateFrame("Frame", "", lib.menu)
|
||
|
|
lib.menu.back:SetPoint("TOPLEFT", lib.menu, "TOPLEFT", 15, -20)
|
||
|
|
lib.menu.back:SetPoint("BOTTOMRIGHT", lib.menu, "BOTTOMRIGHT", -15, 10)
|
||
|
|
lib.menu.back:SetBackdrop({
|
||
|
|
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
|
||
|
|
edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
|
||
|
|
tile = true, tileSize = 32, edgeSize = 16,
|
||
|
|
insets = { left = 5, right = 5, top = 5, bottom = 5 }
|
||
|
|
})
|
||
|
|
lib.menu.back:SetBackdropColor(0,0,0, 0.8)
|
||
|
|
lib.menu.buttons = {}
|
||
|
|
for i=1, NUM_MENU_ITEMS do
|
||
|
|
local l = CreateFrame("Button", "SelectBoxMenuButton"..i, lib.menu.back)
|
||
|
|
lib.menu.buttons[i] = l
|
||
|
|
if (i == 1) then
|
||
|
|
l:SetPoint("TOPLEFT", lib.menu.back, "TOPLEFT", 0,-5)
|
||
|
|
else
|
||
|
|
l:SetPoint("TOPLEFT", lib.menu.buttons[i-1], "BOTTOMLEFT", 0,0)
|
||
|
|
end
|
||
|
|
l:SetPoint("RIGHT", lib.menu.back, "RIGHT", 0,0)
|
||
|
|
if ( l.SetTextFontObject ) then l.SetNormalFontObject = l.SetTextFontObject end -- WotLK Hack
|
||
|
|
l:SetNormalFontObject (GameFontHighlightSmall)
|
||
|
|
l:SetHighlightFontObject(GameFontNormalSmall)
|
||
|
|
l:SetHeight(12)
|
||
|
|
l:SetText("Line "..i)
|
||
|
|
l:SetScript("OnEnter", lib.MouseIn)
|
||
|
|
l:SetScript("OnLeave", lib.MouseOut)
|
||
|
|
l:SetScript("OnClick", lib.OnClick)
|
||
|
|
-- _G["SelectBoxMenuButton"..i.."Text"]:SetJustifyH("LEFT")
|
||
|
|
l:Show()
|
||
|
|
end
|
||
|
|
|
||
|
|
cmenu = lib.menu
|
||
|
|
end
|