WoWInterface SVN RecapFu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk/FuBar_RecapFu/libs/Dewdrop-2.0
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

Dewdrop-2.0.lua
1,6 → 1,6
--[[
--[[
Name: Dewdrop-2.0
Revision: $Rev: 30385 $
Revision: $Rev: 320 $
Author(s): ckknight (ckknight@gmail.com)
Website: http://ckknight.wowinterface.com/
Documentation: http://wiki.wowace.com/index.php/Dewdrop-2.0
11,17 → 11,20
]]
 
local MAJOR_VERSION = "Dewdrop-2.0"
local MINOR_VERSION = "$Revision: 30385 $"
local MINOR_VERSION = tonumber(strmatch("$Revision: 320 $", "%d+")) + 90000
 
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
 
local Dewdrop = {}
 
local SharedMedia
 
local CLOSE = "Close"
local CLOSE_DESC = "Close the menu."
local VALIDATION_ERROR = "Validation error."
local USAGE_TOOLTIP = "Usage: %s."
local RANGE_TOOLTIP = "Note that you can scroll your mouse wheel while over the slider to step by one."
local RESET_KEYBINDING_DESC = "Hit escape to clear the keybinding."
local KEY_BUTTON1 = "Left Mouse"
local KEY_BUTTON2 = "Right Mouse"
32,23 → 35,79
CLOSE = "Schlie\195\159en"
CLOSE_DESC = "Men\195\188 schlie\195\159en."
VALIDATION_ERROR = "Validierungsfehler."
USAGE_TOOLTIP = "Benutzung: %s."
RANGE_TOOLTIP = "Beachte das du mit dem Mausrad scrollen kannst solange du mit dem Mauszeiger \195\188ber dem Schieberegler bist, um feinere Spr\195\188nge zu machen."
RESET_KEYBINDING_DESC = "Escape dr\195\188cken, um die Tastenbelegung zu l\195\182schen."
KEY_BUTTON1 = "Linke Maustaste"
KEY_BUTTON2 = "Rechte Maustaste"
DISABLED = "Deaktiviert"
DEFAULT_CONFIRM_MESSAGE = "Bist du sicher das du `%s' machen willst?"
elseif GetLocale() == "koKR" then
CLOSE = "닫기"
CLOSE_DESC = "메뉴를 닫습니다."
VALIDATION_ERROR = "오류 확인."
USAGE_TOOLTIP = "사용법: %s."
RANGE_TOOLTIP = "알림 : 슬라이더 위에서 마우스 휠을 사용하면 한단계씩 조절할 수 있습니다."
RESET_KEYBINDING_DESC = "단축키를 해제하려면 ESC키를 누르세요."
KEY_BUTTON1 = "왼쪽 마우스"
KEY_BUTTON2 = "오른쪽 마우스"
DISABLED = "비활성화됨"
DEFAULT_CONFIRM_MESSAGE = "정말로 `%s' 실행을 하시겠습니까 ?"
elseif GetLocale() == "frFR" then
CLOSE = "Fermer"
CLOSE_DESC = "Ferme le menu."
VALIDATION_ERROR = "Erreur de validation."
USAGE_TOOLTIP = "Utilisation : %s."
RANGE_TOOLTIP = "Vous pouvez aussi utiliser la molette de la souris pour pour modifier progressivement."
RESET_KEYBINDING_DESC = "Appuyez sur la touche Echappement pour effacer le raccourci."
KEY_BUTTON1 = "Clic gauche"
KEY_BUTTON2 = "Clic droit"
DISABLED = "D\195\169sactiv\195\169"
DEFAULT_CONFIRM_MESSAGE = "\195\138tes-vous s\195\187r de vouloir effectuer '%s' ?"
elseif GetLocale() == "esES" then
CLOSE = "Cerrar"
CLOSE_DESC = "Cierra el men\195\186."
VALIDATION_ERROR = "Error de validaci\195\179n"
RESET_KEYBINDING_DESC = "Pulsa Escape para limpiar la asignaci\195\179n de tecla."
CLOSE_DESC = "Cierra el menú."
VALIDATION_ERROR = "Error de validación."
USAGE_TOOLTIP = "Uso: %s."
RANGE_TOOLTIP = "Puedes desplazarte verticalmente con la rueda del ratón sobre el desplazador."
RESET_KEYBINDING_DESC = "Pulsa Escape para borrar la asignación de tecla."
KEY_BUTTON1 = "Clic Izquierdo"
KEY_BUTTON2 = "Clic Derecho"
DISABLED = "Desactivado"
DEFAULT_CONFIRM_MESSAGE = "¿Estás seguro de querer realizar `%s'?"
elseif GetLocale() == "zhTW" then
CLOSE = "關閉"
CLOSE_DESC = "關閉選單。"
VALIDATION_ERROR = "驗證錯誤。"
USAGE_TOOLTIP = "用法: %s。"
RANGE_TOOLTIP = "你可以在捲動條上使用滑鼠滾輪來捲動。"
RESET_KEYBINDING_DESC = "按Esc鍵清除快捷鍵。"
KEY_BUTTON1 = "滑鼠左鍵"
KEY_BUTTON2 = "滑鼠右鍵"
DISABLED = "停用"
DEFAULT_CONFIRM_MESSAGE = "是否執行「%s」?"
elseif GetLocale() == "zhCN" then
CLOSE = "关闭"
CLOSE_DESC = "关闭菜单"
VALIDATION_ERROR = "验证错误."
USAGE_TOOLTIP = "用法: %s."
RANGE_TOOLTIP = "你可以在滚动条上使用鼠标滚轮来翻页."
RESET_KEYBINDING_DESC = "按ESC键清除按键绑定"
KEY_BUTTON1 = "鼠标左键"
KEY_BUTTON2 = "鼠标右键"
DISABLED = "禁用"
DEFAULT_CONFIRM_MESSAGE = "是否执行'%s'?"
elseif GetLocale() == "ruRU" then
CLOSE = "Закрыть"
CLOSE_DESC = "Закрыть меню."
VALIDATION_ERROR = "Ошибка проверки данных."
USAGE_TOOLTIP = "Используйте: %s."
RANGE_TOOLTIP = "Используйте колесо мыши для прокрутки ползунка."
RESET_KEYBINDING_DESC = "Нажмите клавишу Escape для очистки клавиши."
KEY_BUTTON1 = "ЛКМ"
KEY_BUTTON2 = "ПКМ"
DISABLED = "Отключено"
DEFAULT_CONFIRM_MESSAGE = "Вы уверены что вы хотите выполнять `%s'?"
end
 
Dewdrop.KEY_BUTTON1 = KEY_BUTTON1
106,6 → 165,125
local levels
local buttons
 
 
-- Secure frame handling:
-- Rather than using secure buttons in the menu (has problems), we have one
-- master secureframe that we pop onto menu items on mouseover. This requires
-- some dark magic with OnLeave etc, but it's not too bad.
 
local secureFrame = CreateFrame("Button", nil, nil, "SecureActionButtonTemplate")
secureFrame:Hide()
 
local function secureFrame_Show(self)
local owner = self.owner
 
if self.secure then -- Leftovers from previos owner, clean up! ("Shouldn't" happen but does..)
for k,v in pairs(self.secure) do
self:SetAttribute(k, nil)
end
end
self.secure = owner.secure; -- Grab hold of new secure data
 
local scale = owner:GetEffectiveScale()
 
self:SetPoint("TOPLEFT", nil, "BOTTOMLEFT", owner:GetLeft() * scale, owner:GetTop() * scale)
self:SetPoint("BOTTOMRIGHT", nil, "BOTTOMLEFT", owner:GetRight() * scale, owner:GetBottom() * scale)
self:EnableMouse(true)
for k,v in pairs(self.secure) do
self:SetAttribute(k, v)
end
 
secureFrame:SetFrameStrata(owner:GetFrameStrata())
secureFrame:SetFrameLevel(owner:GetFrameLevel()+1)
 
self:Show()
end
 
local function secureFrame_Hide(self)
self:Hide()
if self.secure then
for k,v in pairs(self.secure) do
self:SetAttribute(k, nil)
end
end
self.secure = nil
end
 
secureFrame:SetScript("OnEvent",
function()
if event=="PLAYER_REGEN_ENABLED" then
this.combat = false
if not this:IsShown() and this.owner then
secureFrame_Show(this)
end
elseif event=="PLAYER_REGEN_DISABLED" then
this.combat = true
if this:IsShown() then
secureFrame_Hide(this)
end
end
end
)
secureFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
secureFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
 
secureFrame:SetScript("OnLeave",
function()
local owner=this.owner
this:Deactivate()
owner:GetScript("OnLeave")()
end
)
 
secureFrame:HookScript("OnClick",
function()
local realthis = this
this = this.owner
this:GetScript("OnClick")()
end
)
 
function secureFrame:IsOwnedBy(frame)
return self.owner == frame
end
 
function secureFrame:Activate(owner)
if self.owner then -- "Shouldn't" happen but apparently it does and I cba to troubleshoot...
if not self.combat then
secureFrame_Hide(self)
end
end
self.owner = owner
if not self.combat then
secureFrame_Show(self)
end
end
 
function secureFrame:Deactivate()
if not self.combat then
secureFrame_Hide(self)
end
self.owner = nil
end
 
-- END secure frame utilities
 
 
-- Underline on mouseover - use a single global underline that we move around, no point in creating lots of copies
local underlineFrame = CreateFrame("Frame", nil)
underlineFrame.tx = underlineFrame:CreateTexture()
underlineFrame.tx:SetTexture(1,1,0.5,0.75)
underlineFrame:SetScript("OnHide", function(this) this:Hide(); end)
underlineFrame:SetScript("OnShow", function(this) -- change sizing on the fly to catch runtime uiscale changes
underlineFrame.tx:SetPoint("TOPLEFT", -1, -2/this:GetEffectiveScale())
underlineFrame.tx:SetPoint("RIGHT", 1,0)
underlineFrame.tx:SetHeight(0.6 / this:GetEffectiveScale());
end)
underlineFrame:SetHeight(1)
 
-- END underline on mouseover
 
 
local function GetScaledCursorPosition()
local x, y = GetCursorPosition()
local scale = UIParent:GetEffectiveScale()
183,17 → 361,21
level:SetWidth(width + 20)
if level:GetLeft() and level:GetRight() and level:GetTop() and level:GetBottom() and (level:GetLeft() < 0 or level:GetRight() > GetScreenWidth() or level:GetTop() > GetScreenHeight() or level:GetBottom() < 0) then
level:ClearAllPoints()
local parent = level.parent or level:GetParent()
if type(parent) ~= "table" then
parent = UIParent
end
if level.lastDirection == "RIGHT" then
if level.lastVDirection == "DOWN" then
level:SetPoint("TOPLEFT", level.parent or level:GetParent(), "TOPRIGHT", 5, 10)
level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
else
level:SetPoint("BOTTOMLEFT", level.parent or level:GetParent(), "BOTTOMRIGHT", 5, -10)
level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
end
else
if level.lastVDirection == "DOWN" then
level:SetPoint("TOPRIGHT", level.parent or level:GetParent(), "TOPLEFT", -5, 10)
level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
else
level:SetPoint("BOTTOMRIGHT", level.parent or level:GetParent(), "BOTTOMLEFT", -5, -10)
level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
end
end
end
218,17 → 400,21
end
if dirty then
level:ClearAllPoints()
local parent = level.parent or level:GetParent()
if type(parent) ~= "table" then
parent = UIParent
end
if level.lastDirection == "RIGHT" then
if level.lastVDirection == "DOWN" then
level:SetPoint("TOPLEFT", level.parent or level:GetParent(), "TOPRIGHT", 5, 10)
level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
else
level:SetPoint("BOTTOMLEFT", level.parent or level:GetParent(), "BOTTOMRIGHT", 5, -10)
level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
end
else
if level.lastVDirection == "DOWN" then
level:SetPoint("TOPRIGHT", level.parent or level:GetParent(), "TOPLEFT", -5, 10)
level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
else
level:SetPoint("BOTTOMRIGHT", level.parent or level:GetParent(), "BOTTOMLEFT", -5, -10)
level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
end
end
end
313,17 → 499,34
local sliderFrame
local editBoxFrame
 
local normalFont
local lastSetFont
local justSetFont = false
local regionTmp = {}
local function fillRegionTmp(...)
for i = 1, select('#', ...) do
regionTmp[i] = select(i, ...)
end
end
 
local function showGameTooltip(this)
if this.tooltipTitle or this.tooltipText then
GameTooltip_SetDefaultAnchor(GameTooltip, this)
local disabled = not this.isTitle and this.disabled
local font
if this.tooltipTitle then
if SharedMedia and SharedMedia:IsValid("font", this.tooltipTitle) then
font = SharedMedia:Fetch("font", this.tooltipTitle)
end
if disabled then
GameTooltip:SetText(this.tooltipTitle, 0.5, 0.5, 0.5, 1)
else
GameTooltip:SetText(this.tooltipTitle, 1, 1, 1, 1)
end
if this.tooltipText then
if not font and SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
font = SharedMedia:Fetch("font", this.tooltipText)
end
if disabled then
GameTooltip:AddLine(this.tooltipText, (NORMAL_FONT_COLOR.r + 0.5) / 2, (NORMAL_FONT_COLOR.g + 0.5) / 2, (NORMAL_FONT_COLOR.b + 0.5) / 2, 1)
else
331,12 → 534,38
end
end
else
if SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
font = SharedMedia:Fetch("font", this.tooltipText)
end
if disabled then
GameTooltip:SetText(this.tooltipText, 0.5, 0.5, 0.5, 1)
else
GameTooltip:SetText(this.tooltipText, 1, 1, 1, 1)
end
end
if font then
fillRegionTmp(GameTooltip:GetRegions())
lastSetFont = font
justSetFont = true
for i,v in ipairs(regionTmp) do
if v.SetFont then
local norm,size,outline = v:GetFont()
v:SetFont(font, size, outline)
if not normalFont then
normalFont = norm
end
end
regionTmp[i] = nil
end
elseif not normalFont then
fillRegionTmp(GameTooltip:GetRegions())
for i,v in ipairs(regionTmp) do
if v.GetFont and not normalFont then
normalFont = v:GetFont()
end
regionTmp[i] = nil
end
end
GameTooltip:Show()
end
if this.tooltipFunc then
391,7 → 620,9
end
self:Close(this.level.num + 1)
if not this.disabled then
if this.hasSlider then
if this.secure then
secureFrame:Activate(this)
elseif this.hasSlider then
OpenSlider(self, this)
elseif this.hasEditBox then
OpenEditBox(self, this)
408,10 → 639,25
if this.isRadio then
button.radioHighlight:Show()
end
if this.mouseoverUnderline then
underlineFrame:SetParent(this)
underlineFrame:SetPoint("BOTTOMLEFT",this.text,0,0)
underlineFrame:SetWidth(this.text:GetWidth())
underlineFrame:Show()
end
end
showGameTooltip(this)
end)
button:SetScript("OnHide", function()
if this.secure and secureFrame:IsOwnedBy(this) then
secureFrame:Deactivate()
end
end)
button:SetScript("OnLeave", function()
if this.secure and secureFrame:IsShown() then
return; -- it's ok, we didn't actually mouse out of the button, only onto the secure frame on top of it
end
underlineFrame:Hide()
if not this.selected then
highlight:Hide()
end
505,7 → 751,7
Dewdrop:Close(i+1)
end
value = levels[i].value
end
end
end
elseif this.closeWhenClicked then
self:Close()
532,14 → 778,14
arrow:SetWidth(16)
arrow:SetHeight(16)
arrow:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
local colorSwatch = button:CreateTexture(nil, "OVERLAY")
local colorSwatch = button:CreateTexture(nil, "ARTWORK")
button.colorSwatch = colorSwatch
colorSwatch:SetWidth(20)
colorSwatch:SetHeight(20)
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
local texture = button:CreateTexture(nil, "OVERLAY")
colorSwatch.texture = texture
texture:SetTexture(1, 1, 1)
texture:SetTexture("Interface\\Buttons\\WHITE8X8")
texture:SetWidth(11.5)
texture:SetHeight(11.5)
texture:Show()
567,10 → 813,10
level.parented = true
level:ClearAllPoints()
if level.num == 1 then
if level.parent ~= UIParent then
if level.parent ~= UIParent and type(level.parent) == "table" then
level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT")
else
level:SetPoint("CENTER", level.parent, "CENTER")
level:SetPoint("CENTER", UIParent, "CENTER")
end
else
if level.lastDirection == "RIGHT" then
668,7 → 914,7
end
end
end
local fullscreenFrame = GetFullScreenFrame()
local fullscreenFrame = GetUIPanel("fullscreen")
local l = levels[level]
local strata, framelevel = l:GetFrameStrata(), l:GetFrameLevel()
if fullscreenFrame then
692,8 → 938,8
local kind = options.type
if type(kind) ~= "string" then
return '"type" must be a string.', position
elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then
return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position
elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "dragLink" and kind ~= "header" then
return '"type" must either be "range", "text", "group", "toggle", "execute", "color", "dragLink", or "header".', position
end
if options.aliases then
if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
728,10 → 974,6
return '"func" must be a string or function', position
end
end
else
if kind == "group" then
return 'cannot have "type" = "group" as a subgroup of a passing group', position
end
end
if options ~= baseOptions then
if kind == "header" then
863,6 → 1105,13
return '"step" must be nonnegative', position
end
end
if options.bigStep then
if type(options.bigStep) ~= "number" then
return '"bigStep" must be a number', position
elseif options.bigStep < 0 then
return '"bigStep" must be nonnegative', position
end
end
if options.isPercent and options.isPercent ~= true then
return '"isPercent" must either be nil, true, or false', position
end
959,11 → 1208,78
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
 
 
Dewdrop:Close()
StaticPopup_Show("DEWDROP20_CONFIRM_DIALOG")
end
 
 
local function getMethod(settingname, handler, v, methodName, ...) -- "..." is simply returned straight out cause you can't do "a,b,c = 111,f(),222"
assert(v and type(v)=="table")
assert(methodName and type(methodName)=="string")
 
local method = v[methodName]
if type(method)=="function" then
return method, ...
elseif type(method)=="string" then
if not handler then
Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
elseif not handler[method] then
Dewdrop:error("[%s] 'handler' method %q not defined", tostring(settingname), method)
end
return handler[method], handler, ...
end
 
Dewdrop:error("[%s] Missing %q directive", tostring(settingname), methodName)
end
 
local function callMethod(settingname, handler, v, methodName, ...)
assert(v and type(v)=="table")
assert(methodName and type(methodName)=="string")
 
local method = v[methodName]
if type(method)=="function" then
local success, ret,ret2,ret3,ret4 = pcall(v[methodName], ...)
if not success then
geterrorhandler()(ret)
return nil
end
return ret,ret2,ret3,ret4
 
elseif type(method)=="string" then
 
local neg = method:match("^~(.-)$")
if neg then
method = neg
end
if not handler then
Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
elseif not handler[method] then
Dewdrop:error("[%s] 'handler' (%q) method %q not defined", tostring(settingname), handler.name or "(unnamed)", method)
end
local success, ret,ret2,ret3,ret4 = pcall(handler[method], handler, ...)
if not success then
geterrorhandler()(ret)
return nil
end
if neg then
return not ret
end
return ret,ret2,ret3,ret4
elseif method == false then
return nil
end
 
Dewdrop:error("[%s] Missing %q directive in %q", tostring(settingname), methodName, v.name or "(unnamed)")
end
 
local function skip1Nil(...)
if select(1,...)==nil then
return select(2,...)
end
return ...
end
 
function Dewdrop:FeedAceOptionsTable(options, difference)
self:argCheck(options, 2, "table")
self:argCheck(difference, 3, "nil", "number")
1002,7 → 1318,7
end
 
local current = level
while current do
while current do -- this traverses from higher level numbers to lower, building "values" with leaf nodes first and trunk nodes later
if current.num == difference + 1 then
break
end
1014,8 → 1330,16
local handler = options.handler
local passTable
local passValue
while #values > 0 do
passTable = options.pass and options or nil
while #values > 0 do -- This loop traverses values from the END (trunk nodes first, then onto leaf nodes)
if options.pass then
if options.get and options.set then
passTable = options
elseif not passTable then
passTable = options
end
else
passTable = nil
end
local value = table.remove(values)
options = options.args and options.args[value]
if not options then
1026,40 → 1350,16
end
 
if options.type == "group" then
local hidden, disabled = options.hidden
if hidden then
if type(hidden) == "function" then
hidden = hidden()
elseif type(hidden) == "string" then
local f = hidden
local neg = f:match("^~(.-)$")
if neg then
f = neg
end
hidden = handler[f](handler)
if neg then
hidden = not hidden
end
end
local hidden = options.hidden
if type(hidden) == "function" or type(hidden) == "string" then
hidden = callMethod(options.name or "(options root)", handler, options, "hidden", options.passValue) or false
end
if hidden then
return
end
local disabled = options.disabled
if disabled then
if type(disabled) == "function" then
disabled = disabled()
elseif type(disabled) == "string" then
local f = disabled
local neg = f:match("^~(.-)$")
if neg then
f = neg
end
hidden = handler[f](handler)
if neg then
disabled = not disabled
end
end
if type(disabled) == "function" or type(disabled) == "string" then
disabled = callMethod(options.name or "(options root)", handler, options, "disabled", options.passValue) or false
end
if disabled then
self:AddLine(
1071,7 → 1371,15
for k in pairs(options.args) do
table.insert(values, k)
end
passTable = options.pass and options or nil
if options.pass then
if options.get and options.set then
passTable = options
elseif not passTable then
passTable = options
end
else
passTable = nil
end
if not mysort then
mysort = function(a, b)
local alpha, bravo = mysort_args[a], mysort_args[b]
1081,7 → 1389,7
local bravo_name = bravo.guiName or bravo.name
if alpha_order == bravo_order then
if not alpha_name then
return true
return bravo_name
elseif not bravo_name then
return false
else
1114,55 → 1422,16
self:AddLine()
end
local hidden, disabled = v.guiHidden or v.hidden, v.disabled
if type(hidden) == "function" then
local success
success, hidden = pcall(hidden)
if not success then
geterrorhandler()(hidden)
hidden = false
end
elseif type(hidden) == "string" then
local f = hidden
local neg = f:match("^~(.-)$")
if neg then
f = neg
end
local success
success, hidden = pcall(handler[f], handler)
if not success then
geterrorhandler()(hidden)
hidden = false
end
if neg then
hidden = not hidden
end
 
if type(hidden) == "function" or type(hidden) == "string" then
hidden = callMethod(k, handler, v, "hidden", v.passValue) or false
end
if not hidden then
if type(disabled) == "function" then
local success
success, disabled = pcall(disabled)
if not success then
geterrorhandler()(disabled)
disabled = false
end
elseif type(disabled) == "string" then
local f = disabled
local neg = f:match("^~(.-)$")
if neg then
f = neg
end
local success
success, disabled = pcall(handler[f], handler)
if not success then
geterrorhandler()(disabled)
disabled = false
end
if neg then
disabled = not disabled
end
if type(disabled) == "function" or type(disabled) == "string" then
disabled = callMethod(k, handler, v, "disabled", v.passValue) or false
end
local name = (v.guiIconOnly and v.icon) and "" or (v.guiName or v.name)
local desc = v.desc
local desc = v.guiDesc or v.desc
local iconHeight = v.iconHeight or 16
local iconWidth = v.iconWidth or 16
local iconCoordLeft = v.iconCoordLeft
1181,63 → 1450,18
tooltipText = USAGE_TOOLTIP:format(v.usage)
end
end
local v_p = passTable or v
local passValue = passTable and k or nil
local v_p = passTable
if not v_p or (v.type ~= "execute" and v.get and v.set) or (v.type == "execute" and v.func) then
v_p = v
end
local passValue = v.passValue or (v_p~=v and k) or nil
if v.type == "toggle" then
local checked
local checked_arg
if type(v_p.get) == "function" then
local success, ret = pcall(v_p.get, passValue)
if success then
checked = ret
else
geterrorhandler()(ret)
checked = false
end
checked_arg = checked
else
local f = v_p.get
local neg = f:match("^~(.-)$")
if neg then
f = neg
end
if not handler[f] then
Dewdrop:error("Handler %q not available", f)
end
local success, ret = pcall(handler[f], handler, passValue)
if success then
checked = ret
else
geterrorhandler()(ret)
checked = false
end
checked_arg = checked
if neg then
checked = not checked
end
local checked = callMethod(name, handler, v_p, "get", passValue) or false
local checked_arg = checked
if type(v_p.get)=="string" and v_p.get:match("^~") then
checked_arg = not checked
end
local func, arg1, arg2, arg3
if type(v_p.set) == "function" then
func = v_p.set
if passValue then
arg1 = passValue
arg2 = not checked_arg
else
arg1 = not checked_arg
end
else
if not handler[v_p.set] then
Dewdrop:error("Handler %q not available", v_p.set)
end
func = handler[v_p.set]
arg1 = handler
if passValue then
arg2 = passValue
arg3 = not checked_arg
else
arg2 = not checked_arg
end
end
local func, arg1, arg2, arg3 = getMethod(name, handler, v_p, "set", skip1Nil(passValue, not checked_arg))
if v.guiNameIsMap then
checked = checked and true or false
name = tostring(v.map and v.map[checked]):gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
1261,32 → 1485,11
local confirm = v.confirm
if confirm == true then
confirm = DEFAULT_CONFIRM_MESSAGE:format(tooltipText or tooltipTitle)
end
if type(v_p.func) == "function" then
if confirm then
func = confirmPopup
arg1 = confirm
arg2 = v_p.func
arg3 = passValue
else
func = v_p.func
arg1 = passValue
end
func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
elseif type(confirm) == "string" then
func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
else
if not handler[v_p.func] then
Dewdrop:error("Handler %q not available", v_p.func)
end
if confirm then
func = confirmPopup
arg1 = confirm
arg2 = handler[v_p.func]
arg3 = handler
arg4 = passValue
else
func = handler[v_p.func]
arg1 = handler
arg2 = passValue
end
func,arg1,arg2 = getMethod(name, handler, v_p, "func", passValue)
end
self:AddLine(
'text', name,
1309,38 → 1512,13
)
elseif v.type == "range" then
local sliderValue
if type(v_p.get) == "function" then
local success, ret = pcall(v_p.get, passValue)
if success then
sliderValue = ret
else
geterrorhandler()(ret)
sliderValue = 0
end
sliderValue = callMethod(name, handler, v_p, "get", passValue) or 0
local sliderFunc, sliderArg1, sliderArg2 = getMethod(name, handler, v_p, "set", passValue)
if tooltipText then
tooltipText = format("%s\n\n%s", tooltipText, RANGE_TOOLTIP)
else
if not handler[v_p.get] then
Dewdrop:error("Handler %q not available", v_p.get)
end
local success, ret = pcall(handler[v_p.get], handler, passValue)
if success then
sliderValue = ret
else
geterrorhandler()(ret)
sliderValue = 0
end
tooltipText = RANGE_TOOLTIP
end
local sliderFunc, sliderArg1, sliderArg2
if type(v_p.set) == "function" then
sliderFunc = v_p.set
sliderArg1 = passValue
else
if not handler[v_p.set] then
Dewdrop:error("Handler %q not available", v_p.set)
end
sliderFunc = handler[v_p.set]
sliderArg1 = handler
sliderArg2 = passValue
end
self:AddLine(
'text', name,
'hasArrow', true,
1348,11 → 1526,13
'sliderMin', v.min or 0,
'sliderMax', v.max or 1,
'sliderStep', v.step or 0,
'sliderBigStep', v.bigStep or nil,
'sliderIsPercent', v.isPercent or false,
'sliderValue', sliderValue,
'sliderFunc', sliderFunc,
'sliderArg1', sliderArg1,
'sliderArg2', sliderArg2,
'fromAceOptions', true,
'disabled', disabled,
'tooltipTitle', tooltipTitle,
'tooltipText', tooltipText,
1365,37 → 1545,11
'iconCoordBottom', iconCoordBottom
)
elseif v.type == "color" then
local r,g,b,a
if type(v_p.get) == "function" then
local success
success, r, g, b, a = pcall(v_p.get, passValue)
if not success then
geterrorhandler()(r)
r, g, b, a = 0, 0, 0, 0
end
else
if not handler[v_p.get] then
Dewdrop:error("Handler %q not available", v_p.get)
end
local success
success, r, g, b, a = pcall(handler[v_p.get], handler, passValue)
if not success then
geterrorhandler()(r)
r, g, b, a = 0, 0, 0, 0
end
local r,g,b,a = callMethod(name, handler, v_p, "get", passValue)
if not r then
r,g,b,a = 0,0,0,0
end
local colorFunc, colorArg1, colorArg2
if type(v_p.set) == "function" then
colorFunc = v_p.set
colorArg1 = passValue
else
if not handler[v_p.set] then
Dewdrop:error("Handler %q not available", v_p.set)
end
colorFunc = handler[v_p.set]
colorArg1 = handler
colorArg2 = passValue
end
local colorFunc, colorArg1, colorArg2 = getMethod(name, handler, v_p, "set", passValue)
self:AddLine(
'text', name,
'hasArrow', true,
1413,12 → 1567,25
'tooltipText', tooltipText
)
elseif v.type == "text" then
if type(v.validate) == "table" then
if type(v.validate) == "table" then
local func,arg1,arg2
if v.onClick then
func,arg1,arg2 = getMethod(name, handler, v, "onClick", passValue)
end
local checked
if v.isChecked then
checked = callMethod(name, handler, v, "isChecked", passValue) or false
end
self:AddLine(
'text', name,
'hasArrow', true,
'value', k,
'func', func,
'arg1', arg1,
'arg2', arg2,
'mouseoverUnderline', func and true or nil,
'disabled', disabled,
'checked', checked,
'tooltipTitle', tooltipTitle,
'tooltipText', tooltipText,
'icon', v.icon,
1431,61 → 1598,23
)
else
local editBoxText
if type(v_p.get) == "function" then
local success, ret = pcall(v_p.get, passValue)
if success then
editBoxText = ret
else
geterrorhandler()(ret)
editBoxText = ""
end
elseif v_p.get == false then
editBoxText = nil
else
if not handler[v_p.get] then
Dewdrop:error("Handler %q not available", v_p.get)
end
local success, ret = pcall(handler[v_p.get], handler, passValue)
if success then
editBoxText = ret
else
geterrorhandler()(ret)
editBoxText = ""
end
end
local editBoxFunc, editBoxArg1, editBoxArg2
if type(v_p.set) == "function" then
editBoxFunc = v_p.set
editBoxArg1 = passValue
else
if not handler[v_p.set] then
Dewdrop:error("Handler %q not available", v_p.set)
end
editBoxFunc = handler[v_p.set]
editBoxArg1 = handler
editBoxArg2 = passValue
end
 
editBoxText = callMethod(name, handler, v_p, "get", passValue) or ""
local editBoxFunc, editBoxArg1, editBoxArg2 = getMethod(name, handler, v_p, "set", passValue)
 
local editBoxValidateFunc, editBoxValidateArg1
 
if v.validate and v.validate ~= "keybinding" then
if type(v.validate) == "function" then
editBoxValidateFunc = v.validate
else
if not handler[v.validate] then
Dewdrop:error("Handler %q not available", v.validate)
if v.validate == "keybinding" then
if tooltipText then
tooltipText = format("%s\n\n%s", tooltipText, RESET_KEYBINDING_DESC)
else
tooltipText = RESET_KEYBINDING_DESC
end
editBoxValidateFunc = handler[v.validate]
editBoxValidateArg1 = handler
end
elseif v.validate then
if tooltipText then
tooltipText = tooltipText .. "\n\n" .. RESET_KEYBINDING_DESC
else
tooltipText = RESET_KEYBINDING_DESC
editBoxValidateFunc, editBoxValidateArg1 = getMethod(name, handler, v, "validate") -- no passvalue!
end
end
 
 
self:AddLine(
'text', name,
'hasArrow', true,
1512,11 → 1641,24
)
end
elseif v.type == "group" then
local func,arg1,arg2
if v.onClick then
func,arg1,arg2 = getMethod(name, handler, v, "onClick", passValue)
end
local checked
if v.isChecked then
checked = callMethod(name, handler, v, "isChecked", passValue) or false
end
self:AddLine(
'text', name,
'hasArrow', true,
'value', k,
'func', func,
'arg1', arg1,
'arg2', arg2,
'mouseoverUnderline', func and true or nil,
'disabled', disabled,
'checked', checked,
'tooltipTitle', tooltipTitle,
'tooltipText', tooltipText,
'icon', v.icon,
1558,17 → 1700,16
end
elseif options.type == "text" and type(options.validate) == "table" then
local current
local options_p = passTable or options
local multiToggle = options_p.multiToggle
local options_p = passTable
if not options_p or (options.get and options.set) then
options_p = options
passTable = nil
passValue = nil
end
local multiToggle = options.multiToggle
local passValue = options.passValue or passValue
if not multiToggle then
if type(options_p.get) == "function" then
current = options_p.get(passValue)
elseif options_p.get ~= false then
if not handler[options_p.get] then
Dewdrop:error("Handler %q not available", options_p.get)
end
current = handler[options_p.get](handler, passValue)
end
current = callMethod(k, handler, options_p, "get", passValue)
end
local indexed = true
for k,v in pairs(options.validate) do
1592,46 → 1733,10
if type(k) == "number" then
k = v
end
local func, arg1, arg2, arg3, arg4
if type(options_p.set) == "function" then
func = options_p.set
if passValue then
arg1 = passValue
arg2 = k
else
arg1 = k
end
else
if not handler[options_p.set] then
Dewdrop:error("Handler %q not available", options_p.set)
end
func = handler[options_p.set]
arg1 = handler
if passValue then
arg2 = passValue
arg3 = k
else
arg2 = k
end
end
local func, arg1, arg2, arg3, arg4 = getMethod(k, handler, options_p, "set", skip1Nil(passValue, k))
local checked
if multiToggle then
if type(options_p.get) == "function" then
if passValue == nil then
checked = options_p.get(k)
else
checked = options_p.get(passValue, k)
end
elseif options_p.get ~= false then
if not handler[options_p.get] then
Dewdrop:error("Handler %q not available", options_p.get)
end
if passValue == nil then
checked = handler[options_p.get](handler, k)
else
checked = handler[options_p.get](handler, passValue, k)
end
end
checked = callMethod(k, handler, options_p, "get", skip1Nil(passValue, k)) or false
if arg2 == nil then
arg2 = not checked
elseif arg3 == nil then
1645,6 → 1750,15
func, arg1, arg2, arg3, arg4 = nil, nil, nil, nil, nil
end
end
local tooltipTitle
local tooltipText
if options.validateDesc then
tooltipTitle = v
tooltipText = options.validateDesc[k]
else
tooltipTitle = options.guiName or options.name
tooltipText = v
end
self:AddLine(
'text', v,
'func', func,
1654,8 → 1768,8
'arg4', arg4,
'isRadio', not multiToggle,
'checked', checked,
'tooltipTitle', options.guiName or options.name,
'tooltipText', v
'tooltipTitle', tooltipTitle,
'tooltipText', tooltipText
)
end
for k in pairs(values) do
1667,6 → 1781,65
return true
end
 
function Dewdrop:FeedTable(s, difference)
self:argCheck(s, 2, "table")
self:argCheck(difference, 3, "nil", "number")
if not currentLevel then
self:error("Cannot call `FeedTable' outside of a Dewdrop declaration")
end
if not difference then
difference = 0
end
local level = levels[currentLevel]
if not level then
self:error("Improper level given")
end
if not values then
values = {}
else
for k,v in pairs(values) do
values[k] = nil
end
end
local t = s.subMenu and s or {subMenu = s}
local current = level
while current do
if current.num == difference + 1 then
break
end
table.insert(values, current.value)
current = levels[current.num - 1]
end
 
while #values > 0 do
local value = table.remove(values)
t = t.subMenu and t.subMenu[value]
if not t then
return
end
end
 
if t.subMenu or current.num == 1 then
for k in pairs(t.subMenu) do
table.insert(values, k)
end
table.sort(values)
for _,k in ipairs(values) do
local argTable = {"value", k}
for key, val in pairs(t.subMenu[k]) do
table.insert(argTable, key)
table.insert(argTable, val)
end
self:AddLine(unpack(argTable))
end
for k in pairs(values) do
values[k] = nil
end
return false
end
return true
end
 
function Refresh(self, level)
if type(level) == "number" then
level = levels[level]
1726,14 → 1899,20
end
 
function Dewdrop:Refresh(level)
self:argCheck(level, 2, "number")
Refresh(self, levels[level])
self:argCheck(level, 2, "number", "nil")
if not level then
for k,v in pairs(levels) do
Refresh(self, v)
end
else
Refresh(self, levels[level])
end
end
 
function OpenSlider(self, parent)
if not sliderFrame then
sliderFrame = CreateFrame("Frame", nil, nil)
sliderFrame:SetWidth(80)
sliderFrame:SetWidth(100)
sliderFrame:SetHeight(170)
sliderFrame:SetScale(UIParent:GetScale())
sliderFrame:SetBackdrop(tmp(
1756,13 → 1935,14
sliderFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
sliderFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
sliderFrame:EnableMouse(true)
sliderFrame:EnableMouseWheel(true)
sliderFrame:Hide()
sliderFrame:SetPoint("CENTER", UIParent, "CENTER")
local slider = CreateFrame("Slider", nil, sliderFrame)
sliderFrame.slider = slider
slider:SetOrientation("VERTICAL")
slider:SetMinMaxValues(0, 1)
slider:SetValueStep(0.01)
slider:SetValueStep(0.000000001)
slider:SetValue(0.5)
slider:SetWidth(16)
slider:SetHeight(128)
1792,13 → 1972,29
text:SetFontObject(GameFontGreenSmall)
text:SetText("0%")
text:SetPoint("TOP", slider, "BOTTOM")
local text = slider:CreateFontString(nil, "ARTWORK")
sliderFrame.currentText = text
text:SetFontObject(GameFontHighlightSmall)
text:SetText("50%")
text:SetPoint("LEFT", slider, "RIGHT")
text:SetPoint("RIGHT", sliderFrame, "RIGHT", -6, 0)
text:SetJustifyH("CENTER")
local editBox = CreateFrame("EditBox", nil, sliderFrame)
sliderFrame.currentText = editBox
editBox:SetFontObject(ChatFontNormal)
editBox:SetHeight(13)
editBox:SetPoint("RIGHT", sliderFrame, "RIGHT", -16, 0)
editBox:SetPoint("LEFT", slider, "RIGHT", 12, 0)
editBox:SetText("50%")
editBox:SetJustifyH("CENTER")
 
local width = editBox:GetWidth()/2 + 10
local left = editBox:CreateTexture(nil, "BACKGROUND")
left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
left:SetTexCoord(0, width / 256, 0, 1)
left:SetWidth(width)
left:SetHeight(32)
left:SetPoint("LEFT", editBox, "LEFT", -10, 0)
local right = editBox:CreateTexture(nil, "BACKGROUND")
right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
right:SetTexCoord(1 - width / 256, 1, 0, 1)
right:SetWidth(width)
right:SetHeight(32)
right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
 
local changed = false
local inside = false
slider:SetScript("OnValueChanged", function()
1810,7 → 2006,12
if sliderFrame.parent and sliderFrame.parent.sliderFunc then
local min = sliderFrame.parent.sliderMin or 0
local max = sliderFrame.parent.sliderMax or 1
local step = sliderFrame.parent.sliderStep or (max - min) / 100
local step
if sliderFrame.fineStep then
step = sliderFrame.parent.sliderStep or (max - min) / 100
else
step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
end
local value = (1 - slider:GetValue()) * (max - min) + min
if step > 0 then
value = math.floor((value - min) / step + 0.5) * step + min
1825,7 → 2026,9
end
sliderFrame.lastValue = value
local text = sliderFrame.parent.sliderFunc(getArgs(sliderFrame.parent, 'sliderArg', 1, value))
if text then
if sliderFrame.parent.fromAceOptions then
text = nil
elseif type(text) == "string" or type(text) == "number" then
sliderFrame.currentText:SetText(text)
done = true
end
1833,7 → 2036,12
if not done then
local min = sliderFrame.parent.sliderMin or 0
local max = sliderFrame.parent.sliderMax or 1
local step = sliderFrame.parent.sliderStep or (max - min) / 100
local step
if sliderFrame.fineStep then
step = sliderFrame.parent.sliderStep or (max - min) / 100
else
step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
end
local value = (1 - slider:GetValue()) * (max - min) + min
if step > 0 then
value = math.floor((value - min) / step + 0.5) * step + min
1856,14 → 2064,38
end
end
end)
sliderFrame:SetScript("OnEnter", function()
local function onEnter()
StopCounting(self, sliderFrame.level)
showGameTooltip(sliderFrame.parent)
end)
end
local function onLeave()
GameTooltip:Hide()
end
sliderFrame:SetScript("OnEnter", onEnter)
sliderFrame:SetScript("OnLeave", function()
StartCounting(self, sliderFrame.level)
GameTooltip:Hide()
if changed then
local parent = sliderFrame.parent
local sliderFunc = parent.sliderFunc
for i = 1, sliderFrame.level - 1 do
Refresh(self, levels[i])
end
local newParent
for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
if button.sliderFunc == sliderFunc then
newParent = button
break
end
end
if newParent then
OpenSlider(self, newParent)
else
sliderFrame:Hide()
end
end
end)
editBox:SetScript("OnEnter", onEnter)
editBox:SetScript("OnLeave", onLeave)
slider:SetScript("OnMouseDown", function()
sliderFrame.mouseDown = true
GameTooltip:Hide()
1900,7 → 2132,6
end)
slider:SetScript("OnLeave", function()
inside = false
StartCounting(self, sliderFrame.level)
GameTooltip:Hide()
if changed and not sliderFrame.mouseDown then
local parent = sliderFrame.parent
1920,14 → 2151,79
else
sliderFrame:Hide()
end
 
changed = false
end
end)
sliderFrame:SetScript("OnMouseWheel", function(t, a1)
local arg1 = a1 or arg1
local up = arg1 > 0
 
local min = sliderFrame.parent.sliderMin or 0
local max = sliderFrame.parent.sliderMax or 1
local step = sliderFrame.parent.sliderStep or (max - min) / 100
if step <= 0 then
step = (max - min) / 100
end
 
local value = (1 - slider:GetValue()) * (max - min) + min
if up then
value = value + step
else
value = value - step
end
if value > max then
value = max
elseif value < min then
value = min
end
sliderFrame.fineStep = true
if max<=min then
slider:SetValue(0)
else
slider:SetValue(1 - (value - min) / (max - min))
end
sliderFrame.fineStep = nil
end)
slider:SetScript("OnMouseWheel", sliderFrame:GetScript("OnMouseWheel"))
editBox:SetScript("OnEnterPressed", function(t, a1)
local value = editBox:GetNumber()
 
if sliderFrame.parent.sliderIsPercent then
value = value / 100
end
 
local min = sliderFrame.parent.sliderMin or 0
local max = sliderFrame.parent.sliderMax or 1
 
if value > max then
value = max
elseif value < min then
value = min
end
sliderFrame.fineStep = true
if max <= min then
slider:SetValue(0)
else
slider:SetValue(1 - (value - min) / (max - min))
end
sliderFrame.fineStep = nil
 
StartCounting(self, sliderFrame.level)
end)
editBox:SetScript("OnEscapePressed", function()
self:Close(sliderFrame.level)
StartCounting(self, sliderFrame.level)
end)
editBox:SetAutoFocus(false)
end
sliderFrame.parent = parent
sliderFrame.level = parent.level.num + 1
sliderFrame.parentValue = parent.level.value
sliderFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3)
sliderFrame.slider:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
sliderFrame.currentText:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
sliderFrame.currentText:ClearFocus()
sliderFrame.changing = true
if not parent.sliderMin or not parent.sliderMax then
return
1945,24 → 2241,35
if not parent.sliderValue then
parent.sliderValue = (parent.sliderMin + parent.sliderMax) / 2
end
sliderFrame.slider:SetValue(1 - (parent.sliderValue - parent.sliderMin) / (parent.sliderMax - parent.sliderMin))
if parent.sliderMax <= parent.sliderMin then
sliderFrame.slider:SetValue(0)
else
sliderFrame.slider:SetValue(1 - (parent.sliderValue - parent.sliderMin) / (parent.sliderMax - parent.sliderMin))
end
sliderFrame.changing = false
sliderFrame.bottomText:SetText(parent.sliderMinText or "0")
sliderFrame.topText:SetText(parent.sliderMaxText or "1")
local text
if parent.sliderFunc then
if parent.sliderFunc and not parent.fromAceOptions then
text = parent.sliderFunc(getArgs(parent, 'sliderArg', 1, parent.sliderValue))
end
if text then
if type(text) == "number" or type(text) == "string" then
sliderFrame.currentText:SetText(text)
elseif parent.sliderIsPercent then
sliderFrame.currentText:SetText(string.format("%.0f%%", parent.sliderValue * 100))
else
sliderFrame.currentText:SetText(parent.sliderValue)
if parent.sliderStep < 0.1 then
sliderFrame.currentText:SetText(string.format("%.2f", parent.sliderValue))
elseif parent.sliderStep < 1 then
sliderFrame.currentText:SetText(string.format("%.1f", parent.sliderValue))
else
sliderFrame.currentText:SetText(string.format("%.0f", parent.sliderValue))
end
end
 
 
sliderFrame.lastValue = parent.sliderValue
 
 
local level = parent.level
sliderFrame:Show()
sliderFrame:ClearAllPoints()
2074,7 → 2381,7
right:SetWidth(100)
right:SetHeight(32)
right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
 
 
editBox:SetScript("OnEnterPressed", function()
if editBoxFrame.parent and editBoxFrame.parent.editBoxValidateFunc then
local t = editBox.realText or editBox:GetText() or ""
2127,7 → 2434,7
end
if text ~= oldText then
changing = true
self:SetText(text)
self:SetText(tostring(text))
changing = false
skipNext = true
end
2171,7 → 2478,7
Screenshot()
return
end
 
 
if arg1 == "LeftButton" then
arg1 = "BUTTON1"
elseif arg1 == "RightButton" then
2256,7 → 2563,7
editBoxFrame.editBox:SetFrameLevel(editBoxFrame:GetFrameLevel() + 1)
editBoxFrame.editBox.realText = nil
editBoxFrame:SetClampedToScreen(false)
 
 
editBoxFrame.editBox:SpecialSetText("")
if parent.editBoxIsKeybinding then
local s = parent.editBoxText
2282,7 → 2589,7
else
editBoxFrame.editBox:SpecialSetText(parent.editBoxText)
end
 
 
editBoxFrame.editBox.keybinding = parent.editBoxIsKeybinding
editBoxFrame.editBox.keybindingOnly = parent.editBoxKeybindingOnly
editBoxFrame.editBox.keybindingExcept = parent.editBoxKeybindingExcept
2420,7 → 2727,7
end
 
function Dewdrop:IsOpen(parent)
self:argCheck(parent, 2, "table", "nil")
self:argCheck(parent, 2, "table", "string", "nil")
return levels[1] and levels[1]:IsShown() and (not parent or parent == levels[1].parent or parent == levels[1]:GetParent())
end
 
2437,7 → 2744,9
DewdropLib:GetInstance('1.0'):Close()
end
end
parent:GetCenter()
if type(parent) == "table" then
parent:GetCenter()
end
local frame = AcquireLevel(self, level)
if level == 1 then
frame.lastDirection = "RIGHT"
2459,7 → 2768,7
-- levels[level].parentTooltipTitle = parent.tooltipTitle
-- levels[level].parentTooltipText = parent.tooltipText
-- levels[level].parentTooltipFunc = parent.tooltipFunc
if parent.arrow then
if type(parent) == "table" and parent.arrow then
-- parent.arrow:SetVertexColor(0.2, 0.6, 0)
-- parent.arrow:SetHeight(24)
-- parent.arrow:SetWidth(24)
2483,7 → 2792,7
point, relativePoint = point .. "RIGHT", relativePoint .. "LEFT"
end
end
frame:SetPoint(point, parent, relativePoint)
frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint)
if cursorX and cursorY then
local left = frame:GetLeft()
local width = frame:GetWidth()
2512,7 → 2821,7
if curX > GetScreenWidth() / 2 then
xOffset = -width
end
frame:SetPoint(point, parent, relativePoint, curX - left + xOffset, curY - bottom + yOffset)
frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left + xOffset, curY - bottom + yOffset)
if level == 1 then
frame.lastDirection = "RIGHT"
end
2535,7 → 2844,7
point = "RIGHT"
end
end
frame:SetPoint(point, parent, relativePoint, curX - left - width / 2, 0)
frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left - width / 2, 0)
if level == 1 then
frame.lastDirection = "RIGHT"
end
2558,7 → 2867,7
point = "TOP"
end
end
frame:SetPoint(point, parent, relativePoint, 0, curY - bottom - height / 2)
frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, 0, curY - bottom - height / 2)
if level == 1 then
frame.lastDirection = "DOWN"
end
2590,19 → 2899,19
end
 
function Dewdrop:IsRegistered(parent)
self:argCheck(parent, 2, "table")
self:argCheck(parent, 2, "table", "string")
return not not self.registry[parent]
end
 
function Dewdrop:Register(parent, ...)
self:argCheck(parent, 2, "table")
self:argCheck(parent, 2, "table", "string")
if self.registry[parent] then
self:Unregister(parent)
end
local info = new(...)
if type(info.children) == "table" then
local err, position = validateOptions(info.children)
 
 
if err then
if position then
Dewdrop:error(position .. ": " .. err)
2612,12 → 2921,12
end
end
self.registry[parent] = info
if not info.dontHook and not self.onceRegistered[parent] then
if not info.dontHook and not self.onceRegistered[parent] and type(parent) == "table" then
if parent:HasScript("OnMouseUp") then
local script = parent:GetScript("OnMouseUp")
parent:SetScript("OnMouseUp", function()
parent:SetScript("OnMouseUp", function(this, ...)
if script then
script()
script(this, ...)
end
if arg1 == "RightButton" and self.registry[parent] then
if self:IsOpen(parent) then
2630,9 → 2939,9
end
if parent:HasScript("OnMouseDown") then
local script = parent:GetScript("OnMouseDown")
parent:SetScript("OnMouseDown", function()
parent:SetScript("OnMouseDown", function(this, ...)
if script then
script()
script(this, ...)
end
if self.registry[parent] then
self:Close()
2644,18 → 2953,20
end
 
function Dewdrop:Unregister(parent)
self:argCheck(parent, 2, "table")
self:argCheck(parent, 2, "table", "string")
self.registry[parent] = nil
end
 
function Dewdrop:Open(parent, ...)
self:argCheck(parent, 2, "table")
self:argCheck(parent, 2, "table", "string")
local info
local k1 = ...
if type(k1) == "table" and k1[0] and k1.IsFrameType and self.registry[k1] then
info = tmp()
info = tmp(select(2, ...))
for k,v in pairs(self.registry[k1]) do
info[k] = v
if info[k] == nil then
info[k] = v
end
end
else
info = tmp(...)
2737,6 → 3048,19
end
end
 
function Dewdrop:AddSeparator(level)
level = levels[level or currentLevel]
if not level or not level.buttons then return; end
 
local prevbutton = level.buttons[#level.buttons]
if not prevbutton then return; end
 
if prevbutton.disabled and prevbutton.text:GetText() == "" then
return
end
self:AddLine("text", "", "disabled", true)
end
 
function Dewdrop:AddLine(...)
local info = tmp(...)
local level = info.level or currentLevel
2745,7 → 3069,7
if not next(info) then
info.disabled = true
end
button.disabled = info.isTitle or info.notClickable or info.disabled
button.disabled = info.isTitle or info.notClickable or info.disabled or (self.combat and info.secure)
button.isTitle = info.isTitle
button.notClickable = info.notClickable
if button.isTitle then
2775,6 → 3099,7
button.notCheckable = info.notCheckable
button.text:SetPoint("LEFT", button, "LEFT", button.notCheckable and 0 or 24, 0)
button.checked = not info.notCheckable and info.checked
button.mouseoverUnderline = info.mouseoverUnderline
button.isRadio = not info.notCheckable and info.isRadio
if info.isRadio then
button.check:Show()
2831,6 → 3156,7
end
if not button.disabled then
button.func = info.func
button.secure = info.secure
end
button.hasColorSwatch = info.hasColorSwatch
if button.hasColorSwatch then
2839,7 → 3165,7
button.r = info.r or 1
button.g = info.g or 1
button.b = info.b or 1
button.colorSwatch.texture:SetTexture(button.r, button.g, button.b)
button.colorSwatch.texture:SetVertexColor(button.r, button.g, button.b)
button.checked = false
button.func = nil
button.colorFunc = info.colorFunc
2867,11 → 3193,16
button.sliderMin = info.sliderMin or 0
button.sliderMax = info.sliderMax or 1
button.sliderStep = info.sliderStep or 0
button.sliderBigStep = info.sliderBigStep or button.sliderStep
if button.sliderBigStep < button.sliderStep then
button.sliderBigStep = button.sliderStep
end
button.sliderIsPercent = info.sliderIsPercent and true or false
button.sliderMinText = info.sliderMinText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMin * 100) or button.sliderMin
button.sliderMaxText = info.sliderMaxText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMax * 100) or button.sliderMax
button.sliderFunc = info.sliderFunc
button.sliderValue = info.sliderValue
button.fromAceOptions = info.fromAceOptions
local i = 1
while true do
local k = "sliderArg" .. i
2990,23 → 3321,9
options.handler = handler
local class = handler.class
if not AceLibrary:HasInstance("AceOO-2.0") or not class then
self:error("Cannot retrieve AceOptions tables from a non-object argument #2")
end
while class and class ~= AceLibrary("AceOO-2.0").Class do
if type(class.GetAceOptionsDataTable) == "function" then
local t = class:GetAceOptionsDataTable(handler)
for k,v in pairs(t) do
if type(options.args) ~= "table" then
options.args = {}
end
if options.args[k] == nil then
options.args[k] = v
end
end
end
local mixins = class.mixins
if mixins then
for mixin in pairs(mixins) do
if Rock then
-- possible Rock object
for mixin in Rock:IterateObjectMixins(handler) do
if type(mixin.GetAceOptionsDataTable) == "function" then
local t = mixin:GetAceOptionsDataTable(handler)
for k,v in pairs(t) do
3020,11 → 3337,62
end
end
end
class = class.super
else
-- Ace2 object
while class and class ~= AceLibrary("AceOO-2.0").Class do
if type(class.GetAceOptionsDataTable) == "function" then
local t = class:GetAceOptionsDataTable(handler)
for k,v in pairs(t) do
if type(options.args) ~= "table" then
options.args = {}
end
if options.args[k] == nil then
options.args[k] = v
end
end
end
local mixins = class.mixins
if mixins then
for mixin in pairs(mixins) do
if type(mixin.GetAceOptionsDataTable) == "function" then
local t = mixin:GetAceOptionsDataTable(handler)
for k,v in pairs(t) do
if type(options.args) ~= "table" then
options.args = {}
end
if options.args[k] == nil then
options.args[k] = v
end
end
end
end
end
class = class.super
end
end
return options
end
 
function Dewdrop:OnTooltipHide()
if lastSetFont then
if lastSetFont == normalFont then
lastSetFont = nil
return
end
fillRegionTmp(GameTooltip:GetRegions())
for i,v in ipairs(regionTmp) do
if v.GetFont then
local font,size,outline = v:GetFont()
if font == lastSetFont then
v:SetFont(normalFont, size, outline)
end
end
regionTmp[i] = nil
end
lastSetFont = nil
end
end
 
local function activate(self, oldLib, oldDeactivate)
Dewdrop = self
if oldLib and oldLib.registry then
3037,20 → 3405,20
local WorldFrame_OnMouseDown = WorldFrame:GetScript("OnMouseDown")
local WorldFrame_OnMouseUp = WorldFrame:GetScript("OnMouseUp")
local oldX, oldY, clickTime
WorldFrame:SetScript("OnMouseDown", function()
WorldFrame:SetScript("OnMouseDown", function(this, ...)
oldX,oldY = GetCursorPosition()
clickTime = GetTime()
if WorldFrame_OnMouseDown then
WorldFrame_OnMouseDown()
WorldFrame_OnMouseDown(this, ...)
end
end)
 
WorldFrame:SetScript("OnMouseUp", function()
WorldFrame:SetScript("OnMouseUp", function(this, ...)
local x,y = GetCursorPosition()
if not oldX or not oldY or not x or not y or not clickTime then
self:Close()
if WorldFrame_OnMouseUp then
WorldFrame_OnMouseUp()
WorldFrame_OnMouseUp(this, ...)
end
return
end
3059,7 → 3427,7
self:Close()
end
if WorldFrame_OnMouseUp then
WorldFrame_OnMouseUp()
WorldFrame_OnMouseUp(this, ...)
end
end)
 
3068,13 → 3436,13
self:Close()
end
end)
 
 
hooksecurefunc("HideDropDownMenu", function()
if levels[1] and levels[1]:IsVisible() then
self:Close()
end
end)
 
 
hooksecurefunc("CloseDropDownMenus", function()
if levels[1] and levels[1]:IsVisible() then
local stack = debugstack()
3091,11 → 3459,28
self.frame:Hide()
self.frame:SetScript("OnEvent", function(this, event)
this:Show()
if event=="PLAYER_REGEN_ENABLED" then -- track combat state for secure frame operations
self.combat = false
elseif event=="PLAYER_REGEN_DISABLED" then
self.combat = true
end
end)
self.frame:SetScript("OnUpdate", function(this)
this:Hide()
self:Refresh(1)
end)
self.hookedTooltip = true
if not oldLib or not oldLib.hookedTooltip then
local OnTooltipHide = GameTooltip:GetScript("OnHide")
GameTooltip:SetScript("OnHide", function(this, ...)
if OnTooltipHide then
OnTooltipHide(this, ...)
end
if type(self.OnTooltipHide) == "function" then
self:OnTooltipHide()
end
end)
end
levels = {}
buttons = {}
 
3104,4 → 3489,10
end
end
 
AceLibrary:Register(Dewdrop, MAJOR_VERSION, MINOR_VERSION, activate)
local function external(lib, major, instance)
if major == "LibSharedMedia-3.0" then
SharedMedia = instance
end
end
 
AceLibrary:Register(Dewdrop, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)