annotate modules/FuBar_ReActionFu/lib/Dewdrop-2.0/Dewdrop-2.0.lua @ 30:0d95ce7a9ec2

- added Ace3 externs - converted ReAction_ConfigUI to use blizzard interface addons panel via AceConfigDialog-3.0 - partially converted FuBar module to LibRock, deprecated it (going to remove it entirely later) - cleaned up a couple other tidbits
author Flick <flickerstreak@gmail.com>
date Wed, 02 Apr 2008 23:31:13 +0000
parents 21bcaf8215ff
children
rev   line source
flickerstreak@30 1 --[[
flickerstreak@30 2 Name: Dewdrop-2.0
flickerstreak@30 3 Revision: $Rev: 56529 $
flickerstreak@30 4 Author(s): ckknight (ckknight@gmail.com)
flickerstreak@30 5 Website: http://ckknight.wowinterface.com/
flickerstreak@30 6 Documentation: http://wiki.wowace.com/index.php/Dewdrop-2.0
flickerstreak@30 7 SVN: http://svn.wowace.com/root/trunk/DewdropLib/Dewdrop-2.0
flickerstreak@30 8 Description: A library to provide a clean dropdown menu interface.
flickerstreak@30 9 Dependencies: AceLibrary
flickerstreak@30 10 License: LGPL v2.1
flickerstreak@30 11 ]]
flickerstreak@30 12
flickerstreak@30 13 local MAJOR_VERSION = "Dewdrop-2.0"
flickerstreak@30 14 local MINOR_VERSION = "$Revision: 56529 $"
flickerstreak@30 15
flickerstreak@30 16 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
flickerstreak@30 17 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
flickerstreak@30 18
flickerstreak@30 19 local Dewdrop = {}
flickerstreak@30 20
flickerstreak@30 21 local SharedMedia
flickerstreak@30 22
flickerstreak@30 23 local CLOSE = "Close"
flickerstreak@30 24 local CLOSE_DESC = "Close the menu."
flickerstreak@30 25 local VALIDATION_ERROR = "Validation error."
flickerstreak@30 26 local USAGE_TOOLTIP = "Usage: %s."
flickerstreak@30 27 local RANGE_TOOLTIP = "Note that you can scroll your mouse wheel while over the slider to step by one."
flickerstreak@30 28 local RESET_KEYBINDING_DESC = "Hit escape to clear the keybinding."
flickerstreak@30 29 local KEY_BUTTON1 = "Left Mouse"
flickerstreak@30 30 local KEY_BUTTON2 = "Right Mouse"
flickerstreak@30 31 local DISABLED = "Disabled"
flickerstreak@30 32 local DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?"
flickerstreak@30 33
flickerstreak@30 34 if GetLocale() == "deDE" then
flickerstreak@30 35 CLOSE = "Schlie\195\159en"
flickerstreak@30 36 CLOSE_DESC = "Men\195\188 schlie\195\159en."
flickerstreak@30 37 VALIDATION_ERROR = "Validierungsfehler."
flickerstreak@30 38 USAGE_TOOLTIP = "Benutzung: %s."
flickerstreak@30 39 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."
flickerstreak@30 40 RESET_KEYBINDING_DESC = "Escape dr\195\188cken, um die Tastenbelegung zu l\195\182schen."
flickerstreak@30 41 KEY_BUTTON1 = "Linke Maustaste"
flickerstreak@30 42 KEY_BUTTON2 = "Rechte Maustaste"
flickerstreak@30 43 DISABLED = "Deaktiviert"
flickerstreak@30 44 DEFAULT_CONFIRM_MESSAGE = "Bist du sicher das du `%s' machen willst?"
flickerstreak@30 45 elseif GetLocale() == "koKR" then
flickerstreak@30 46 CLOSE = "닫기"
flickerstreak@30 47 CLOSE_DESC = "메뉴를 닫습니다."
flickerstreak@30 48 VALIDATION_ERROR = "오류 확인."
flickerstreak@30 49 USAGE_TOOLTIP = "사용법: %s."
flickerstreak@30 50 RANGE_TOOLTIP = "알림 : 슬라이더 위에서 마우스 휠을 사용하면 한단계씩 조절할 수 있습니다."
flickerstreak@30 51 RESET_KEYBINDING_DESC = "단축키를 해제하려면 ESC키를 누르세요."
flickerstreak@30 52 KEY_BUTTON1 = "왼쪽 마우스"
flickerstreak@30 53 KEY_BUTTON2 = "오른쪽 마우스"
flickerstreak@30 54 DISABLED = "비활성화됨"
flickerstreak@30 55 DEFAULT_CONFIRM_MESSAGE = "정말로 `%s' 실행을 하시겠습니까 ?"
flickerstreak@30 56 elseif GetLocale() == "frFR" then
flickerstreak@30 57 CLOSE = "Fermer"
flickerstreak@30 58 CLOSE_DESC = "Ferme le menu."
flickerstreak@30 59 VALIDATION_ERROR = "Erreur de validation."
flickerstreak@30 60 USAGE_TOOLTIP = "Utilisation : %s."
flickerstreak@30 61 RANGE_TOOLTIP = "Vous pouvez aussi utiliser la molette de la souris pour pour modifier progressivement."
flickerstreak@30 62 RESET_KEYBINDING_DESC = "Appuyez sur la touche Echappement pour effacer le raccourci."
flickerstreak@30 63 KEY_BUTTON1 = "Clic gauche"
flickerstreak@30 64 KEY_BUTTON2 = "Clic droit"
flickerstreak@30 65 DISABLED = "D\195\169sactiv\195\169"
flickerstreak@30 66 DEFAULT_CONFIRM_MESSAGE = "\195\138tes-vous s\195\187r de vouloir effectuer '%s' ?"
flickerstreak@30 67 elseif GetLocale() == "esES" then
flickerstreak@30 68 CLOSE = "Cerrar"
flickerstreak@30 69 CLOSE_DESC = "Cierra el menú."
flickerstreak@30 70 VALIDATION_ERROR = "Error de validación."
flickerstreak@30 71 USAGE_TOOLTIP = "Uso: %s."
flickerstreak@30 72 RANGE_TOOLTIP = "Puedes desplazarte verticalmente con la rueda del ratón sobre el desplazador."
flickerstreak@30 73 RESET_KEYBINDING_DESC = "Pulsa Escape para borrar la asignación de tecla."
flickerstreak@30 74 KEY_BUTTON1 = "Clic Izquierdo"
flickerstreak@30 75 KEY_BUTTON2 = "Clic Derecho"
flickerstreak@30 76 DISABLED = "Desactivado"
flickerstreak@30 77 DEFAULT_CONFIRM_MESSAGE = "¿Estás seguro de querer realizar `%s'?"
flickerstreak@30 78 elseif GetLocale() == "zhTW" then
flickerstreak@30 79 CLOSE = "關閉"
flickerstreak@30 80 CLOSE_DESC = "關閉選單。"
flickerstreak@30 81 VALIDATION_ERROR = "驗證錯誤。"
flickerstreak@30 82 USAGE_TOOLTIP = "用法: %s。"
flickerstreak@30 83 RANGE_TOOLTIP = "你可以在捲動條上使用滑鼠滾輪來捲動。"
flickerstreak@30 84 RESET_KEYBINDING_DESC = "按Esc鍵清除快捷鍵。"
flickerstreak@30 85 KEY_BUTTON1 = "滑鼠左鍵"
flickerstreak@30 86 KEY_BUTTON2 = "滑鼠右鍵"
flickerstreak@30 87 DISABLED = "停用"
flickerstreak@30 88 DEFAULT_CONFIRM_MESSAGE = "是否執行「%s」?"
flickerstreak@30 89 elseif GetLocale() == "zhCN" then
flickerstreak@30 90 CLOSE = "关闭"
flickerstreak@30 91 CLOSE_DESC = "关闭菜单"
flickerstreak@30 92 VALIDATION_ERROR = "验证错误."
flickerstreak@30 93 USAGE_TOOLTIP = "用法: %s."
flickerstreak@30 94 RANGE_TOOLTIP = "你可以在滚动条上使用鼠标滚轮来翻页."
flickerstreak@30 95 RESET_KEYBINDING_DESC = "按ESC键清除按键绑定"
flickerstreak@30 96 KEY_BUTTON1 = "鼠标左键"
flickerstreak@30 97 KEY_BUTTON2 = "鼠标右键"
flickerstreak@30 98 DISABLED = "禁用"
flickerstreak@30 99 DEFAULT_CONFIRM_MESSAGE = "是否执行'%s'?"
flickerstreak@30 100 end
flickerstreak@30 101
flickerstreak@30 102 Dewdrop.KEY_BUTTON1 = KEY_BUTTON1
flickerstreak@30 103 Dewdrop.KEY_BUTTON2 = KEY_BUTTON2
flickerstreak@30 104
flickerstreak@30 105 local function new(...)
flickerstreak@30 106 local t = {}
flickerstreak@30 107 for i = 1, select('#', ...), 2 do
flickerstreak@30 108 local k = select(i, ...)
flickerstreak@30 109 if k then
flickerstreak@30 110 t[k] = select(i+1, ...)
flickerstreak@30 111 else
flickerstreak@30 112 break
flickerstreak@30 113 end
flickerstreak@30 114 end
flickerstreak@30 115 return t
flickerstreak@30 116 end
flickerstreak@30 117
flickerstreak@30 118 local tmp
flickerstreak@30 119 do
flickerstreak@30 120 local t = {}
flickerstreak@30 121 function tmp(...)
flickerstreak@30 122 for k in pairs(t) do
flickerstreak@30 123 t[k] = nil
flickerstreak@30 124 end
flickerstreak@30 125 for i = 1, select('#', ...), 2 do
flickerstreak@30 126 local k = select(i, ...)
flickerstreak@30 127 if k then
flickerstreak@30 128 t[k] = select(i+1, ...)
flickerstreak@30 129 else
flickerstreak@30 130 break
flickerstreak@30 131 end
flickerstreak@30 132 end
flickerstreak@30 133 return t
flickerstreak@30 134 end
flickerstreak@30 135 end
flickerstreak@30 136 local tmp2
flickerstreak@30 137 do
flickerstreak@30 138 local t = {}
flickerstreak@30 139 function tmp2(...)
flickerstreak@30 140 for k in pairs(t) do
flickerstreak@30 141 t[k] = nil
flickerstreak@30 142 end
flickerstreak@30 143 for i = 1, select('#', ...), 2 do
flickerstreak@30 144 local k = select(i, ...)
flickerstreak@30 145 if k then
flickerstreak@30 146 t[k] = select(i+1, ...)
flickerstreak@30 147 else
flickerstreak@30 148 break
flickerstreak@30 149 end
flickerstreak@30 150 end
flickerstreak@30 151 return t
flickerstreak@30 152 end
flickerstreak@30 153 end
flickerstreak@30 154 local levels
flickerstreak@30 155 local buttons
flickerstreak@30 156
flickerstreak@30 157
flickerstreak@30 158 -- Secure frame handling:
flickerstreak@30 159 -- Rather than using secure buttons in the menu (has problems), we have one
flickerstreak@30 160 -- master secureframe that we pop onto menu items on mouseover. This requires
flickerstreak@30 161 -- some dark magic with OnLeave etc, but it's not too bad.
flickerstreak@30 162
flickerstreak@30 163 local secureFrame = CreateFrame("Button", nil, nil, "SecureActionButtonTemplate")
flickerstreak@30 164 secureFrame:Hide()
flickerstreak@30 165
flickerstreak@30 166 local function secureFrame_Show(self)
flickerstreak@30 167 local owner = self.owner
flickerstreak@30 168
flickerstreak@30 169 if self.secure then -- Leftovers from previos owner, clean up! ("Shouldn't" happen but does..)
flickerstreak@30 170 for k,v in pairs(self.secure) do
flickerstreak@30 171 self:SetAttribute(k, nil)
flickerstreak@30 172 end
flickerstreak@30 173 end
flickerstreak@30 174 self.secure = owner.secure; -- Grab hold of new secure data
flickerstreak@30 175
flickerstreak@30 176 local scale = owner:GetEffectiveScale()
flickerstreak@30 177
flickerstreak@30 178 self:SetPoint("TOPLEFT", nil, "BOTTOMLEFT", owner:GetLeft() * scale, owner:GetTop() * scale)
flickerstreak@30 179 self:SetPoint("BOTTOMRIGHT", nil, "BOTTOMLEFT", owner:GetRight() * scale, owner:GetBottom() * scale)
flickerstreak@30 180 self:EnableMouse(true)
flickerstreak@30 181 for k,v in pairs(self.secure) do
flickerstreak@30 182 self:SetAttribute(k, v)
flickerstreak@30 183 end
flickerstreak@30 184
flickerstreak@30 185 secureFrame:SetFrameStrata(owner:GetFrameStrata())
flickerstreak@30 186 secureFrame:SetFrameLevel(owner:GetFrameLevel()+1)
flickerstreak@30 187
flickerstreak@30 188 self:Show()
flickerstreak@30 189 end
flickerstreak@30 190
flickerstreak@30 191 local function secureFrame_Hide(self)
flickerstreak@30 192 self:Hide()
flickerstreak@30 193 if self.secure then
flickerstreak@30 194 for k,v in pairs(self.secure) do
flickerstreak@30 195 self:SetAttribute(k, nil)
flickerstreak@30 196 end
flickerstreak@30 197 end
flickerstreak@30 198 self.secure = nil
flickerstreak@30 199 end
flickerstreak@30 200
flickerstreak@30 201 secureFrame:SetScript("OnEvent",
flickerstreak@30 202 function()
flickerstreak@30 203 if event=="PLAYER_REGEN_ENABLED" then
flickerstreak@30 204 this.combat = false
flickerstreak@30 205 if not this:IsShown() and this.owner then
flickerstreak@30 206 secureFrame_Show(this)
flickerstreak@30 207 end
flickerstreak@30 208 elseif event=="PLAYER_REGEN_DISABLED" then
flickerstreak@30 209 this.combat = true
flickerstreak@30 210 if this:IsShown() then
flickerstreak@30 211 secureFrame_Hide(this)
flickerstreak@30 212 end
flickerstreak@30 213 end
flickerstreak@30 214 end
flickerstreak@30 215 )
flickerstreak@30 216 secureFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
flickerstreak@30 217 secureFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
flickerstreak@30 218
flickerstreak@30 219 secureFrame:SetScript("OnLeave",
flickerstreak@30 220 function()
flickerstreak@30 221 local owner=this.owner
flickerstreak@30 222 this:Deactivate()
flickerstreak@30 223 owner:GetScript("OnLeave")()
flickerstreak@30 224 end
flickerstreak@30 225 )
flickerstreak@30 226
flickerstreak@30 227 secureFrame:HookScript("OnClick",
flickerstreak@30 228 function()
flickerstreak@30 229 local realthis = this
flickerstreak@30 230 this = this.owner
flickerstreak@30 231 this:GetScript("OnClick")()
flickerstreak@30 232 end
flickerstreak@30 233 )
flickerstreak@30 234
flickerstreak@30 235 function secureFrame:IsOwnedBy(frame)
flickerstreak@30 236 return self.owner == frame
flickerstreak@30 237 end
flickerstreak@30 238
flickerstreak@30 239 function secureFrame:Activate(owner)
flickerstreak@30 240 if self.owner then -- "Shouldn't" happen but apparently it does and I cba to troubleshoot...
flickerstreak@30 241 if not self.combat then
flickerstreak@30 242 secureFrame_Hide(self)
flickerstreak@30 243 end
flickerstreak@30 244 end
flickerstreak@30 245 self.owner = owner
flickerstreak@30 246 if not self.combat then
flickerstreak@30 247 secureFrame_Show(self)
flickerstreak@30 248 end
flickerstreak@30 249 end
flickerstreak@30 250
flickerstreak@30 251 function secureFrame:Deactivate()
flickerstreak@30 252 if not self.combat then
flickerstreak@30 253 secureFrame_Hide(self)
flickerstreak@30 254 end
flickerstreak@30 255 self.owner = nil
flickerstreak@30 256 end
flickerstreak@30 257
flickerstreak@30 258 -- END secure frame utilities
flickerstreak@30 259
flickerstreak@30 260
flickerstreak@30 261 -- Underline on mouseover - use a single global underline that we move around, no point in creating lots of copies
flickerstreak@30 262 local underlineFrame = CreateFrame("Frame", nil)
flickerstreak@30 263 underlineFrame.tx = underlineFrame:CreateTexture()
flickerstreak@30 264 underlineFrame.tx:SetTexture(1,1,0.5,0.75)
flickerstreak@30 265 underlineFrame:SetScript("OnHide", function(this) this:Hide(); end)
flickerstreak@30 266 underlineFrame:SetScript("OnShow", function(this) -- change sizing on the fly to catch runtime uiscale changes
flickerstreak@30 267 underlineFrame.tx:SetPoint("TOPLEFT", -1, -2/this:GetEffectiveScale())
flickerstreak@30 268 underlineFrame.tx:SetPoint("RIGHT", 1,0)
flickerstreak@30 269 underlineFrame.tx:SetHeight(0.6 / this:GetEffectiveScale());
flickerstreak@30 270 end)
flickerstreak@30 271 underlineFrame:SetHeight(1)
flickerstreak@30 272
flickerstreak@30 273 -- END underline on mouseover
flickerstreak@30 274
flickerstreak@30 275
flickerstreak@30 276 local function GetScaledCursorPosition()
flickerstreak@30 277 local x, y = GetCursorPosition()
flickerstreak@30 278 local scale = UIParent:GetEffectiveScale()
flickerstreak@30 279 return x / scale, y / scale
flickerstreak@30 280 end
flickerstreak@30 281
flickerstreak@30 282 local function StartCounting(self, level)
flickerstreak@30 283 for i = level, 1, -1 do
flickerstreak@30 284 if levels[i] then
flickerstreak@30 285 levels[i].count = 3
flickerstreak@30 286 end
flickerstreak@30 287 end
flickerstreak@30 288 end
flickerstreak@30 289
flickerstreak@30 290 local function StopCounting(self, level)
flickerstreak@30 291 for i = level, 1, -1 do
flickerstreak@30 292 if levels[i] then
flickerstreak@30 293 levels[i].count = nil
flickerstreak@30 294 end
flickerstreak@30 295 end
flickerstreak@30 296 end
flickerstreak@30 297
flickerstreak@30 298 local function OnUpdate(self, elapsed)
flickerstreak@30 299 for _,level in ipairs(levels) do
flickerstreak@30 300 local count = level.count
flickerstreak@30 301 if count then
flickerstreak@30 302 count = count - elapsed
flickerstreak@30 303 if count < 0 then
flickerstreak@30 304 level.count = nil
flickerstreak@30 305 self:Close(level.num)
flickerstreak@30 306 else
flickerstreak@30 307 level.count = count
flickerstreak@30 308 end
flickerstreak@30 309 end
flickerstreak@30 310 end
flickerstreak@30 311 end
flickerstreak@30 312
flickerstreak@30 313 local function CheckDualMonitor(self, frame)
flickerstreak@30 314 local ratio = GetScreenWidth() / GetScreenHeight()
flickerstreak@30 315 if ratio >= 2.4 and frame:GetRight() > GetScreenWidth() / 2 and frame:GetLeft() < GetScreenWidth() / 2 then
flickerstreak@30 316 local offsetx
flickerstreak@30 317 if GetCursorPosition() / GetScreenHeight() * 768 < GetScreenWidth() / 2 then
flickerstreak@30 318 offsetx = GetScreenWidth() / 2 - frame:GetRight()
flickerstreak@30 319 else
flickerstreak@30 320 offsetx = GetScreenWidth() / 2 - frame:GetLeft()
flickerstreak@30 321 end
flickerstreak@30 322 local point, parent, relativePoint, x, y = frame:GetPoint(1)
flickerstreak@30 323 frame:SetPoint(point, parent, relativePoint, (x or 0) + offsetx, y or 0)
flickerstreak@30 324 end
flickerstreak@30 325 end
flickerstreak@30 326
flickerstreak@30 327 local function CheckSize(self, level)
flickerstreak@30 328 if not level.buttons then
flickerstreak@30 329 return
flickerstreak@30 330 end
flickerstreak@30 331 local height = 20
flickerstreak@30 332 for _, button in ipairs(level.buttons) do
flickerstreak@30 333 height = height + button:GetHeight()
flickerstreak@30 334 end
flickerstreak@30 335 level:SetHeight(height)
flickerstreak@30 336 local width = 160
flickerstreak@30 337 for _, button in ipairs(level.buttons) do
flickerstreak@30 338 local extra = 1
flickerstreak@30 339 if button.hasArrow or button.hasColorSwatch then
flickerstreak@30 340 extra = extra + 16
flickerstreak@30 341 end
flickerstreak@30 342 if not button.notCheckable then
flickerstreak@30 343 extra = extra + 24
flickerstreak@30 344 end
flickerstreak@30 345 button.text:SetFont(STANDARD_TEXT_FONT, button.textHeight)
flickerstreak@30 346 if button.text:GetWidth() + extra > width then
flickerstreak@30 347 width = button.text:GetWidth() + extra
flickerstreak@30 348 end
flickerstreak@30 349 end
flickerstreak@30 350 level:SetWidth(width + 20)
flickerstreak@30 351 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
flickerstreak@30 352 level:ClearAllPoints()
flickerstreak@30 353 local parent = level.parent or level:GetParent()
flickerstreak@30 354 if type(parent) ~= "table" then
flickerstreak@30 355 parent = UIParent
flickerstreak@30 356 end
flickerstreak@30 357 if level.lastDirection == "RIGHT" then
flickerstreak@30 358 if level.lastVDirection == "DOWN" then
flickerstreak@30 359 level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 360 else
flickerstreak@30 361 level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 362 end
flickerstreak@30 363 else
flickerstreak@30 364 if level.lastVDirection == "DOWN" then
flickerstreak@30 365 level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 366 else
flickerstreak@30 367 level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 368 end
flickerstreak@30 369 end
flickerstreak@30 370 end
flickerstreak@30 371 local dirty = false
flickerstreak@30 372 if not level:GetRight() then
flickerstreak@30 373 self:Close()
flickerstreak@30 374 return
flickerstreak@30 375 end
flickerstreak@30 376 if level:GetRight() > GetScreenWidth() and level.lastDirection == "RIGHT" then
flickerstreak@30 377 level.lastDirection = "LEFT"
flickerstreak@30 378 dirty = true
flickerstreak@30 379 elseif level:GetLeft() < 0 and level.lastDirection == "LEFT" then
flickerstreak@30 380 level.lastDirection = "RIGHT"
flickerstreak@30 381 dirty = true
flickerstreak@30 382 end
flickerstreak@30 383 if level:GetTop() > GetScreenHeight() and level.lastVDirection == "UP" then
flickerstreak@30 384 level.lastVDirection = "DOWN"
flickerstreak@30 385 dirty = true
flickerstreak@30 386 elseif level:GetBottom() < 0 and level.lastVDirection == "DOWN" then
flickerstreak@30 387 level.lastVDirection = "UP"
flickerstreak@30 388 dirty = true
flickerstreak@30 389 end
flickerstreak@30 390 if dirty then
flickerstreak@30 391 level:ClearAllPoints()
flickerstreak@30 392 local parent = level.parent or level:GetParent()
flickerstreak@30 393 if type(parent) ~= "table" then
flickerstreak@30 394 parent = UIParent
flickerstreak@30 395 end
flickerstreak@30 396 if level.lastDirection == "RIGHT" then
flickerstreak@30 397 if level.lastVDirection == "DOWN" then
flickerstreak@30 398 level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 399 else
flickerstreak@30 400 level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 401 end
flickerstreak@30 402 else
flickerstreak@30 403 if level.lastVDirection == "DOWN" then
flickerstreak@30 404 level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 405 else
flickerstreak@30 406 level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 407 end
flickerstreak@30 408 end
flickerstreak@30 409 end
flickerstreak@30 410 if level:GetTop() > GetScreenHeight() then
flickerstreak@30 411 local top = level:GetTop()
flickerstreak@30 412 local point, parent, relativePoint, x, y = level:GetPoint(1)
flickerstreak@30 413 level:ClearAllPoints()
flickerstreak@30 414 level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) + GetScreenHeight() - top)
flickerstreak@30 415 elseif level:GetBottom() < 0 then
flickerstreak@30 416 local bottom = level:GetBottom()
flickerstreak@30 417 local point, parent, relativePoint, x, y = level:GetPoint(1)
flickerstreak@30 418 level:ClearAllPoints()
flickerstreak@30 419 level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) - bottom)
flickerstreak@30 420 end
flickerstreak@30 421 CheckDualMonitor(self, level)
flickerstreak@30 422 if mod(level.num, 5) == 0 then
flickerstreak@30 423 local left, bottom = level:GetLeft(), level:GetBottom()
flickerstreak@30 424 level:ClearAllPoints()
flickerstreak@30 425 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
flickerstreak@30 426 end
flickerstreak@30 427 end
flickerstreak@30 428
flickerstreak@30 429 local Open
flickerstreak@30 430 local OpenSlider
flickerstreak@30 431 local OpenEditBox
flickerstreak@30 432 local Refresh
flickerstreak@30 433 local Clear
flickerstreak@30 434 local function ReleaseButton(self, level, index)
flickerstreak@30 435 if not level.buttons then
flickerstreak@30 436 return
flickerstreak@30 437 end
flickerstreak@30 438 if not level.buttons[index] then
flickerstreak@30 439 return
flickerstreak@30 440 end
flickerstreak@30 441 local button = level.buttons[index]
flickerstreak@30 442 button:Hide()
flickerstreak@30 443 if button.highlight then
flickerstreak@30 444 button.highlight:Hide()
flickerstreak@30 445 end
flickerstreak@30 446 -- button.arrow:SetVertexColor(1, 1, 1)
flickerstreak@30 447 -- button.arrow:SetHeight(16)
flickerstreak@30 448 -- button.arrow:SetWidth(16)
flickerstreak@30 449 table.remove(level.buttons, index)
flickerstreak@30 450 table.insert(buttons, button)
flickerstreak@30 451 for k in pairs(button) do
flickerstreak@30 452 if k ~= 0 and k ~= "text" and k ~= "check" and k ~= "arrow" and k ~= "colorSwatch" and k ~= "highlight" and k ~= "radioHighlight" then
flickerstreak@30 453 button[k] = nil
flickerstreak@30 454 end
flickerstreak@30 455 end
flickerstreak@30 456 return true
flickerstreak@30 457 end
flickerstreak@30 458
flickerstreak@30 459 local function Scroll(self, level, down)
flickerstreak@30 460 if down then
flickerstreak@30 461 if level:GetBottom() < 0 then
flickerstreak@30 462 local point, parent, relativePoint, x, y = level:GetPoint(1)
flickerstreak@30 463 level:SetPoint(point, parent, relativePoint, x, y + 50)
flickerstreak@30 464 if level:GetBottom() > 0 then
flickerstreak@30 465 level:SetPoint(point, parent, relativePoint, x, y + 50 - level:GetBottom())
flickerstreak@30 466 end
flickerstreak@30 467 end
flickerstreak@30 468 else
flickerstreak@30 469 if level:GetTop() > GetScreenHeight() then
flickerstreak@30 470 local point, parent, relativePoint, x, y = level:GetPoint(1)
flickerstreak@30 471 level:SetPoint(point, parent, relativePoint, x, y - 50)
flickerstreak@30 472 if level:GetTop() < GetScreenHeight() then
flickerstreak@30 473 level:SetPoint(point, parent, relativePoint, x, y - 50 + GetScreenHeight() - level:GetTop())
flickerstreak@30 474 end
flickerstreak@30 475 end
flickerstreak@30 476 end
flickerstreak@30 477 end
flickerstreak@30 478
flickerstreak@30 479 local function getArgs(t, str, num, ...)
flickerstreak@30 480 local x = t[str .. num]
flickerstreak@30 481 if x == nil then
flickerstreak@30 482 return ...
flickerstreak@30 483 else
flickerstreak@30 484 return x, getArgs(t, str, num + 1, ...)
flickerstreak@30 485 end
flickerstreak@30 486 end
flickerstreak@30 487
flickerstreak@30 488 local sliderFrame
flickerstreak@30 489 local editBoxFrame
flickerstreak@30 490
flickerstreak@30 491 local normalFont
flickerstreak@30 492 local lastSetFont
flickerstreak@30 493 local justSetFont = false
flickerstreak@30 494 local regionTmp = {}
flickerstreak@30 495 local function fillRegionTmp(...)
flickerstreak@30 496 for i = 1, select('#', ...) do
flickerstreak@30 497 regionTmp[i] = select(i, ...)
flickerstreak@30 498 end
flickerstreak@30 499 end
flickerstreak@30 500
flickerstreak@30 501 local function showGameTooltip(this)
flickerstreak@30 502 if this.tooltipTitle or this.tooltipText then
flickerstreak@30 503 GameTooltip_SetDefaultAnchor(GameTooltip, this)
flickerstreak@30 504 local disabled = not this.isTitle and this.disabled
flickerstreak@30 505 local font
flickerstreak@30 506 if this.tooltipTitle then
flickerstreak@30 507 if SharedMedia and SharedMedia:IsValid("font", this.tooltipTitle) then
flickerstreak@30 508 font = SharedMedia:Fetch("font", this.tooltipTitle)
flickerstreak@30 509 end
flickerstreak@30 510 if disabled then
flickerstreak@30 511 GameTooltip:SetText(this.tooltipTitle, 0.5, 0.5, 0.5, 1)
flickerstreak@30 512 else
flickerstreak@30 513 GameTooltip:SetText(this.tooltipTitle, 1, 1, 1, 1)
flickerstreak@30 514 end
flickerstreak@30 515 if this.tooltipText then
flickerstreak@30 516 if not font and SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
flickerstreak@30 517 font = SharedMedia:Fetch("font", this.tooltipText)
flickerstreak@30 518 end
flickerstreak@30 519 if disabled then
flickerstreak@30 520 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)
flickerstreak@30 521 else
flickerstreak@30 522 GameTooltip:AddLine(this.tooltipText, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
flickerstreak@30 523 end
flickerstreak@30 524 end
flickerstreak@30 525 else
flickerstreak@30 526 if SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
flickerstreak@30 527 font = SharedMedia:Fetch("font", this.tooltipText)
flickerstreak@30 528 end
flickerstreak@30 529 if disabled then
flickerstreak@30 530 GameTooltip:SetText(this.tooltipText, 0.5, 0.5, 0.5, 1)
flickerstreak@30 531 else
flickerstreak@30 532 GameTooltip:SetText(this.tooltipText, 1, 1, 1, 1)
flickerstreak@30 533 end
flickerstreak@30 534 end
flickerstreak@30 535 if font then
flickerstreak@30 536 fillRegionTmp(GameTooltip:GetRegions())
flickerstreak@30 537 lastSetFont = font
flickerstreak@30 538 justSetFont = true
flickerstreak@30 539 for i,v in ipairs(regionTmp) do
flickerstreak@30 540 if v.SetFont then
flickerstreak@30 541 local norm,size,outline = v:GetFont()
flickerstreak@30 542 v:SetFont(font, size, outline)
flickerstreak@30 543 if not normalFont then
flickerstreak@30 544 normalFont = norm
flickerstreak@30 545 end
flickerstreak@30 546 end
flickerstreak@30 547 regionTmp[i] = nil
flickerstreak@30 548 end
flickerstreak@30 549 elseif not normalFont then
flickerstreak@30 550 fillRegionTmp(GameTooltip:GetRegions())
flickerstreak@30 551 for i,v in ipairs(regionTmp) do
flickerstreak@30 552 if v.GetFont and not normalFont then
flickerstreak@30 553 normalFont = v:GetFont()
flickerstreak@30 554 end
flickerstreak@30 555 regionTmp[i] = nil
flickerstreak@30 556 end
flickerstreak@30 557 end
flickerstreak@30 558 GameTooltip:Show()
flickerstreak@30 559 end
flickerstreak@30 560 if this.tooltipFunc then
flickerstreak@30 561 GameTooltip:SetOwner(this, "ANCHOR_NONE")
flickerstreak@30 562 GameTooltip:SetPoint("TOPLEFT", this, "TOPRIGHT", 5, 0)
flickerstreak@30 563 this.tooltipFunc(getArgs(this, 'tooltipArg', 1))
flickerstreak@30 564 GameTooltip:Show()
flickerstreak@30 565 end
flickerstreak@30 566 end
flickerstreak@30 567
flickerstreak@30 568 local tmpt = setmetatable({}, {mode='v'})
flickerstreak@30 569 local numButtons = 0
flickerstreak@30 570 local function AcquireButton(self, level)
flickerstreak@30 571 if not levels[level] then
flickerstreak@30 572 return
flickerstreak@30 573 end
flickerstreak@30 574 level = levels[level]
flickerstreak@30 575 if not level.buttons then
flickerstreak@30 576 level.buttons = {}
flickerstreak@30 577 end
flickerstreak@30 578 local button
flickerstreak@30 579 if #buttons == 0 then
flickerstreak@30 580 numButtons = numButtons + 1
flickerstreak@30 581 button = CreateFrame("Button", "Dewdrop20Button" .. numButtons, nil)
flickerstreak@30 582 button:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 583 button:SetHeight(16)
flickerstreak@30 584 local highlight = button:CreateTexture(nil, "BACKGROUND")
flickerstreak@30 585 highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
flickerstreak@30 586 button.highlight = highlight
flickerstreak@30 587 highlight:SetBlendMode("ADD")
flickerstreak@30 588 highlight:SetAllPoints(button)
flickerstreak@30 589 highlight:Hide()
flickerstreak@30 590 local check = button:CreateTexture(nil, "ARTWORK")
flickerstreak@30 591 button.check = check
flickerstreak@30 592 check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
flickerstreak@30 593 check:SetPoint("CENTER", button, "LEFT", 12, 0)
flickerstreak@30 594 check:SetWidth(24)
flickerstreak@30 595 check:SetHeight(24)
flickerstreak@30 596 local radioHighlight = button:CreateTexture(nil, "ARTWORK")
flickerstreak@30 597 button.radioHighlight = radioHighlight
flickerstreak@30 598 radioHighlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
flickerstreak@30 599 radioHighlight:SetAllPoints(check)
flickerstreak@30 600 radioHighlight:SetBlendMode("ADD")
flickerstreak@30 601 radioHighlight:SetTexCoord(0.5, 0.75, 0, 1)
flickerstreak@30 602 radioHighlight:Hide()
flickerstreak@30 603 button:SetScript("OnEnter", function()
flickerstreak@30 604 if (sliderFrame and sliderFrame:IsShown() and sliderFrame.mouseDown and sliderFrame.level == this.level.num + 1) or (editBoxFrame and editBoxFrame:IsShown() and editBoxFrame.mouseDown and editBoxFrame.level == this.level.num + 1) then
flickerstreak@30 605 for i = 1, this.level.num do
flickerstreak@30 606 Refresh(self, levels[i])
flickerstreak@30 607 end
flickerstreak@30 608 return
flickerstreak@30 609 end
flickerstreak@30 610 self:Close(this.level.num + 1)
flickerstreak@30 611 if not this.disabled then
flickerstreak@30 612 if this.secure then
flickerstreak@30 613 secureFrame:Activate(this)
flickerstreak@30 614 elseif this.hasSlider then
flickerstreak@30 615 OpenSlider(self, this)
flickerstreak@30 616 elseif this.hasEditBox then
flickerstreak@30 617 OpenEditBox(self, this)
flickerstreak@30 618 elseif this.hasArrow then
flickerstreak@30 619 Open(self, this, nil, this.level.num + 1, this.value)
flickerstreak@30 620 end
flickerstreak@30 621 end
flickerstreak@30 622 if not this.level then -- button reclaimed
flickerstreak@30 623 return
flickerstreak@30 624 end
flickerstreak@30 625 StopCounting(self, this.level.num + 1)
flickerstreak@30 626 if not this.disabled then
flickerstreak@30 627 highlight:Show()
flickerstreak@30 628 if this.isRadio then
flickerstreak@30 629 button.radioHighlight:Show()
flickerstreak@30 630 end
flickerstreak@30 631 if this.mouseoverUnderline then
flickerstreak@30 632 underlineFrame:SetParent(this)
flickerstreak@30 633 underlineFrame:SetPoint("BOTTOMLEFT",this.text,0,0)
flickerstreak@30 634 underlineFrame:SetWidth(this.text:GetWidth())
flickerstreak@30 635 underlineFrame:Show()
flickerstreak@30 636 end
flickerstreak@30 637 end
flickerstreak@30 638 showGameTooltip(this)
flickerstreak@30 639 end)
flickerstreak@30 640 button:SetScript("OnHide", function()
flickerstreak@30 641 if this.secure and secureFrame:IsOwnedBy(this) then
flickerstreak@30 642 secureFrame:Deactivate()
flickerstreak@30 643 end
flickerstreak@30 644 end)
flickerstreak@30 645 button:SetScript("OnLeave", function()
flickerstreak@30 646 if this.secure and secureFrame:IsShown() then
flickerstreak@30 647 return; -- it's ok, we didn't actually mouse out of the button, only onto the secure frame on top of it
flickerstreak@30 648 end
flickerstreak@30 649 underlineFrame:Hide()
flickerstreak@30 650 if not this.selected then
flickerstreak@30 651 highlight:Hide()
flickerstreak@30 652 end
flickerstreak@30 653 button.radioHighlight:Hide()
flickerstreak@30 654 if this.level then
flickerstreak@30 655 StartCounting(self, this.level.num)
flickerstreak@30 656 end
flickerstreak@30 657 GameTooltip:Hide()
flickerstreak@30 658 end)
flickerstreak@30 659 local first = true
flickerstreak@30 660 button:SetScript("OnClick", function()
flickerstreak@30 661 if not this.disabled then
flickerstreak@30 662 if this.hasColorSwatch then
flickerstreak@30 663 local func = button.colorFunc
flickerstreak@30 664 local hasOpacity = this.hasOpacity
flickerstreak@30 665 local this = this
flickerstreak@30 666 for k in pairs(tmpt) do
flickerstreak@30 667 tmpt[k] = nil
flickerstreak@30 668 end
flickerstreak@30 669 for i = 1, 1000 do
flickerstreak@30 670 local x = this['colorArg'..i]
flickerstreak@30 671 if x == nil then
flickerstreak@30 672 break
flickerstreak@30 673 else
flickerstreak@30 674 tmpt[i] = x
flickerstreak@30 675 end
flickerstreak@30 676 end
flickerstreak@30 677 ColorPickerFrame.func = function()
flickerstreak@30 678 if func then
flickerstreak@30 679 local r,g,b = ColorPickerFrame:GetColorRGB()
flickerstreak@30 680 local a = hasOpacity and 1 - OpacitySliderFrame:GetValue() or nil
flickerstreak@30 681 local n = #tmpt
flickerstreak@30 682 tmpt[n+1] = r
flickerstreak@30 683 tmpt[n+2] = g
flickerstreak@30 684 tmpt[n+3] = b
flickerstreak@30 685 tmpt[n+4] = a
flickerstreak@30 686 func(unpack(tmpt))
flickerstreak@30 687 tmpt[n+1] = nil
flickerstreak@30 688 tmpt[n+2] = nil
flickerstreak@30 689 tmpt[n+3] = nil
flickerstreak@30 690 tmpt[n+4] = nil
flickerstreak@30 691 end
flickerstreak@30 692 end
flickerstreak@30 693 ColorPickerFrame.hasOpacity = this.hasOpacity
flickerstreak@30 694 ColorPickerFrame.opacityFunc = ColorPickerFrame.func
flickerstreak@30 695 ColorPickerFrame.opacity = 1 - this.opacity
flickerstreak@30 696 ColorPickerFrame:SetColorRGB(this.r, this.g, this.b)
flickerstreak@30 697 local r, g, b, a = this.r, this.g, this.b, this.opacity
flickerstreak@30 698 ColorPickerFrame.cancelFunc = function()
flickerstreak@30 699 if func then
flickerstreak@30 700 local n = #tmpt
flickerstreak@30 701 tmpt[n+1] = r
flickerstreak@30 702 tmpt[n+2] = g
flickerstreak@30 703 tmpt[n+3] = b
flickerstreak@30 704 tmpt[n+4] = a
flickerstreak@30 705 func(unpack(tmpt))
flickerstreak@30 706 for i = 1, n+4 do
flickerstreak@30 707 tmpt[i] = nil
flickerstreak@30 708 end
flickerstreak@30 709 end
flickerstreak@30 710 end
flickerstreak@30 711 self:Close(1)
flickerstreak@30 712 ShowUIPanel(ColorPickerFrame)
flickerstreak@30 713 elseif this.func then
flickerstreak@30 714 local level = this.level
flickerstreak@30 715 if type(this.func) == "string" then
flickerstreak@30 716 if type(this.arg1[this.func]) ~= "function" then
flickerstreak@30 717 self:error("Cannot call method %q", this.func)
flickerstreak@30 718 end
flickerstreak@30 719 this.arg1[this.func](this.arg1, getArgs(this, 'arg', 2))
flickerstreak@30 720 else
flickerstreak@30 721 this.func(getArgs(this, 'arg', 1))
flickerstreak@30 722 end
flickerstreak@30 723 if this.closeWhenClicked then
flickerstreak@30 724 self:Close()
flickerstreak@30 725 elseif level:IsShown() then
flickerstreak@30 726 for i = 1, level.num do
flickerstreak@30 727 Refresh(self, levels[i])
flickerstreak@30 728 end
flickerstreak@30 729 local value = levels[level.num].value
flickerstreak@30 730 for i = level.num-1, 1, -1 do
flickerstreak@30 731 local level = levels[i]
flickerstreak@30 732 local good = false
flickerstreak@30 733 for _,button in ipairs(level.buttons) do
flickerstreak@30 734 if button.value == value then
flickerstreak@30 735 good = true
flickerstreak@30 736 break
flickerstreak@30 737 end
flickerstreak@30 738 end
flickerstreak@30 739 if not good then
flickerstreak@30 740 Dewdrop:Close(i+1)
flickerstreak@30 741 end
flickerstreak@30 742 value = levels[i].value
flickerstreak@30 743 end
flickerstreak@30 744 end
flickerstreak@30 745 elseif this.closeWhenClicked then
flickerstreak@30 746 self:Close()
flickerstreak@30 747 end
flickerstreak@30 748 end
flickerstreak@30 749 end)
flickerstreak@30 750 local text = button:CreateFontString(nil, "ARTWORK")
flickerstreak@30 751 button.text = text
flickerstreak@30 752 text:SetFontObject(GameFontHighlightSmall)
flickerstreak@30 753 button.text:SetFont(STANDARD_TEXT_FONT, UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT)
flickerstreak@30 754 button:SetScript("OnMouseDown", function()
flickerstreak@30 755 if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then
flickerstreak@30 756 text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 1 or 25, -1)
flickerstreak@30 757 end
flickerstreak@30 758 end)
flickerstreak@30 759 button:SetScript("OnMouseUp", function()
flickerstreak@30 760 if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then
flickerstreak@30 761 text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 0 or 24, 0)
flickerstreak@30 762 end
flickerstreak@30 763 end)
flickerstreak@30 764 local arrow = button:CreateTexture(nil, "ARTWORK")
flickerstreak@30 765 button.arrow = arrow
flickerstreak@30 766 arrow:SetPoint("LEFT", button, "RIGHT", -16, 0)
flickerstreak@30 767 arrow:SetWidth(16)
flickerstreak@30 768 arrow:SetHeight(16)
flickerstreak@30 769 arrow:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
flickerstreak@30 770 local colorSwatch = button:CreateTexture(nil, "ARTWORK")
flickerstreak@30 771 button.colorSwatch = colorSwatch
flickerstreak@30 772 colorSwatch:SetWidth(20)
flickerstreak@30 773 colorSwatch:SetHeight(20)
flickerstreak@30 774 colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
flickerstreak@30 775 local texture = button:CreateTexture(nil, "OVERLAY")
flickerstreak@30 776 colorSwatch.texture = texture
flickerstreak@30 777 texture:SetTexture("Interface\\Buttons\\WHITE8X8")
flickerstreak@30 778 texture:SetWidth(11.5)
flickerstreak@30 779 texture:SetHeight(11.5)
flickerstreak@30 780 texture:Show()
flickerstreak@30 781 texture:SetPoint("CENTER", colorSwatch, "CENTER")
flickerstreak@30 782 colorSwatch:SetPoint("RIGHT", button, "RIGHT", 0, 0)
flickerstreak@30 783 else
flickerstreak@30 784 button = table.remove(buttons)
flickerstreak@30 785 end
flickerstreak@30 786 button:ClearAllPoints()
flickerstreak@30 787 button:SetParent(level)
flickerstreak@30 788 button:SetFrameStrata(level:GetFrameStrata())
flickerstreak@30 789 button:SetFrameLevel(level:GetFrameLevel() + 1)
flickerstreak@30 790 button:SetPoint("LEFT", level, "LEFT", 10, 0)
flickerstreak@30 791 button:SetPoint("RIGHT", level, "RIGHT", -10, 0)
flickerstreak@30 792 if #level.buttons == 0 then
flickerstreak@30 793 button:SetPoint("TOP", level, "TOP", 0, -10)
flickerstreak@30 794 else
flickerstreak@30 795 button:SetPoint("TOP", level.buttons[#level.buttons], "BOTTOM", 0, 0)
flickerstreak@30 796 end
flickerstreak@30 797 button.text:SetPoint("LEFT", button, "LEFT", 24, 0)
flickerstreak@30 798 button:Show()
flickerstreak@30 799 button.level = level
flickerstreak@30 800 table.insert(level.buttons, button)
flickerstreak@30 801 if not level.parented then
flickerstreak@30 802 level.parented = true
flickerstreak@30 803 level:ClearAllPoints()
flickerstreak@30 804 if level.num == 1 then
flickerstreak@30 805 if level.parent ~= UIParent and type(level.parent) == "table" then
flickerstreak@30 806 level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT")
flickerstreak@30 807 else
flickerstreak@30 808 level:SetPoint("CENTER", UIParent, "CENTER")
flickerstreak@30 809 end
flickerstreak@30 810 else
flickerstreak@30 811 if level.lastDirection == "RIGHT" then
flickerstreak@30 812 if level.lastVDirection == "DOWN" then
flickerstreak@30 813 level:SetPoint("TOPLEFT", level.parent, "TOPRIGHT", 5, 10)
flickerstreak@30 814 else
flickerstreak@30 815 level:SetPoint("BOTTOMLEFT", level.parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 816 end
flickerstreak@30 817 else
flickerstreak@30 818 if level.lastVDirection == "DOWN" then
flickerstreak@30 819 level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT", -5, 10)
flickerstreak@30 820 else
flickerstreak@30 821 level:SetPoint("BOTTOMRIGHT", level.parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 822 end
flickerstreak@30 823 end
flickerstreak@30 824 end
flickerstreak@30 825 level:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 826 end
flickerstreak@30 827 button:SetAlpha(1)
flickerstreak@30 828 return button
flickerstreak@30 829 end
flickerstreak@30 830
flickerstreak@30 831 local numLevels = 0
flickerstreak@30 832 local function AcquireLevel(self, level)
flickerstreak@30 833 if not levels[level] then
flickerstreak@30 834 for i = #levels + 1, level, -1 do
flickerstreak@30 835 local i = i
flickerstreak@30 836 numLevels = numLevels + 1
flickerstreak@30 837 local frame = CreateFrame("Button", "Dewdrop20Level" .. numLevels, nil)
flickerstreak@30 838 if i == 1 then
flickerstreak@30 839 local old_CloseSpecialWindows = CloseSpecialWindows
flickerstreak@30 840 function CloseSpecialWindows()
flickerstreak@30 841 local found = old_CloseSpecialWindows()
flickerstreak@30 842 if levels[1]:IsShown() then
flickerstreak@30 843 self:Close()
flickerstreak@30 844 return 1
flickerstreak@30 845 end
flickerstreak@30 846 return found
flickerstreak@30 847 end
flickerstreak@30 848 end
flickerstreak@30 849 levels[i] = frame
flickerstreak@30 850 frame.num = i
flickerstreak@30 851 frame:SetParent(UIParent)
flickerstreak@30 852 frame:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 853 frame:Hide()
flickerstreak@30 854 frame:SetWidth(180)
flickerstreak@30 855 frame:SetHeight(10)
flickerstreak@30 856 frame:SetFrameLevel(i * 3)
flickerstreak@30 857 frame:SetScript("OnHide", function()
flickerstreak@30 858 self:Close(level + 1)
flickerstreak@30 859 end)
flickerstreak@30 860 if frame.SetTopLevel then
flickerstreak@30 861 frame:SetTopLevel(true)
flickerstreak@30 862 end
flickerstreak@30 863 frame:EnableMouse(true)
flickerstreak@30 864 frame:EnableMouseWheel(true)
flickerstreak@30 865 local backdrop = CreateFrame("Frame", nil, frame)
flickerstreak@30 866 backdrop:SetAllPoints(frame)
flickerstreak@30 867 backdrop:SetBackdrop(tmp(
flickerstreak@30 868 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
flickerstreak@30 869 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
flickerstreak@30 870 'tile', true,
flickerstreak@30 871 'insets', tmp2(
flickerstreak@30 872 'left', 5,
flickerstreak@30 873 'right', 5,
flickerstreak@30 874 'top', 5,
flickerstreak@30 875 'bottom', 5
flickerstreak@30 876 ),
flickerstreak@30 877 'tileSize', 16,
flickerstreak@30 878 'edgeSize', 16
flickerstreak@30 879 ))
flickerstreak@30 880 backdrop:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
flickerstreak@30 881 backdrop:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
flickerstreak@30 882 frame:SetScript("OnClick", function()
flickerstreak@30 883 self:Close(i)
flickerstreak@30 884 end)
flickerstreak@30 885 frame:SetScript("OnEnter", function()
flickerstreak@30 886 StopCounting(self, i)
flickerstreak@30 887 end)
flickerstreak@30 888 frame:SetScript("OnLeave", function()
flickerstreak@30 889 StartCounting(self, i)
flickerstreak@30 890 end)
flickerstreak@30 891 frame:SetScript("OnMouseWheel", function()
flickerstreak@30 892 Scroll(self, frame, arg1 < 0)
flickerstreak@30 893 end)
flickerstreak@30 894 if i == 1 then
flickerstreak@30 895 frame:SetScript("OnUpdate", function(this, arg1)
flickerstreak@30 896 OnUpdate(self, arg1)
flickerstreak@30 897 end)
flickerstreak@30 898 levels[1].lastDirection = "RIGHT"
flickerstreak@30 899 levels[1].lastVDirection = "DOWN"
flickerstreak@30 900 else
flickerstreak@30 901 levels[i].lastDirection = levels[i - 1].lastDirection
flickerstreak@30 902 levels[i].lastVDirection = levels[i - 1].lastVDirection
flickerstreak@30 903 end
flickerstreak@30 904 end
flickerstreak@30 905 end
flickerstreak@30 906 local fullscreenFrame = GetUIPanel("fullscreen")
flickerstreak@30 907 local l = levels[level]
flickerstreak@30 908 local strata, framelevel = l:GetFrameStrata(), l:GetFrameLevel()
flickerstreak@30 909 if fullscreenFrame then
flickerstreak@30 910 l:SetParent(fullscreenFrame)
flickerstreak@30 911 else
flickerstreak@30 912 l:SetParent(UIParent)
flickerstreak@30 913 end
flickerstreak@30 914 l:SetFrameStrata(strata)
flickerstreak@30 915 l:SetFrameLevel(framelevel)
flickerstreak@30 916 l:SetAlpha(1)
flickerstreak@30 917 return l
flickerstreak@30 918 end
flickerstreak@30 919
flickerstreak@30 920 local function validateOptions(options, position, baseOptions, fromPass)
flickerstreak@30 921 if not baseOptions then
flickerstreak@30 922 baseOptions = options
flickerstreak@30 923 end
flickerstreak@30 924 if type(options) ~= "table" then
flickerstreak@30 925 return "Options must be a table.", position
flickerstreak@30 926 end
flickerstreak@30 927 local kind = options.type
flickerstreak@30 928 if type(kind) ~= "string" then
flickerstreak@30 929 return '"type" must be a string.', position
flickerstreak@30 930 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
flickerstreak@30 931 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", "dragLink", or "header".', position
flickerstreak@30 932 end
flickerstreak@30 933 if options.aliases then
flickerstreak@30 934 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
flickerstreak@30 935 return '"alias" must be a table or string', position
flickerstreak@30 936 end
flickerstreak@30 937 end
flickerstreak@30 938 if not fromPass then
flickerstreak@30 939 if kind == "execute" then
flickerstreak@30 940 if type(options.func) ~= "string" and type(options.func) ~= "function" then
flickerstreak@30 941 return '"func" must be a string or function', position
flickerstreak@30 942 end
flickerstreak@30 943 elseif kind == "range" or kind == "text" or kind == "toggle" then
flickerstreak@30 944 if type(options.set) ~= "string" and type(options.set) ~= "function" then
flickerstreak@30 945 return '"set" must be a string or function', position
flickerstreak@30 946 end
flickerstreak@30 947 if kind == "text" and options.get == false then
flickerstreak@30 948 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then
flickerstreak@30 949 return '"get" must be a string or function', position
flickerstreak@30 950 end
flickerstreak@30 951 elseif kind == "group" and options.pass then
flickerstreak@30 952 if options.pass ~= true then
flickerstreak@30 953 return '"pass" must be either nil, true, or false', position
flickerstreak@30 954 end
flickerstreak@30 955 if not options.func then
flickerstreak@30 956 if type(options.set) ~= "string" and type(options.set) ~= "function" then
flickerstreak@30 957 return '"set" must be a string or function', position
flickerstreak@30 958 end
flickerstreak@30 959 if type(options.get) ~= "string" and type(options.get) ~= "function" then
flickerstreak@30 960 return '"get" must be a string or function', position
flickerstreak@30 961 end
flickerstreak@30 962 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then
flickerstreak@30 963 return '"func" must be a string or function', position
flickerstreak@30 964 end
flickerstreak@30 965 end
flickerstreak@30 966 end
flickerstreak@30 967 if options ~= baseOptions then
flickerstreak@30 968 if kind == "header" then
flickerstreak@30 969 elseif type(options.desc) ~= "string" then
flickerstreak@30 970 return '"desc" must be a string', position
flickerstreak@30 971 elseif options.desc:len() == 0 then
flickerstreak@30 972 return '"desc" cannot be a 0-length string', position
flickerstreak@30 973 end
flickerstreak@30 974 end
flickerstreak@30 975 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then
flickerstreak@30 976 if options.type == "header" and not options.cmdName and not options.name then
flickerstreak@30 977 elseif options.cmdName then
flickerstreak@30 978 if type(options.cmdName) ~= "string" then
flickerstreak@30 979 return '"cmdName" must be a string or nil', position
flickerstreak@30 980 elseif options.cmdName:len() == 0 then
flickerstreak@30 981 return '"cmdName" cannot be a 0-length string', position
flickerstreak@30 982 end
flickerstreak@30 983 if type(options.guiName) ~= "string" then
flickerstreak@30 984 if not options.guiNameIsMap then
flickerstreak@30 985 return '"guiName" must be a string or nil', position
flickerstreak@30 986 end
flickerstreak@30 987 elseif options.guiName:len() == 0 then
flickerstreak@30 988 return '"guiName" cannot be a 0-length string', position
flickerstreak@30 989 end
flickerstreak@30 990 else
flickerstreak@30 991 if type(options.name) ~= "string" then
flickerstreak@30 992 return '"name" must be a string', position
flickerstreak@30 993 elseif options.name:len() == 0 then
flickerstreak@30 994 return '"name" cannot be a 0-length string', position
flickerstreak@30 995 end
flickerstreak@30 996 end
flickerstreak@30 997 end
flickerstreak@30 998 if options.guiNameIsMap then
flickerstreak@30 999 if type(options.guiNameIsMap) ~= "boolean" then
flickerstreak@30 1000 return '"guiNameIsMap" must be a boolean or nil', position
flickerstreak@30 1001 elseif options.type ~= "toggle" then
flickerstreak@30 1002 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position
flickerstreak@30 1003 elseif type(options.map) ~= "table" then
flickerstreak@30 1004 return '"map" must be a table', position
flickerstreak@30 1005 end
flickerstreak@30 1006 end
flickerstreak@30 1007 if options.message and type(options.message) ~= "string" then
flickerstreak@30 1008 return '"message" must be a string or nil', position
flickerstreak@30 1009 end
flickerstreak@30 1010 if options.error and type(options.error) ~= "string" then
flickerstreak@30 1011 return '"error" must be a string or nil', position
flickerstreak@30 1012 end
flickerstreak@30 1013 if options.current and type(options.current) ~= "string" then
flickerstreak@30 1014 return '"current" must be a string or nil', position
flickerstreak@30 1015 end
flickerstreak@30 1016 if options.order then
flickerstreak@30 1017 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then
flickerstreak@30 1018 return '"order" must be a non-zero number or nil', position
flickerstreak@30 1019 end
flickerstreak@30 1020 end
flickerstreak@30 1021 if options.disabled then
flickerstreak@30 1022 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then
flickerstreak@30 1023 return '"disabled" must be a function, string, or boolean', position
flickerstreak@30 1024 end
flickerstreak@30 1025 end
flickerstreak@30 1026 if options.cmdHidden then
flickerstreak@30 1027 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then
flickerstreak@30 1028 return '"cmdHidden" must be a function, string, or boolean', position
flickerstreak@30 1029 end
flickerstreak@30 1030 end
flickerstreak@30 1031 if options.guiHidden then
flickerstreak@30 1032 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then
flickerstreak@30 1033 return '"guiHidden" must be a function, string, or boolean', position
flickerstreak@30 1034 end
flickerstreak@30 1035 end
flickerstreak@30 1036 if options.hidden then
flickerstreak@30 1037 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then
flickerstreak@30 1038 return '"hidden" must be a function, string, or boolean', position
flickerstreak@30 1039 end
flickerstreak@30 1040 end
flickerstreak@30 1041 if kind == "text" then
flickerstreak@30 1042 if type(options.validate) == "table" then
flickerstreak@30 1043 local t = options.validate
flickerstreak@30 1044 local iTable = nil
flickerstreak@30 1045 for k,v in pairs(t) do
flickerstreak@30 1046 if type(k) == "number" then
flickerstreak@30 1047 if iTable == nil then
flickerstreak@30 1048 iTable = true
flickerstreak@30 1049 elseif not iTable then
flickerstreak@30 1050 return '"validate" must either have all keys be indexed numbers or strings', position
flickerstreak@30 1051 elseif k < 1 or k > #t then
flickerstreak@30 1052 return '"validate" numeric keys must be indexed properly. >= 1 and <= #t', position
flickerstreak@30 1053 end
flickerstreak@30 1054 else
flickerstreak@30 1055 if iTable == nil then
flickerstreak@30 1056 iTable = false
flickerstreak@30 1057 elseif iTable then
flickerstreak@30 1058 return '"validate" must either have all keys be indexed numbers or strings', position
flickerstreak@30 1059 end
flickerstreak@30 1060 end
flickerstreak@30 1061 if type(v) ~= "string" then
flickerstreak@30 1062 return '"validate" values must all be strings', position
flickerstreak@30 1063 end
flickerstreak@30 1064 end
flickerstreak@30 1065 if options.multiToggle and options.multiToggle ~= true then
flickerstreak@30 1066 return '"multiToggle" must be a boolean or nil if "validate" is a table', position
flickerstreak@30 1067 end
flickerstreak@30 1068 elseif options.validate == "keybinding" then
flickerstreak@30 1069 -- no other checks
flickerstreak@30 1070 else
flickerstreak@30 1071 if type(options.usage) ~= "string" then
flickerstreak@30 1072 return '"usage" must be a string', position
flickerstreak@30 1073 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then
flickerstreak@30 1074 return '"validate" must be a string, function, or table', position
flickerstreak@30 1075 end
flickerstreak@30 1076 end
flickerstreak@30 1077 if options.multiToggle and type(options.validate) ~= "table" then
flickerstreak@30 1078 return '"validate" must be a table if "multiToggle" is true', position
flickerstreak@30 1079 end
flickerstreak@30 1080 elseif kind == "range" then
flickerstreak@30 1081 if options.min or options.max then
flickerstreak@30 1082 if type(options.min) ~= "number" then
flickerstreak@30 1083 return '"min" must be a number', position
flickerstreak@30 1084 elseif type(options.max) ~= "number" then
flickerstreak@30 1085 return '"max" must be a number', position
flickerstreak@30 1086 elseif options.min >= options.max then
flickerstreak@30 1087 return '"min" must be less than "max"', position
flickerstreak@30 1088 end
flickerstreak@30 1089 end
flickerstreak@30 1090 if options.step then
flickerstreak@30 1091 if type(options.step) ~= "number" then
flickerstreak@30 1092 return '"step" must be a number', position
flickerstreak@30 1093 elseif options.step < 0 then
flickerstreak@30 1094 return '"step" must be nonnegative', position
flickerstreak@30 1095 end
flickerstreak@30 1096 end
flickerstreak@30 1097 if options.bigStep then
flickerstreak@30 1098 if type(options.bigStep) ~= "number" then
flickerstreak@30 1099 return '"bigStep" must be a number', position
flickerstreak@30 1100 elseif options.bigStep < 0 then
flickerstreak@30 1101 return '"bigStep" must be nonnegative', position
flickerstreak@30 1102 end
flickerstreak@30 1103 end
flickerstreak@30 1104 if options.isPercent and options.isPercent ~= true then
flickerstreak@30 1105 return '"isPercent" must either be nil, true, or false', position
flickerstreak@30 1106 end
flickerstreak@30 1107 elseif kind == "toggle" then
flickerstreak@30 1108 if options.map then
flickerstreak@30 1109 if type(options.map) ~= "table" then
flickerstreak@30 1110 return '"map" must be a table', position
flickerstreak@30 1111 elseif type(options.map[true]) ~= "string" then
flickerstreak@30 1112 return '"map[true]" must be a string', position
flickerstreak@30 1113 elseif type(options.map[false]) ~= "string" then
flickerstreak@30 1114 return '"map[false]" must be a string', position
flickerstreak@30 1115 end
flickerstreak@30 1116 end
flickerstreak@30 1117 elseif kind == "color" then
flickerstreak@30 1118 if options.hasAlpha and options.hasAlpha ~= true then
flickerstreak@30 1119 return '"hasAlpha" must be nil, true, or false', position
flickerstreak@30 1120 end
flickerstreak@30 1121 elseif kind == "group" then
flickerstreak@30 1122 if options.pass and options.pass ~= true then
flickerstreak@30 1123 return '"pass" must be nil, true, or false', position
flickerstreak@30 1124 end
flickerstreak@30 1125 if type(options.args) ~= "table" then
flickerstreak@30 1126 return '"args" must be a table', position
flickerstreak@30 1127 end
flickerstreak@30 1128 for k,v in pairs(options.args) do
flickerstreak@30 1129 if type(k) ~= "number" then
flickerstreak@30 1130 if type(k) ~= "string" then
flickerstreak@30 1131 return '"args" keys must be strings or numbers', position
flickerstreak@30 1132 elseif k:len() == 0 then
flickerstreak@30 1133 return '"args" keys must not be 0-length strings.', position
flickerstreak@30 1134 end
flickerstreak@30 1135 end
flickerstreak@30 1136 if type(v) ~= "table" then
flickerstreak@30 1137 return '"args" values must be tables', position and position .. "." .. k or k
flickerstreak@30 1138 end
flickerstreak@30 1139 local newposition
flickerstreak@30 1140 if position then
flickerstreak@30 1141 newposition = position .. ".args." .. k
flickerstreak@30 1142 else
flickerstreak@30 1143 newposition = "args." .. k
flickerstreak@30 1144 end
flickerstreak@30 1145 local err, pos = validateOptions(v, newposition, baseOptions, options.pass)
flickerstreak@30 1146 if err then
flickerstreak@30 1147 return err, pos
flickerstreak@30 1148 end
flickerstreak@30 1149 end
flickerstreak@30 1150 elseif kind == "execute" then
flickerstreak@30 1151 if type(options.confirm) ~= "string" and type(options.confirm) ~= "boolean" and type(options.confirm) ~= "nil" then
flickerstreak@30 1152 return '"confirm" must be a string, boolean, or nil', position
flickerstreak@30 1153 end
flickerstreak@30 1154 end
flickerstreak@30 1155 if options.icon and type(options.icon) ~= "string" then
flickerstreak@30 1156 return'"icon" must be a string', position
flickerstreak@30 1157 end
flickerstreak@30 1158 if options.iconWidth or options.iconHeight then
flickerstreak@30 1159 if type(options.iconWidth) ~= "number" or type(options.iconHeight) ~= "number" then
flickerstreak@30 1160 return '"iconHeight" and "iconWidth" must be numbers', position
flickerstreak@30 1161 end
flickerstreak@30 1162 end
flickerstreak@30 1163 if options.iconCoordLeft or options.iconCoordRight or options.iconCoordTop or options.iconCoordBottom then
flickerstreak@30 1164 if type(options.iconCoordLeft) ~= "number" or type(options.iconCoordRight) ~= "number" or type(options.iconCoordTop) ~= "number" or type(options.iconCoordBottom) ~= "number" then
flickerstreak@30 1165 return '"iconCoordLeft", "iconCoordRight", "iconCoordTop", and "iconCoordBottom" must be numbers', position
flickerstreak@30 1166 end
flickerstreak@30 1167 end
flickerstreak@30 1168 end
flickerstreak@30 1169
flickerstreak@30 1170 local validatedOptions
flickerstreak@30 1171
flickerstreak@30 1172 local values
flickerstreak@30 1173 local mysort_args
flickerstreak@30 1174 local mysort
flickerstreak@30 1175 local othersort
flickerstreak@30 1176 local othersort_validate
flickerstreak@30 1177
flickerstreak@30 1178 local baseFunc, currentLevel
flickerstreak@30 1179
flickerstreak@30 1180 local function confirmPopup(message, func, ...)
flickerstreak@30 1181 if not StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"] then
flickerstreak@30 1182 StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"] = {}
flickerstreak@30 1183 end
flickerstreak@30 1184 local t = StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"]
flickerstreak@30 1185 for k in pairs(t) do
flickerstreak@30 1186 t[k] = nil
flickerstreak@30 1187 end
flickerstreak@30 1188 t.text = message
flickerstreak@30 1189 t.button1 = ACCEPT or "Accept"
flickerstreak@30 1190 t.button2 = CANCEL or "Cancel"
flickerstreak@30 1191 t.OnAccept = function()
flickerstreak@30 1192 func(unpack(t))
flickerstreak@30 1193 end
flickerstreak@30 1194 for i = 1, select('#', ...) do
flickerstreak@30 1195 t[i] = select(i, ...)
flickerstreak@30 1196 end
flickerstreak@30 1197 t.timeout = 0
flickerstreak@30 1198 t.whileDead = 1
flickerstreak@30 1199 t.hideOnEscape = 1
flickerstreak@30 1200
flickerstreak@30 1201 Dewdrop:Close()
flickerstreak@30 1202 StaticPopup_Show("DEWDROP20_CONFIRM_DIALOG")
flickerstreak@30 1203 end
flickerstreak@30 1204
flickerstreak@30 1205
flickerstreak@30 1206 local function getMethod(settingname, handler, v, methodName, ...) -- "..." is simply returned straight out cause you can't do "a,b,c = 111,f(),222"
flickerstreak@30 1207 assert(v and type(v)=="table")
flickerstreak@30 1208 assert(methodName and type(methodName)=="string")
flickerstreak@30 1209
flickerstreak@30 1210 local method = v[methodName]
flickerstreak@30 1211 if type(method)=="function" then
flickerstreak@30 1212 return method, ...
flickerstreak@30 1213 elseif type(method)=="string" then
flickerstreak@30 1214 if not handler then
flickerstreak@30 1215 Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
flickerstreak@30 1216 elseif not handler[method] then
flickerstreak@30 1217 Dewdrop:error("[%s] 'handler' method %q not defined", tostring(settingname), method)
flickerstreak@30 1218 end
flickerstreak@30 1219 return handler[method], handler, ...
flickerstreak@30 1220 end
flickerstreak@30 1221
flickerstreak@30 1222 Dewdrop:error("[%s] Missing %q directive", tostring(settingname), methodName)
flickerstreak@30 1223 end
flickerstreak@30 1224
flickerstreak@30 1225 local function callMethod(settingname, handler, v, methodName, ...)
flickerstreak@30 1226 assert(v and type(v)=="table")
flickerstreak@30 1227 assert(methodName and type(methodName)=="string")
flickerstreak@30 1228
flickerstreak@30 1229 local method = v[methodName]
flickerstreak@30 1230 if type(method)=="function" then
flickerstreak@30 1231 local success, ret,ret2,ret3,ret4 = pcall(v[methodName], ...)
flickerstreak@30 1232 if not success then
flickerstreak@30 1233 geterrorhandler()(ret)
flickerstreak@30 1234 return nil
flickerstreak@30 1235 end
flickerstreak@30 1236 return ret,ret2,ret3,ret4
flickerstreak@30 1237
flickerstreak@30 1238 elseif type(method)=="string" then
flickerstreak@30 1239
flickerstreak@30 1240 local neg = method:match("^~(.-)$")
flickerstreak@30 1241 if neg then
flickerstreak@30 1242 method = neg
flickerstreak@30 1243 end
flickerstreak@30 1244 if not handler then
flickerstreak@30 1245 Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
flickerstreak@30 1246 elseif not handler[method] then
flickerstreak@30 1247 Dewdrop:error("[%s] 'handler' (%q) method %q not defined", tostring(settingname), handler.name or "(unnamed)", method)
flickerstreak@30 1248 end
flickerstreak@30 1249 local success, ret,ret2,ret3,ret4 = pcall(handler[method], handler, ...)
flickerstreak@30 1250 if not success then
flickerstreak@30 1251 geterrorhandler()(ret)
flickerstreak@30 1252 return nil
flickerstreak@30 1253 end
flickerstreak@30 1254 if neg then
flickerstreak@30 1255 return not ret
flickerstreak@30 1256 end
flickerstreak@30 1257 return ret,ret2,ret3,ret4
flickerstreak@30 1258 elseif method == false then
flickerstreak@30 1259 return nil
flickerstreak@30 1260 end
flickerstreak@30 1261
flickerstreak@30 1262 Dewdrop:error("[%s] Missing %q directive in %q", tostring(settingname), methodName, v.name or "(unnamed)")
flickerstreak@30 1263 end
flickerstreak@30 1264
flickerstreak@30 1265 local function skip1Nil(...)
flickerstreak@30 1266 if select(1,...)==nil then
flickerstreak@30 1267 return select(2,...)
flickerstreak@30 1268 end
flickerstreak@30 1269 return ...
flickerstreak@30 1270 end
flickerstreak@30 1271
flickerstreak@30 1272 function Dewdrop:FeedAceOptionsTable(options, difference)
flickerstreak@30 1273 self:argCheck(options, 2, "table")
flickerstreak@30 1274 self:argCheck(difference, 3, "nil", "number")
flickerstreak@30 1275 if not currentLevel then
flickerstreak@30 1276 self:error("Cannot call `FeedAceOptionsTable' outside of a Dewdrop declaration")
flickerstreak@30 1277 end
flickerstreak@30 1278 if not difference then
flickerstreak@30 1279 difference = 0
flickerstreak@30 1280 end
flickerstreak@30 1281 if not validatedOptions then
flickerstreak@30 1282 validatedOptions = {}
flickerstreak@30 1283 end
flickerstreak@30 1284 if not validatedOptions[options] then
flickerstreak@30 1285 local err, position = validateOptions(options)
flickerstreak@30 1286
flickerstreak@30 1287 if err then
flickerstreak@30 1288 if position then
flickerstreak@30 1289 Dewdrop:error(position .. ": " .. err)
flickerstreak@30 1290 else
flickerstreak@30 1291 Dewdrop:error(err)
flickerstreak@30 1292 end
flickerstreak@30 1293 end
flickerstreak@30 1294
flickerstreak@30 1295 validatedOptions[options] = true
flickerstreak@30 1296 end
flickerstreak@30 1297 local level = levels[currentLevel]
flickerstreak@30 1298 if not level then
flickerstreak@30 1299 self:error("Improper level given")
flickerstreak@30 1300 end
flickerstreak@30 1301 if not values then
flickerstreak@30 1302 values = {}
flickerstreak@30 1303 else
flickerstreak@30 1304 for k,v in pairs(values) do
flickerstreak@30 1305 values[k] = nil
flickerstreak@30 1306 end
flickerstreak@30 1307 end
flickerstreak@30 1308
flickerstreak@30 1309 local current = level
flickerstreak@30 1310 while current do -- this traverses from higher level numbers to lower, building "values" with leaf nodes first and trunk nodes later
flickerstreak@30 1311 if current.num == difference + 1 then
flickerstreak@30 1312 break
flickerstreak@30 1313 end
flickerstreak@30 1314 table.insert(values, current.value)
flickerstreak@30 1315 current = levels[current.num - 1]
flickerstreak@30 1316 end
flickerstreak@30 1317
flickerstreak@30 1318 local realOptions = options
flickerstreak@30 1319 local handler = options.handler
flickerstreak@30 1320 local passTable
flickerstreak@30 1321 local passValue
flickerstreak@30 1322 while #values > 0 do -- This loop traverses values from the END (trunk nodes first, then onto leaf nodes)
flickerstreak@30 1323 if options.pass then
flickerstreak@30 1324 if options.get and options.set then
flickerstreak@30 1325 passTable = options
flickerstreak@30 1326 elseif not passTable then
flickerstreak@30 1327 passTable = options
flickerstreak@30 1328 end
flickerstreak@30 1329 else
flickerstreak@30 1330 passTable = nil
flickerstreak@30 1331 end
flickerstreak@30 1332 local value = table.remove(values)
flickerstreak@30 1333 options = options.args and options.args[value]
flickerstreak@30 1334 if not options then
flickerstreak@30 1335 return
flickerstreak@30 1336 end
flickerstreak@30 1337 handler = options.handler or handler
flickerstreak@30 1338 passValue = passTable and value or nil
flickerstreak@30 1339 end
flickerstreak@30 1340
flickerstreak@30 1341 if options.type == "group" then
flickerstreak@30 1342 local hidden = options.hidden
flickerstreak@30 1343 if type(hidden) == "function" or type(hidden) == "string" then
flickerstreak@30 1344 hidden = callMethod(options.name or "(options root)", handler, options, "hidden", options.passValue) or false
flickerstreak@30 1345 end
flickerstreak@30 1346 if hidden then
flickerstreak@30 1347 return
flickerstreak@30 1348 end
flickerstreak@30 1349 local disabled = options.disabled
flickerstreak@30 1350 if type(disabled) == "function" or type(disabled) == "string" then
flickerstreak@30 1351 disabled = callMethod(options.name or "(options root)", handler, options, "disabled", options.passValue) or false
flickerstreak@30 1352 end
flickerstreak@30 1353 if disabled then
flickerstreak@30 1354 self:AddLine(
flickerstreak@30 1355 'text', DISABLED,
flickerstreak@30 1356 'disabled', true
flickerstreak@30 1357 )
flickerstreak@30 1358 return
flickerstreak@30 1359 end
flickerstreak@30 1360 for k in pairs(options.args) do
flickerstreak@30 1361 table.insert(values, k)
flickerstreak@30 1362 end
flickerstreak@30 1363 if options.pass then
flickerstreak@30 1364 if options.get and options.set then
flickerstreak@30 1365 passTable = options
flickerstreak@30 1366 elseif not passTable then
flickerstreak@30 1367 passTable = options
flickerstreak@30 1368 end
flickerstreak@30 1369 else
flickerstreak@30 1370 passTable = nil
flickerstreak@30 1371 end
flickerstreak@30 1372 if not mysort then
flickerstreak@30 1373 mysort = function(a, b)
flickerstreak@30 1374 local alpha, bravo = mysort_args[a], mysort_args[b]
flickerstreak@30 1375 local alpha_order = alpha.order or 100
flickerstreak@30 1376 local bravo_order = bravo.order or 100
flickerstreak@30 1377 local alpha_name = alpha.guiName or alpha.name
flickerstreak@30 1378 local bravo_name = bravo.guiName or bravo.name
flickerstreak@30 1379 if alpha_order == bravo_order then
flickerstreak@30 1380 if not alpha_name then
flickerstreak@30 1381 return bravo_name
flickerstreak@30 1382 elseif not bravo_name then
flickerstreak@30 1383 return false
flickerstreak@30 1384 else
flickerstreak@30 1385 return alpha_name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper() < bravo_name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper()
flickerstreak@30 1386 end
flickerstreak@30 1387 else
flickerstreak@30 1388 if alpha_order < 0 then
flickerstreak@30 1389 if bravo_order > 0 then
flickerstreak@30 1390 return false
flickerstreak@30 1391 end
flickerstreak@30 1392 else
flickerstreak@30 1393 if bravo_order < 0 then
flickerstreak@30 1394 return true
flickerstreak@30 1395 end
flickerstreak@30 1396 end
flickerstreak@30 1397 return alpha_order < bravo_order
flickerstreak@30 1398 end
flickerstreak@30 1399 end
flickerstreak@30 1400 end
flickerstreak@30 1401 mysort_args = options.args
flickerstreak@30 1402 table.sort(values, mysort)
flickerstreak@30 1403 mysort_args = nil
flickerstreak@30 1404 local hasBoth = #values >= 1 and (options.args[values[1]].order or 100) > 0 and (options.args[values[#values]].order or 100) < 0
flickerstreak@30 1405 local last_order = 1
flickerstreak@30 1406 for _,k in ipairs(values) do
flickerstreak@30 1407 local v = options.args[k]
flickerstreak@30 1408 local handler = v.handler or handler
flickerstreak@30 1409 if hasBoth and last_order > 0 and (v.order or 100) < 0 then
flickerstreak@30 1410 hasBoth = false
flickerstreak@30 1411 self:AddLine()
flickerstreak@30 1412 end
flickerstreak@30 1413 local hidden, disabled = v.guiHidden or v.hidden, v.disabled
flickerstreak@30 1414
flickerstreak@30 1415 if type(hidden) == "function" or type(hidden) == "string" then
flickerstreak@30 1416 hidden = callMethod(k, handler, v, "hidden", v.passValue) or false
flickerstreak@30 1417 end
flickerstreak@30 1418 if not hidden then
flickerstreak@30 1419 if type(disabled) == "function" or type(disabled) == "string" then
flickerstreak@30 1420 disabled = callMethod(k, handler, v, "disabled", v.passValue) or false
flickerstreak@30 1421 end
flickerstreak@30 1422 local name = (v.guiIconOnly and v.icon) and "" or (v.guiName or v.name)
flickerstreak@30 1423 local desc = v.guiDesc or v.desc
flickerstreak@30 1424 local iconHeight = v.iconHeight or 16
flickerstreak@30 1425 local iconWidth = v.iconWidth or 16
flickerstreak@30 1426 local iconCoordLeft = v.iconCoordLeft
flickerstreak@30 1427 local iconCoordRight = v.iconCoordRight
flickerstreak@30 1428 local iconCoordBottom = v.iconCoordBottom
flickerstreak@30 1429 local iconCoordTop = v.iconCoordTop
flickerstreak@30 1430 local tooltipTitle, tooltipText
flickerstreak@30 1431 tooltipTitle = name
flickerstreak@30 1432 if name ~= desc then
flickerstreak@30 1433 tooltipText = desc
flickerstreak@30 1434 end
flickerstreak@30 1435 if type(v.usage) == "string" and v.usage:trim():len() > 0 then
flickerstreak@30 1436 if tooltipText then
flickerstreak@30 1437 tooltipText = tooltipText .. "\n\n" .. USAGE_TOOLTIP:format(v.usage)
flickerstreak@30 1438 else
flickerstreak@30 1439 tooltipText = USAGE_TOOLTIP:format(v.usage)
flickerstreak@30 1440 end
flickerstreak@30 1441 end
flickerstreak@30 1442 local v_p = passTable
flickerstreak@30 1443 if not v_p or (v.type ~= "execute" and v.get and v.set) or (v.type == "execute" and v.func) then
flickerstreak@30 1444 v_p = v
flickerstreak@30 1445 end
flickerstreak@30 1446 local passValue = v.passValue or (v_p~=v and k) or nil
flickerstreak@30 1447 if v.type == "toggle" then
flickerstreak@30 1448 local checked = callMethod(name, handler, v_p, "get", passValue) or false
flickerstreak@30 1449 local checked_arg = checked
flickerstreak@30 1450 if type(v_p.get)=="string" and v_p.get:match("^~") then
flickerstreak@30 1451 checked_arg = not checked
flickerstreak@30 1452 end
flickerstreak@30 1453 local func, arg1, arg2, arg3 = getMethod(name, handler, v_p, "set", skip1Nil(passValue, not checked_arg))
flickerstreak@30 1454 if v.guiNameIsMap then
flickerstreak@30 1455 checked = checked and true or false
flickerstreak@30 1456 name = tostring(v.map and v.map[checked]):gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
flickerstreak@30 1457 tooltipTitle = name
flickerstreak@30 1458 checked = true--nil
flickerstreak@30 1459 end
flickerstreak@30 1460 self:AddLine(
flickerstreak@30 1461 'text', name,
flickerstreak@30 1462 'checked', checked,
flickerstreak@30 1463 'isRadio', v.isRadio,
flickerstreak@30 1464 'func', func,
flickerstreak@30 1465 'arg1', arg1,
flickerstreak@30 1466 'arg2', arg2,
flickerstreak@30 1467 'arg3', arg3,
flickerstreak@30 1468 'disabled', disabled,
flickerstreak@30 1469 'tooltipTitle', tooltipTitle,
flickerstreak@30 1470 'tooltipText', tooltipText
flickerstreak@30 1471 )
flickerstreak@30 1472 elseif v.type == "execute" then
flickerstreak@30 1473 local func, arg1, arg2, arg3, arg4
flickerstreak@30 1474 local confirm = v.confirm
flickerstreak@30 1475 if confirm == true then
flickerstreak@30 1476 confirm = DEFAULT_CONFIRM_MESSAGE:format(tooltipText or tooltipTitle)
flickerstreak@30 1477 func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
flickerstreak@30 1478 elseif type(confirm) == "string" then
flickerstreak@30 1479 func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
flickerstreak@30 1480 else
flickerstreak@30 1481 func,arg1,arg2 = getMethod(name, handler, v_p, "func", passValue)
flickerstreak@30 1482 end
flickerstreak@30 1483 self:AddLine(
flickerstreak@30 1484 'text', name,
flickerstreak@30 1485 'checked', checked,
flickerstreak@30 1486 'func', func,
flickerstreak@30 1487 'arg1', arg1,
flickerstreak@30 1488 'arg2', arg2,
flickerstreak@30 1489 'arg3', arg3,
flickerstreak@30 1490 'arg4', arg4,
flickerstreak@30 1491 'disabled', disabled,
flickerstreak@30 1492 'tooltipTitle', tooltipTitle,
flickerstreak@30 1493 'tooltipText', tooltipText,
flickerstreak@30 1494 'icon', v.icon,
flickerstreak@30 1495 'iconHeight', iconHeight,
flickerstreak@30 1496 'iconWidth', iconWidth,
flickerstreak@30 1497 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1498 'iconCoordRight', iconCoordRight,
flickerstreak@30 1499 'iconCoordTop', iconCoordTop,
flickerstreak@30 1500 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1501 )
flickerstreak@30 1502 elseif v.type == "range" then
flickerstreak@30 1503 local sliderValue
flickerstreak@30 1504 sliderValue = callMethod(name, handler, v_p, "get", passValue) or 0
flickerstreak@30 1505 local sliderFunc, sliderArg1, sliderArg2 = getMethod(name, handler, v_p, "set", passValue)
flickerstreak@30 1506 if tooltipText then
flickerstreak@30 1507 tooltipText = format("%s\n\n%s", tooltipText, RANGE_TOOLTIP)
flickerstreak@30 1508 else
flickerstreak@30 1509 tooltipText = RANGE_TOOLTIP
flickerstreak@30 1510 end
flickerstreak@30 1511 self:AddLine(
flickerstreak@30 1512 'text', name,
flickerstreak@30 1513 'hasArrow', true,
flickerstreak@30 1514 'hasSlider', true,
flickerstreak@30 1515 'sliderMin', v.min or 0,
flickerstreak@30 1516 'sliderMax', v.max or 1,
flickerstreak@30 1517 'sliderStep', v.step or 0,
flickerstreak@30 1518 'sliderBigStep', v.bigStep or nil,
flickerstreak@30 1519 'sliderIsPercent', v.isPercent or false,
flickerstreak@30 1520 'sliderValue', sliderValue,
flickerstreak@30 1521 'sliderFunc', sliderFunc,
flickerstreak@30 1522 'sliderArg1', sliderArg1,
flickerstreak@30 1523 'sliderArg2', sliderArg2,
flickerstreak@30 1524 'fromAceOptions', true,
flickerstreak@30 1525 'disabled', disabled,
flickerstreak@30 1526 'tooltipTitle', tooltipTitle,
flickerstreak@30 1527 'tooltipText', tooltipText,
flickerstreak@30 1528 'icon', v.icon,
flickerstreak@30 1529 'iconHeight', iconHeight,
flickerstreak@30 1530 'iconWidth', iconWidth,
flickerstreak@30 1531 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1532 'iconCoordRight', iconCoordRight,
flickerstreak@30 1533 'iconCoordTop', iconCoordTop,
flickerstreak@30 1534 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1535 )
flickerstreak@30 1536 elseif v.type == "color" then
flickerstreak@30 1537 local r,g,b,a = callMethod(name, handler, v_p, "get", passValue)
flickerstreak@30 1538 if not r then
flickerstreak@30 1539 r,g,b,a = 0,0,0,0
flickerstreak@30 1540 end
flickerstreak@30 1541 local colorFunc, colorArg1, colorArg2 = getMethod(name, handler, v_p, "set", passValue)
flickerstreak@30 1542 self:AddLine(
flickerstreak@30 1543 'text', name,
flickerstreak@30 1544 'hasArrow', true,
flickerstreak@30 1545 'hasColorSwatch', true,
flickerstreak@30 1546 'r', r,
flickerstreak@30 1547 'g', g,
flickerstreak@30 1548 'b', b,
flickerstreak@30 1549 'opacity', v.hasAlpha and a or nil,
flickerstreak@30 1550 'hasOpacity', v.hasAlpha,
flickerstreak@30 1551 'colorFunc', colorFunc,
flickerstreak@30 1552 'colorArg1', colorArg1,
flickerstreak@30 1553 'colorArg2', colorArg2,
flickerstreak@30 1554 'disabled', disabled,
flickerstreak@30 1555 'tooltipTitle', tooltipTitle,
flickerstreak@30 1556 'tooltipText', tooltipText
flickerstreak@30 1557 )
flickerstreak@30 1558 elseif v.type == "text" then
flickerstreak@30 1559 if type(v.validate) == "table" then
flickerstreak@30 1560 local func,arg1,arg2
flickerstreak@30 1561 if v.onClick then
flickerstreak@30 1562 func,arg1,arg2 = getMethod(name, handler, v, "onClick", passValue)
flickerstreak@30 1563 end
flickerstreak@30 1564 local checked
flickerstreak@30 1565 if v.isChecked then
flickerstreak@30 1566 checked = callMethod(name, handler, v, "isChecked", passValue) or false
flickerstreak@30 1567 end
flickerstreak@30 1568 self:AddLine(
flickerstreak@30 1569 'text', name,
flickerstreak@30 1570 'hasArrow', true,
flickerstreak@30 1571 'value', k,
flickerstreak@30 1572 'func', func,
flickerstreak@30 1573 'arg1', arg1,
flickerstreak@30 1574 'arg2', arg2,
flickerstreak@30 1575 'mouseoverUnderline', func and true or nil,
flickerstreak@30 1576 'disabled', disabled,
flickerstreak@30 1577 'checked', checked,
flickerstreak@30 1578 'tooltipTitle', tooltipTitle,
flickerstreak@30 1579 'tooltipText', tooltipText,
flickerstreak@30 1580 'icon', v.icon,
flickerstreak@30 1581 'iconHeight', iconHeight,
flickerstreak@30 1582 'iconWidth', iconWidth,
flickerstreak@30 1583 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1584 'iconCoordRight', iconCoordRight,
flickerstreak@30 1585 'iconCoordTop', iconCoordTop,
flickerstreak@30 1586 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1587 )
flickerstreak@30 1588 else
flickerstreak@30 1589 local editBoxText
flickerstreak@30 1590 editBoxText = callMethod(name, handler, v_p, "get", passValue) or ""
flickerstreak@30 1591 local editBoxFunc, editBoxArg1, editBoxArg2 = getMethod(name, handler, v_p, "set", passValue)
flickerstreak@30 1592
flickerstreak@30 1593 local editBoxValidateFunc, editBoxValidateArg1
flickerstreak@30 1594
flickerstreak@30 1595 if v.validate and v.validate ~= "keybinding" then
flickerstreak@30 1596 if v.validate == "keybinding" then
flickerstreak@30 1597 if tooltipText then
flickerstreak@30 1598 tooltipText = format("%s\n\n%s", tooltipText, RESET_KEYBINDING_DESC)
flickerstreak@30 1599 else
flickerstreak@30 1600 tooltipText = RESET_KEYBINDING_DESC
flickerstreak@30 1601 end
flickerstreak@30 1602 else
flickerstreak@30 1603 editBoxValidateFunc, editBoxValidateArg1 = getMethod(name, handler, v, "validate") -- no passvalue!
flickerstreak@30 1604 end
flickerstreak@30 1605 end
flickerstreak@30 1606
flickerstreak@30 1607 self:AddLine(
flickerstreak@30 1608 'text', name,
flickerstreak@30 1609 'hasArrow', true,
flickerstreak@30 1610 'icon', v.icon,
flickerstreak@30 1611 'iconHeight', iconHeight,
flickerstreak@30 1612 'iconWidth', iconWidth,
flickerstreak@30 1613 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1614 'iconCoordRight', iconCoordRight,
flickerstreak@30 1615 'iconCoordTop', iconCoordTop,
flickerstreak@30 1616 'iconCoordBottom', iconCoordBottom,
flickerstreak@30 1617 'hasEditBox', true,
flickerstreak@30 1618 'editBoxText', editBoxText,
flickerstreak@30 1619 'editBoxFunc', editBoxFunc,
flickerstreak@30 1620 'editBoxArg1', editBoxArg1,
flickerstreak@30 1621 'editBoxArg2', editBoxArg2,
flickerstreak@30 1622 'editBoxValidateFunc', editBoxValidateFunc,
flickerstreak@30 1623 'editBoxValidateArg1', editBoxValidateArg1,
flickerstreak@30 1624 'editBoxIsKeybinding', v.validate == "keybinding",
flickerstreak@30 1625 'editBoxKeybindingOnly', v.keybindingOnly,
flickerstreak@30 1626 'editBoxKeybindingExcept', v.keybindingExcept,
flickerstreak@30 1627 'disabled', disabled,
flickerstreak@30 1628 'tooltipTitle', tooltipTitle,
flickerstreak@30 1629 'tooltipText', tooltipText
flickerstreak@30 1630 )
flickerstreak@30 1631 end
flickerstreak@30 1632 elseif v.type == "group" then
flickerstreak@30 1633 local func,arg1,arg2
flickerstreak@30 1634 if v.onClick then
flickerstreak@30 1635 func,arg1,arg2 = getMethod(name, handler, v, "onClick", passValue)
flickerstreak@30 1636 end
flickerstreak@30 1637 local checked
flickerstreak@30 1638 if v.isChecked then
flickerstreak@30 1639 checked = callMethod(name, handler, v, "isChecked", passValue) or false
flickerstreak@30 1640 end
flickerstreak@30 1641 self:AddLine(
flickerstreak@30 1642 'text', name,
flickerstreak@30 1643 'hasArrow', true,
flickerstreak@30 1644 'value', k,
flickerstreak@30 1645 'func', func,
flickerstreak@30 1646 'arg1', arg1,
flickerstreak@30 1647 'arg2', arg2,
flickerstreak@30 1648 'mouseoverUnderline', func and true or nil,
flickerstreak@30 1649 'disabled', disabled,
flickerstreak@30 1650 'checked', checked,
flickerstreak@30 1651 'tooltipTitle', tooltipTitle,
flickerstreak@30 1652 'tooltipText', tooltipText,
flickerstreak@30 1653 'icon', v.icon,
flickerstreak@30 1654 'iconHeight', iconHeight,
flickerstreak@30 1655 'iconWidth', iconWidth,
flickerstreak@30 1656 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1657 'iconCoordRight', iconCoordRight,
flickerstreak@30 1658 'iconCoordTop', iconCoordTop,
flickerstreak@30 1659 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1660 )
flickerstreak@30 1661 elseif v.type == "header" then
flickerstreak@30 1662 if name == "" or not name then
flickerstreak@30 1663 self:AddLine(
flickerstreak@30 1664 'isTitle', true,
flickerstreak@30 1665 'icon', v.icon,
flickerstreak@30 1666 'iconHeight', iconHeight,
flickerstreak@30 1667 'iconWidth', iconWidth,
flickerstreak@30 1668 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1669 'iconCoordRight', iconCoordRight,
flickerstreak@30 1670 'iconCoordTop', iconCoordTop,
flickerstreak@30 1671 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1672 )
flickerstreak@30 1673 else
flickerstreak@30 1674 self:AddLine(
flickerstreak@30 1675 'text', name,
flickerstreak@30 1676 'isTitle', true,
flickerstreak@30 1677 'icon', v.icon,
flickerstreak@30 1678 'iconHeight', iconHeight,
flickerstreak@30 1679 'iconWidth', iconWidth,
flickerstreak@30 1680 'iconCoordLeft', iconCoordLeft,
flickerstreak@30 1681 'iconCoordRight', iconCoordRight,
flickerstreak@30 1682 'iconCoordTop', iconCoordTop,
flickerstreak@30 1683 'iconCoordBottom', iconCoordBottom
flickerstreak@30 1684 )
flickerstreak@30 1685 end
flickerstreak@30 1686 end
flickerstreak@30 1687 end
flickerstreak@30 1688 last_order = v.order or 100
flickerstreak@30 1689 end
flickerstreak@30 1690 elseif options.type == "text" and type(options.validate) == "table" then
flickerstreak@30 1691 local current
flickerstreak@30 1692 local options_p = passTable
flickerstreak@30 1693 if not options_p or (options.get and options.set) then
flickerstreak@30 1694 options_p = options
flickerstreak@30 1695 passTable = nil
flickerstreak@30 1696 passValue = nil
flickerstreak@30 1697 end
flickerstreak@30 1698 local multiToggle = options.multiToggle
flickerstreak@30 1699 local passValue = options.passValue or passValue
flickerstreak@30 1700 if not multiToggle then
flickerstreak@30 1701 current = callMethod(k, handler, options_p, "get", passValue)
flickerstreak@30 1702 end
flickerstreak@30 1703 local indexed = true
flickerstreak@30 1704 for k,v in pairs(options.validate) do
flickerstreak@30 1705 if type(k) ~= "number" then
flickerstreak@30 1706 indexed = false
flickerstreak@30 1707 end
flickerstreak@30 1708 table.insert(values, k)
flickerstreak@30 1709 end
flickerstreak@30 1710 if not indexed then
flickerstreak@30 1711 if not othersort then
flickerstreak@30 1712 othersort = function(alpha, bravo)
flickerstreak@30 1713 return othersort_validate[alpha]:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper() < othersort_validate[bravo]:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper()
flickerstreak@30 1714 end
flickerstreak@30 1715 end
flickerstreak@30 1716 othersort_validate = options.validate
flickerstreak@30 1717 table.sort(values, othersort)
flickerstreak@30 1718 othersort_validate = nil
flickerstreak@30 1719 end
flickerstreak@30 1720 for _,k in ipairs(values) do
flickerstreak@30 1721 local v = options.validate[k]
flickerstreak@30 1722 if type(k) == "number" then
flickerstreak@30 1723 k = v
flickerstreak@30 1724 end
flickerstreak@30 1725 local func, arg1, arg2, arg3, arg4 = getMethod(k, handler, options_p, "set", skip1Nil(passValue, k))
flickerstreak@30 1726 local checked
flickerstreak@30 1727 if multiToggle then
flickerstreak@30 1728 checked = callMethod(k, handler, options_p, "get", skip1Nil(passValue, k)) or false
flickerstreak@30 1729 if arg2 == nil then
flickerstreak@30 1730 arg2 = not checked
flickerstreak@30 1731 elseif arg3 == nil then
flickerstreak@30 1732 arg3 = not checked
flickerstreak@30 1733 else
flickerstreak@30 1734 arg4 = not checked
flickerstreak@30 1735 end
flickerstreak@30 1736 else
flickerstreak@30 1737 checked = (k == current or (type(k) == "string" and type(current) == "string" and k:lower() == current:lower()))
flickerstreak@30 1738 if checked then
flickerstreak@30 1739 func, arg1, arg2, arg3, arg4 = nil, nil, nil, nil, nil
flickerstreak@30 1740 end
flickerstreak@30 1741 end
flickerstreak@30 1742 local tooltipTitle
flickerstreak@30 1743 local tooltipText
flickerstreak@30 1744 if options.validateDesc then
flickerstreak@30 1745 tooltipTitle = v
flickerstreak@30 1746 tooltipText = options.validateDesc[k]
flickerstreak@30 1747 else
flickerstreak@30 1748 tooltipTitle = options.guiName or options.name
flickerstreak@30 1749 tooltipText = v
flickerstreak@30 1750 end
flickerstreak@30 1751 self:AddLine(
flickerstreak@30 1752 'text', v,
flickerstreak@30 1753 'func', func,
flickerstreak@30 1754 'arg1', arg1,
flickerstreak@30 1755 'arg2', arg2,
flickerstreak@30 1756 'arg3', arg3,
flickerstreak@30 1757 'arg4', arg4,
flickerstreak@30 1758 'isRadio', not multiToggle,
flickerstreak@30 1759 'checked', checked,
flickerstreak@30 1760 'tooltipTitle', tooltipTitle,
flickerstreak@30 1761 'tooltipText', tooltipText
flickerstreak@30 1762 )
flickerstreak@30 1763 end
flickerstreak@30 1764 for k in pairs(values) do
flickerstreak@30 1765 values[k] = nil
flickerstreak@30 1766 end
flickerstreak@30 1767 else
flickerstreak@30 1768 return false
flickerstreak@30 1769 end
flickerstreak@30 1770 return true
flickerstreak@30 1771 end
flickerstreak@30 1772
flickerstreak@30 1773 function Dewdrop:FeedTable(s, difference)
flickerstreak@30 1774 self:argCheck(s, 2, "table")
flickerstreak@30 1775 self:argCheck(difference, 3, "nil", "number")
flickerstreak@30 1776 if not currentLevel then
flickerstreak@30 1777 self:error("Cannot call `FeedTable' outside of a Dewdrop declaration")
flickerstreak@30 1778 end
flickerstreak@30 1779 if not difference then
flickerstreak@30 1780 difference = 0
flickerstreak@30 1781 end
flickerstreak@30 1782 local level = levels[currentLevel]
flickerstreak@30 1783 if not level then
flickerstreak@30 1784 self:error("Improper level given")
flickerstreak@30 1785 end
flickerstreak@30 1786 if not values then
flickerstreak@30 1787 values = {}
flickerstreak@30 1788 else
flickerstreak@30 1789 for k,v in pairs(values) do
flickerstreak@30 1790 values[k] = nil
flickerstreak@30 1791 end
flickerstreak@30 1792 end
flickerstreak@30 1793 local t = s.subMenu and s or {subMenu = s}
flickerstreak@30 1794 local current = level
flickerstreak@30 1795 while current do
flickerstreak@30 1796 if current.num == difference + 1 then
flickerstreak@30 1797 break
flickerstreak@30 1798 end
flickerstreak@30 1799 table.insert(values, current.value)
flickerstreak@30 1800 current = levels[current.num - 1]
flickerstreak@30 1801 end
flickerstreak@30 1802
flickerstreak@30 1803 while #values > 0 do
flickerstreak@30 1804 local value = table.remove(values)
flickerstreak@30 1805 t = t.subMenu and t.subMenu[value]
flickerstreak@30 1806 if not t then
flickerstreak@30 1807 return
flickerstreak@30 1808 end
flickerstreak@30 1809 end
flickerstreak@30 1810
flickerstreak@30 1811 if t.subMenu or current.num == 1 then
flickerstreak@30 1812 for k in pairs(t.subMenu) do
flickerstreak@30 1813 table.insert(values, k)
flickerstreak@30 1814 end
flickerstreak@30 1815 table.sort(values)
flickerstreak@30 1816 for _,k in ipairs(values) do
flickerstreak@30 1817 local argTable = {"value", k}
flickerstreak@30 1818 for key, val in pairs(t.subMenu[k]) do
flickerstreak@30 1819 table.insert(argTable, key)
flickerstreak@30 1820 table.insert(argTable, val)
flickerstreak@30 1821 end
flickerstreak@30 1822 self:AddLine(unpack(argTable))
flickerstreak@30 1823 end
flickerstreak@30 1824 for k in pairs(values) do
flickerstreak@30 1825 values[k] = nil
flickerstreak@30 1826 end
flickerstreak@30 1827 return false
flickerstreak@30 1828 end
flickerstreak@30 1829 return true
flickerstreak@30 1830 end
flickerstreak@30 1831
flickerstreak@30 1832 function Refresh(self, level)
flickerstreak@30 1833 if type(level) == "number" then
flickerstreak@30 1834 level = levels[level]
flickerstreak@30 1835 end
flickerstreak@30 1836 if not level then
flickerstreak@30 1837 return
flickerstreak@30 1838 end
flickerstreak@30 1839 if baseFunc then
flickerstreak@30 1840 Clear(self, level)
flickerstreak@30 1841 currentLevel = level.num
flickerstreak@30 1842 if type(baseFunc) == "table" then
flickerstreak@30 1843 if currentLevel == 1 then
flickerstreak@30 1844 local handler = baseFunc.handler
flickerstreak@30 1845 if handler then
flickerstreak@30 1846 local name = tostring(handler)
flickerstreak@30 1847 if not name:find('^table:') and not handler.hideMenuTitle then
flickerstreak@30 1848 name = name:gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
flickerstreak@30 1849 self:AddLine(
flickerstreak@30 1850 'text', name,
flickerstreak@30 1851 'isTitle', true
flickerstreak@30 1852 )
flickerstreak@30 1853 end
flickerstreak@30 1854 end
flickerstreak@30 1855 -- elseif level.parentText then
flickerstreak@30 1856 -- self:AddLine(
flickerstreak@30 1857 -- 'text', level.parentText,
flickerstreak@30 1858 -- 'tooltipTitle', level.parentTooltipTitle,
flickerstreak@30 1859 -- 'tooltipText', level.parentTooltipText,
flickerstreak@30 1860 -- 'tooltipFunc', level.parentTooltipFunc,
flickerstreak@30 1861 -- 'isTitle', true
flickerstreak@30 1862 -- )
flickerstreak@30 1863 end
flickerstreak@30 1864 self:FeedAceOptionsTable(baseFunc)
flickerstreak@30 1865 if currentLevel == 1 then
flickerstreak@30 1866 self:AddLine(
flickerstreak@30 1867 'text', CLOSE,
flickerstreak@30 1868 'tooltipTitle', CLOSE,
flickerstreak@30 1869 'tooltipText', CLOSE_DESC,
flickerstreak@30 1870 'closeWhenClicked', true
flickerstreak@30 1871 )
flickerstreak@30 1872 end
flickerstreak@30 1873 else
flickerstreak@30 1874 -- if level.parentText then
flickerstreak@30 1875 -- self:AddLine(
flickerstreak@30 1876 -- 'text', level.parentText,
flickerstreak@30 1877 -- 'tooltipTitle', level.parentTooltipTitle,
flickerstreak@30 1878 -- 'tooltipText', level.parentTooltipText,
flickerstreak@30 1879 -- 'tooltipFunc', level.parentTooltipFunc,
flickerstreak@30 1880 -- 'isTitle', true
flickerstreak@30 1881 -- )
flickerstreak@30 1882 -- end
flickerstreak@30 1883 baseFunc(currentLevel, level.value, levels[level.num - 1] and levels[level.num - 1].value, levels[level.num - 2] and levels[level.num - 2].value, levels[level.num - 3] and levels[level.num - 3].value, levels[level.num - 4] and levels[level.num - 4].value)
flickerstreak@30 1884 end
flickerstreak@30 1885 currentLevel = nil
flickerstreak@30 1886 CheckSize(self, level)
flickerstreak@30 1887 end
flickerstreak@30 1888 end
flickerstreak@30 1889
flickerstreak@30 1890 function Dewdrop:Refresh(level)
flickerstreak@30 1891 self:argCheck(level, 2, "number", "nil")
flickerstreak@30 1892 if not level then
flickerstreak@30 1893 for k,v in pairs(levels) do
flickerstreak@30 1894 Refresh(self, v)
flickerstreak@30 1895 end
flickerstreak@30 1896 else
flickerstreak@30 1897 Refresh(self, levels[level])
flickerstreak@30 1898 end
flickerstreak@30 1899 end
flickerstreak@30 1900
flickerstreak@30 1901 function OpenSlider(self, parent)
flickerstreak@30 1902 if not sliderFrame then
flickerstreak@30 1903 sliderFrame = CreateFrame("Frame", nil, nil)
flickerstreak@30 1904 sliderFrame:SetWidth(100)
flickerstreak@30 1905 sliderFrame:SetHeight(170)
flickerstreak@30 1906 sliderFrame:SetScale(UIParent:GetScale())
flickerstreak@30 1907 sliderFrame:SetBackdrop(tmp(
flickerstreak@30 1908 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
flickerstreak@30 1909 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
flickerstreak@30 1910 'tile', true,
flickerstreak@30 1911 'insets', tmp2(
flickerstreak@30 1912 'left', 5,
flickerstreak@30 1913 'right', 5,
flickerstreak@30 1914 'top', 5,
flickerstreak@30 1915 'bottom', 5
flickerstreak@30 1916 ),
flickerstreak@30 1917 'tileSize', 16,
flickerstreak@30 1918 'edgeSize', 16
flickerstreak@30 1919 ))
flickerstreak@30 1920 sliderFrame:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 1921 if sliderFrame.SetTopLevel then
flickerstreak@30 1922 sliderFrame:SetTopLevel(true)
flickerstreak@30 1923 end
flickerstreak@30 1924 sliderFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
flickerstreak@30 1925 sliderFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
flickerstreak@30 1926 sliderFrame:EnableMouse(true)
flickerstreak@30 1927 sliderFrame:EnableMouseWheel(true)
flickerstreak@30 1928 sliderFrame:Hide()
flickerstreak@30 1929 sliderFrame:SetPoint("CENTER", UIParent, "CENTER")
flickerstreak@30 1930 local slider = CreateFrame("Slider", nil, sliderFrame)
flickerstreak@30 1931 sliderFrame.slider = slider
flickerstreak@30 1932 slider:SetOrientation("VERTICAL")
flickerstreak@30 1933 slider:SetMinMaxValues(0, 1)
flickerstreak@30 1934 slider:SetValueStep(0.000000001)
flickerstreak@30 1935 slider:SetValue(0.5)
flickerstreak@30 1936 slider:SetWidth(16)
flickerstreak@30 1937 slider:SetHeight(128)
flickerstreak@30 1938 slider:SetPoint("LEFT", sliderFrame, "LEFT", 15, 0)
flickerstreak@30 1939 slider:SetBackdrop(tmp(
flickerstreak@30 1940 'bgFile', "Interface\\Buttons\\UI-SliderBar-Background",
flickerstreak@30 1941 'edgeFile', "Interface\\Buttons\\UI-SliderBar-Border",
flickerstreak@30 1942 'tile', true,
flickerstreak@30 1943 'edgeSize', 8,
flickerstreak@30 1944 'tileSize', 8,
flickerstreak@30 1945 'insets', tmp2(
flickerstreak@30 1946 'left', 3,
flickerstreak@30 1947 'right', 3,
flickerstreak@30 1948 'top', 3,
flickerstreak@30 1949 'bottom', 3
flickerstreak@30 1950 )
flickerstreak@30 1951 ))
flickerstreak@30 1952 local texture = slider:CreateTexture()
flickerstreak@30 1953 slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
flickerstreak@30 1954 local text = slider:CreateFontString(nil, "ARTWORK")
flickerstreak@30 1955 sliderFrame.topText = text
flickerstreak@30 1956 text:SetFontObject(GameFontGreenSmall)
flickerstreak@30 1957 text:SetText("100%")
flickerstreak@30 1958 text:SetPoint("BOTTOM", slider, "TOP")
flickerstreak@30 1959 local text = slider:CreateFontString(nil, "ARTWORK")
flickerstreak@30 1960 sliderFrame.bottomText = text
flickerstreak@30 1961 text:SetFontObject(GameFontGreenSmall)
flickerstreak@30 1962 text:SetText("0%")
flickerstreak@30 1963 text:SetPoint("TOP", slider, "BOTTOM")
flickerstreak@30 1964 local editBox = CreateFrame("EditBox", nil, sliderFrame)
flickerstreak@30 1965 sliderFrame.currentText = editBox
flickerstreak@30 1966 editBox:SetFontObject(ChatFontNormal)
flickerstreak@30 1967 editBox:SetHeight(13)
flickerstreak@30 1968 editBox:SetPoint("RIGHT", sliderFrame, "RIGHT", -16, 0)
flickerstreak@30 1969 editBox:SetPoint("LEFT", slider, "RIGHT", 12, 0)
flickerstreak@30 1970 editBox:SetText("50%")
flickerstreak@30 1971 editBox:SetJustifyH("CENTER")
flickerstreak@30 1972
flickerstreak@30 1973 local width = editBox:GetWidth()/2 + 10
flickerstreak@30 1974 local left = editBox:CreateTexture(nil, "BACKGROUND")
flickerstreak@30 1975 left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
flickerstreak@30 1976 left:SetTexCoord(0, width / 256, 0, 1)
flickerstreak@30 1977 left:SetWidth(width)
flickerstreak@30 1978 left:SetHeight(32)
flickerstreak@30 1979 left:SetPoint("LEFT", editBox, "LEFT", -10, 0)
flickerstreak@30 1980 local right = editBox:CreateTexture(nil, "BACKGROUND")
flickerstreak@30 1981 right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
flickerstreak@30 1982 right:SetTexCoord(1 - width / 256, 1, 0, 1)
flickerstreak@30 1983 right:SetWidth(width)
flickerstreak@30 1984 right:SetHeight(32)
flickerstreak@30 1985 right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
flickerstreak@30 1986
flickerstreak@30 1987 local changed = false
flickerstreak@30 1988 local inside = false
flickerstreak@30 1989 slider:SetScript("OnValueChanged", function()
flickerstreak@30 1990 if sliderFrame.changing then
flickerstreak@30 1991 return
flickerstreak@30 1992 end
flickerstreak@30 1993 changed = true
flickerstreak@30 1994 local done = false
flickerstreak@30 1995 if sliderFrame.parent and sliderFrame.parent.sliderFunc then
flickerstreak@30 1996 local min = sliderFrame.parent.sliderMin or 0
flickerstreak@30 1997 local max = sliderFrame.parent.sliderMax or 1
flickerstreak@30 1998 local step
flickerstreak@30 1999 if sliderFrame.fineStep then
flickerstreak@30 2000 step = sliderFrame.parent.sliderStep or (max - min) / 100
flickerstreak@30 2001 else
flickerstreak@30 2002 step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
flickerstreak@30 2003 end
flickerstreak@30 2004 local value = (1 - slider:GetValue()) * (max - min) + min
flickerstreak@30 2005 if step > 0 then
flickerstreak@30 2006 value = math.floor((value - min) / step + 0.5) * step + min
flickerstreak@30 2007 if value > max then
flickerstreak@30 2008 value = max
flickerstreak@30 2009 elseif value < min then
flickerstreak@30 2010 value = min
flickerstreak@30 2011 end
flickerstreak@30 2012 end
flickerstreak@30 2013 if value == sliderFrame.lastValue then
flickerstreak@30 2014 return
flickerstreak@30 2015 end
flickerstreak@30 2016 sliderFrame.lastValue = value
flickerstreak@30 2017 local text = sliderFrame.parent.sliderFunc(getArgs(sliderFrame.parent, 'sliderArg', 1, value))
flickerstreak@30 2018 if sliderFrame.parent.fromAceOptions then
flickerstreak@30 2019 text = nil
flickerstreak@30 2020 elseif type(text) == "string" or type(text) == "number" then
flickerstreak@30 2021 sliderFrame.currentText:SetText(text)
flickerstreak@30 2022 done = true
flickerstreak@30 2023 end
flickerstreak@30 2024 end
flickerstreak@30 2025 if not done then
flickerstreak@30 2026 local min = sliderFrame.parent.sliderMin or 0
flickerstreak@30 2027 local max = sliderFrame.parent.sliderMax or 1
flickerstreak@30 2028 local step
flickerstreak@30 2029 if sliderFrame.fineStep then
flickerstreak@30 2030 step = sliderFrame.parent.sliderStep or (max - min) / 100
flickerstreak@30 2031 else
flickerstreak@30 2032 step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
flickerstreak@30 2033 end
flickerstreak@30 2034 local value = (1 - slider:GetValue()) * (max - min) + min
flickerstreak@30 2035 if step > 0 then
flickerstreak@30 2036 value = math.floor((value - min) / step + 0.5) * step + min
flickerstreak@30 2037 if value > max then
flickerstreak@30 2038 value = max
flickerstreak@30 2039 elseif value < min then
flickerstreak@30 2040 value = min
flickerstreak@30 2041 end
flickerstreak@30 2042 end
flickerstreak@30 2043 if sliderFrame.parent.sliderIsPercent then
flickerstreak@30 2044 sliderFrame.currentText:SetText(string.format("%.0f%%", value * 100))
flickerstreak@30 2045 else
flickerstreak@30 2046 if step < 0.1 then
flickerstreak@30 2047 sliderFrame.currentText:SetText(string.format("%.2f", value))
flickerstreak@30 2048 elseif step < 1 then
flickerstreak@30 2049 sliderFrame.currentText:SetText(string.format("%.1f", value))
flickerstreak@30 2050 else
flickerstreak@30 2051 sliderFrame.currentText:SetText(string.format("%.0f", value))
flickerstreak@30 2052 end
flickerstreak@30 2053 end
flickerstreak@30 2054 end
flickerstreak@30 2055 end)
flickerstreak@30 2056 local function onEnter()
flickerstreak@30 2057 StopCounting(self, sliderFrame.level)
flickerstreak@30 2058 showGameTooltip(sliderFrame.parent)
flickerstreak@30 2059 end
flickerstreak@30 2060 local function onLeave()
flickerstreak@30 2061 GameTooltip:Hide()
flickerstreak@30 2062 end
flickerstreak@30 2063 sliderFrame:SetScript("OnEnter", onEnter)
flickerstreak@30 2064 sliderFrame:SetScript("OnLeave", function()
flickerstreak@30 2065 GameTooltip:Hide()
flickerstreak@30 2066 if changed then
flickerstreak@30 2067 local parent = sliderFrame.parent
flickerstreak@30 2068 local sliderFunc = parent.sliderFunc
flickerstreak@30 2069 for i = 1, sliderFrame.level - 1 do
flickerstreak@30 2070 Refresh(self, levels[i])
flickerstreak@30 2071 end
flickerstreak@30 2072 local newParent
flickerstreak@30 2073 for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
flickerstreak@30 2074 if button.sliderFunc == sliderFunc then
flickerstreak@30 2075 newParent = button
flickerstreak@30 2076 break
flickerstreak@30 2077 end
flickerstreak@30 2078 end
flickerstreak@30 2079 if newParent then
flickerstreak@30 2080 OpenSlider(self, newParent)
flickerstreak@30 2081 else
flickerstreak@30 2082 sliderFrame:Hide()
flickerstreak@30 2083 end
flickerstreak@30 2084 end
flickerstreak@30 2085 end)
flickerstreak@30 2086 editBox:SetScript("OnEnter", onEnter)
flickerstreak@30 2087 editBox:SetScript("OnLeave", onLeave)
flickerstreak@30 2088 slider:SetScript("OnMouseDown", function()
flickerstreak@30 2089 sliderFrame.mouseDown = true
flickerstreak@30 2090 GameTooltip:Hide()
flickerstreak@30 2091 end)
flickerstreak@30 2092 slider:SetScript("OnMouseUp", function()
flickerstreak@30 2093 sliderFrame.mouseDown = false
flickerstreak@30 2094 if changed--[[ and not inside]] then
flickerstreak@30 2095 local parent = sliderFrame.parent
flickerstreak@30 2096 local sliderFunc = parent.sliderFunc
flickerstreak@30 2097 for i = 1, sliderFrame.level - 1 do
flickerstreak@30 2098 Refresh(self, levels[i])
flickerstreak@30 2099 end
flickerstreak@30 2100 local newParent
flickerstreak@30 2101 for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
flickerstreak@30 2102 if button.sliderFunc == sliderFunc then
flickerstreak@30 2103 newParent = button
flickerstreak@30 2104 break
flickerstreak@30 2105 end
flickerstreak@30 2106 end
flickerstreak@30 2107 if newParent then
flickerstreak@30 2108 OpenSlider(self, newParent)
flickerstreak@30 2109 else
flickerstreak@30 2110 sliderFrame:Hide()
flickerstreak@30 2111 end
flickerstreak@30 2112 end
flickerstreak@30 2113 if inside then
flickerstreak@30 2114 showGameTooltip(sliderFrame.parent)
flickerstreak@30 2115 end
flickerstreak@30 2116 end)
flickerstreak@30 2117 slider:SetScript("OnEnter", function()
flickerstreak@30 2118 inside = true
flickerstreak@30 2119 StopCounting(self, sliderFrame.level)
flickerstreak@30 2120 showGameTooltip(sliderFrame.parent)
flickerstreak@30 2121 end)
flickerstreak@30 2122 slider:SetScript("OnLeave", function()
flickerstreak@30 2123 inside = false
flickerstreak@30 2124 GameTooltip:Hide()
flickerstreak@30 2125 if changed and not sliderFrame.mouseDown then
flickerstreak@30 2126 local parent = sliderFrame.parent
flickerstreak@30 2127 local sliderFunc = parent.sliderFunc
flickerstreak@30 2128 for i = 1, sliderFrame.level - 1 do
flickerstreak@30 2129 Refresh(self, levels[i])
flickerstreak@30 2130 end
flickerstreak@30 2131 local newParent
flickerstreak@30 2132 for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
flickerstreak@30 2133 if button.sliderFunc == sliderFunc then
flickerstreak@30 2134 newParent = button
flickerstreak@30 2135 break
flickerstreak@30 2136 end
flickerstreak@30 2137 end
flickerstreak@30 2138 if newParent then
flickerstreak@30 2139 OpenSlider(self, newParent)
flickerstreak@30 2140 else
flickerstreak@30 2141 sliderFrame:Hide()
flickerstreak@30 2142 end
flickerstreak@30 2143
flickerstreak@30 2144 changed = false
flickerstreak@30 2145 end
flickerstreak@30 2146 end)
flickerstreak@30 2147 sliderFrame:SetScript("OnMouseWheel", function(t, a1)
flickerstreak@30 2148 local arg1 = a1 or arg1
flickerstreak@30 2149 local up = arg1 > 0
flickerstreak@30 2150
flickerstreak@30 2151 local min = sliderFrame.parent.sliderMin or 0
flickerstreak@30 2152 local max = sliderFrame.parent.sliderMax or 1
flickerstreak@30 2153 local step = sliderFrame.parent.sliderStep or (max - min) / 100
flickerstreak@30 2154 if step <= 0 then
flickerstreak@30 2155 step = (max - min) / 100
flickerstreak@30 2156 end
flickerstreak@30 2157
flickerstreak@30 2158 local value = (1 - slider:GetValue()) * (max - min) + min
flickerstreak@30 2159 if up then
flickerstreak@30 2160 value = value + step
flickerstreak@30 2161 else
flickerstreak@30 2162 value = value - step
flickerstreak@30 2163 end
flickerstreak@30 2164 if value > max then
flickerstreak@30 2165 value = max
flickerstreak@30 2166 elseif value < min then
flickerstreak@30 2167 value = min
flickerstreak@30 2168 end
flickerstreak@30 2169 sliderFrame.fineStep = true
flickerstreak@30 2170 if max<=min then
flickerstreak@30 2171 slider:SetValue(0)
flickerstreak@30 2172 else
flickerstreak@30 2173 slider:SetValue(1 - (value - min) / (max - min))
flickerstreak@30 2174 end
flickerstreak@30 2175 sliderFrame.fineStep = nil
flickerstreak@30 2176 end)
flickerstreak@30 2177 slider:SetScript("OnMouseWheel", sliderFrame:GetScript("OnMouseWheel"))
flickerstreak@30 2178 editBox:SetScript("OnEnterPressed", function(t, a1)
flickerstreak@30 2179 local value = editBox:GetNumber()
flickerstreak@30 2180
flickerstreak@30 2181 if sliderFrame.parent.sliderIsPercent then
flickerstreak@30 2182 value = value / 100
flickerstreak@30 2183 end
flickerstreak@30 2184
flickerstreak@30 2185 local min = sliderFrame.parent.sliderMin or 0
flickerstreak@30 2186 local max = sliderFrame.parent.sliderMax or 1
flickerstreak@30 2187
flickerstreak@30 2188 if value > max then
flickerstreak@30 2189 value = max
flickerstreak@30 2190 elseif value < min then
flickerstreak@30 2191 value = min
flickerstreak@30 2192 end
flickerstreak@30 2193 sliderFrame.fineStep = true
flickerstreak@30 2194 if max <= min then
flickerstreak@30 2195 slider:SetValue(0)
flickerstreak@30 2196 else
flickerstreak@30 2197 slider:SetValue(1 - (value - min) / (max - min))
flickerstreak@30 2198 end
flickerstreak@30 2199 sliderFrame.fineStep = nil
flickerstreak@30 2200
flickerstreak@30 2201 StartCounting(self, sliderFrame.level)
flickerstreak@30 2202 end)
flickerstreak@30 2203 editBox:SetScript("OnEscapePressed", function()
flickerstreak@30 2204 self:Close(sliderFrame.level)
flickerstreak@30 2205 StartCounting(self, sliderFrame.level)
flickerstreak@30 2206 end)
flickerstreak@30 2207 editBox:SetAutoFocus(false)
flickerstreak@30 2208 end
flickerstreak@30 2209 sliderFrame.parent = parent
flickerstreak@30 2210 sliderFrame.level = parent.level.num + 1
flickerstreak@30 2211 sliderFrame.parentValue = parent.level.value
flickerstreak@30 2212 sliderFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3)
flickerstreak@30 2213 sliderFrame.slider:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
flickerstreak@30 2214 sliderFrame.currentText:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
flickerstreak@30 2215 sliderFrame.currentText:ClearFocus()
flickerstreak@30 2216 sliderFrame.changing = true
flickerstreak@30 2217 if not parent.sliderMin or not parent.sliderMax then
flickerstreak@30 2218 return
flickerstreak@30 2219 end
flickerstreak@30 2220
flickerstreak@30 2221 if parent.arrow then
flickerstreak@30 2222 -- parent.arrow:SetVertexColor(0.2, 0.6, 0)
flickerstreak@30 2223 -- parent.arrow:SetHeight(24)
flickerstreak@30 2224 -- parent.arrow:SetWidth(24)
flickerstreak@30 2225 parent.selected = true
flickerstreak@30 2226 parent.highlight:Show()
flickerstreak@30 2227 end
flickerstreak@30 2228
flickerstreak@30 2229 sliderFrame:SetClampedToScreen(false)
flickerstreak@30 2230 if not parent.sliderValue then
flickerstreak@30 2231 parent.sliderValue = (parent.sliderMin + parent.sliderMax) / 2
flickerstreak@30 2232 end
flickerstreak@30 2233 if parent.sliderMax <= parent.sliderMin then
flickerstreak@30 2234 sliderFrame.slider:SetValue(0)
flickerstreak@30 2235 else
flickerstreak@30 2236 sliderFrame.slider:SetValue(1 - (parent.sliderValue - parent.sliderMin) / (parent.sliderMax - parent.sliderMin))
flickerstreak@30 2237 end
flickerstreak@30 2238 sliderFrame.changing = false
flickerstreak@30 2239 sliderFrame.bottomText:SetText(parent.sliderMinText or "0")
flickerstreak@30 2240 sliderFrame.topText:SetText(parent.sliderMaxText or "1")
flickerstreak@30 2241 local text
flickerstreak@30 2242 if parent.sliderFunc and not parent.fromAceOptions then
flickerstreak@30 2243 text = parent.sliderFunc(getArgs(parent, 'sliderArg', 1, parent.sliderValue))
flickerstreak@30 2244 end
flickerstreak@30 2245 if type(text) == "number" or type(text) == "string" then
flickerstreak@30 2246 sliderFrame.currentText:SetText(text)
flickerstreak@30 2247 elseif parent.sliderIsPercent then
flickerstreak@30 2248 sliderFrame.currentText:SetText(string.format("%.0f%%", parent.sliderValue * 100))
flickerstreak@30 2249 else
flickerstreak@30 2250 if parent.sliderStep < 0.1 then
flickerstreak@30 2251 sliderFrame.currentText:SetText(string.format("%.2f", parent.sliderValue))
flickerstreak@30 2252 elseif parent.sliderStep < 1 then
flickerstreak@30 2253 sliderFrame.currentText:SetText(string.format("%.1f", parent.sliderValue))
flickerstreak@30 2254 else
flickerstreak@30 2255 sliderFrame.currentText:SetText(string.format("%.0f", parent.sliderValue))
flickerstreak@30 2256 end
flickerstreak@30 2257 end
flickerstreak@30 2258
flickerstreak@30 2259
flickerstreak@30 2260 sliderFrame.lastValue = parent.sliderValue
flickerstreak@30 2261
flickerstreak@30 2262 local level = parent.level
flickerstreak@30 2263 sliderFrame:Show()
flickerstreak@30 2264 sliderFrame:ClearAllPoints()
flickerstreak@30 2265 if level.lastDirection == "RIGHT" then
flickerstreak@30 2266 if level.lastVDirection == "DOWN" then
flickerstreak@30 2267 sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 2268 else
flickerstreak@30 2269 sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 2270 end
flickerstreak@30 2271 else
flickerstreak@30 2272 if level.lastVDirection == "DOWN" then
flickerstreak@30 2273 sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 2274 else
flickerstreak@30 2275 sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 2276 end
flickerstreak@30 2277 end
flickerstreak@30 2278 local dirty
flickerstreak@30 2279 if level.lastDirection == "RIGHT" then
flickerstreak@30 2280 if sliderFrame:GetRight() > GetScreenWidth() then
flickerstreak@30 2281 level.lastDirection = "LEFT"
flickerstreak@30 2282 dirty = true
flickerstreak@30 2283 end
flickerstreak@30 2284 elseif sliderFrame:GetLeft() < 0 then
flickerstreak@30 2285 level.lastDirection = "RIGHT"
flickerstreak@30 2286 dirty = true
flickerstreak@30 2287 end
flickerstreak@30 2288 if level.lastVDirection == "DOWN" then
flickerstreak@30 2289 if sliderFrame:GetBottom() < 0 then
flickerstreak@30 2290 level.lastVDirection = "UP"
flickerstreak@30 2291 dirty = true
flickerstreak@30 2292 end
flickerstreak@30 2293 elseif sliderFrame:GetTop() > GetScreenWidth() then
flickerstreak@30 2294 level.lastVDirection = "DOWN"
flickerstreak@30 2295 dirty = true
flickerstreak@30 2296 end
flickerstreak@30 2297 if dirty then
flickerstreak@30 2298 sliderFrame:ClearAllPoints()
flickerstreak@30 2299 if level.lastDirection == "RIGHT" then
flickerstreak@30 2300 if level.lastVDirection == "DOWN" then
flickerstreak@30 2301 sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 2302 else
flickerstreak@30 2303 sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 2304 end
flickerstreak@30 2305 else
flickerstreak@30 2306 if level.lastVDirection == "DOWN" then
flickerstreak@30 2307 sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 2308 else
flickerstreak@30 2309 sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 2310 end
flickerstreak@30 2311 end
flickerstreak@30 2312 end
flickerstreak@30 2313 local left, bottom = sliderFrame:GetLeft(), sliderFrame:GetBottom()
flickerstreak@30 2314 sliderFrame:ClearAllPoints()
flickerstreak@30 2315 sliderFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
flickerstreak@30 2316 if mod(level.num, 5) == 0 then
flickerstreak@30 2317 local left, bottom = level:GetLeft(), level:GetBottom()
flickerstreak@30 2318 level:ClearAllPoints()
flickerstreak@30 2319 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
flickerstreak@30 2320 end
flickerstreak@30 2321 sliderFrame:SetClampedToScreen(true)
flickerstreak@30 2322 end
flickerstreak@30 2323
flickerstreak@30 2324 function OpenEditBox(self, parent)
flickerstreak@30 2325 if not editBoxFrame then
flickerstreak@30 2326 editBoxFrame = CreateFrame("Frame", nil, nil)
flickerstreak@30 2327 editBoxFrame:SetWidth(200)
flickerstreak@30 2328 editBoxFrame:SetHeight(40)
flickerstreak@30 2329 editBoxFrame:SetScale(UIParent:GetScale())
flickerstreak@30 2330 editBoxFrame:SetBackdrop(tmp(
flickerstreak@30 2331 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
flickerstreak@30 2332 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
flickerstreak@30 2333 'tile', true,
flickerstreak@30 2334 'insets', tmp2(
flickerstreak@30 2335 'left', 5,
flickerstreak@30 2336 'right', 5,
flickerstreak@30 2337 'top', 5,
flickerstreak@30 2338 'bottom', 5
flickerstreak@30 2339 ),
flickerstreak@30 2340 'tileSize', 16,
flickerstreak@30 2341 'edgeSize', 16
flickerstreak@30 2342 ))
flickerstreak@30 2343 editBoxFrame:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 2344 if editBoxFrame.SetTopLevel then
flickerstreak@30 2345 editBoxFrame:SetTopLevel(true)
flickerstreak@30 2346 end
flickerstreak@30 2347 editBoxFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
flickerstreak@30 2348 editBoxFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
flickerstreak@30 2349 editBoxFrame:EnableMouse(true)
flickerstreak@30 2350 editBoxFrame:EnableMouseWheel(true)
flickerstreak@30 2351 editBoxFrame:Hide()
flickerstreak@30 2352 editBoxFrame:SetPoint("CENTER", UIParent, "CENTER")
flickerstreak@30 2353
flickerstreak@30 2354 local editBox = CreateFrame("EditBox", nil, editBoxFrame)
flickerstreak@30 2355 editBoxFrame.editBox = editBox
flickerstreak@30 2356 editBox:SetFontObject(ChatFontNormal)
flickerstreak@30 2357 editBox:SetWidth(160)
flickerstreak@30 2358 editBox:SetHeight(13)
flickerstreak@30 2359 editBox:SetPoint("CENTER", editBoxFrame, "CENTER", 0, 0)
flickerstreak@30 2360
flickerstreak@30 2361 local left = editBox:CreateTexture(nil, "BACKGROUND")
flickerstreak@30 2362 left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
flickerstreak@30 2363 left:SetTexCoord(0, 100 / 256, 0, 1)
flickerstreak@30 2364 left:SetWidth(100)
flickerstreak@30 2365 left:SetHeight(32)
flickerstreak@30 2366 left:SetPoint("LEFT", editBox, "LEFT", -10, 0)
flickerstreak@30 2367 local right = editBox:CreateTexture(nil, "BACKGROUND")
flickerstreak@30 2368 right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
flickerstreak@30 2369 right:SetTexCoord(156/256, 1, 0, 1)
flickerstreak@30 2370 right:SetWidth(100)
flickerstreak@30 2371 right:SetHeight(32)
flickerstreak@30 2372 right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
flickerstreak@30 2373
flickerstreak@30 2374 editBox:SetScript("OnEnterPressed", function()
flickerstreak@30 2375 if editBoxFrame.parent and editBoxFrame.parent.editBoxValidateFunc then
flickerstreak@30 2376 local t = editBox.realText or editBox:GetText() or ""
flickerstreak@30 2377 local result = editBoxFrame.parent.editBoxValidateFunc(getArgs(editBoxFrame.parent, 'editBoxValidateArg', 1, t))
flickerstreak@30 2378 if not result then
flickerstreak@30 2379 UIErrorsFrame:AddMessage(VALIDATION_ERROR, 1, 0, 0)
flickerstreak@30 2380 return
flickerstreak@30 2381 end
flickerstreak@30 2382 end
flickerstreak@30 2383 if editBoxFrame.parent and editBoxFrame.parent.editBoxFunc then
flickerstreak@30 2384 local t
flickerstreak@30 2385 if editBox.realText ~= "NONE" then
flickerstreak@30 2386 t = editBox.realText or editBox:GetText() or ""
flickerstreak@30 2387 end
flickerstreak@30 2388 editBoxFrame.parent.editBoxFunc(getArgs(editBoxFrame.parent, 'editBoxArg', 1, t))
flickerstreak@30 2389 end
flickerstreak@30 2390 self:Close(editBoxFrame.level)
flickerstreak@30 2391 for i = 1, editBoxFrame.level - 1 do
flickerstreak@30 2392 Refresh(self, levels[i])
flickerstreak@30 2393 end
flickerstreak@30 2394 StartCounting(self, editBoxFrame.level-1)
flickerstreak@30 2395 end)
flickerstreak@30 2396 editBox:SetScript("OnEscapePressed", function()
flickerstreak@30 2397 self:Close(editBoxFrame.level)
flickerstreak@30 2398 StartCounting(self, editBoxFrame.level-1)
flickerstreak@30 2399 end)
flickerstreak@30 2400 editBox:SetScript("OnReceiveDrag", function(this)
flickerstreak@30 2401 if GetCursorInfo then
flickerstreak@30 2402 local type, alpha, bravo = GetCursorInfo()
flickerstreak@30 2403 local text
flickerstreak@30 2404 if type == "spell" then
flickerstreak@30 2405 text = GetSpellName(alpha, bravo)
flickerstreak@30 2406 elseif type == "item" then
flickerstreak@30 2407 text = bravo
flickerstreak@30 2408 end
flickerstreak@30 2409 if not text then
flickerstreak@30 2410 return
flickerstreak@30 2411 end
flickerstreak@30 2412 ClearCursor()
flickerstreak@30 2413 editBox:SetText(text)
flickerstreak@30 2414 end
flickerstreak@30 2415 end)
flickerstreak@30 2416 local changing = false
flickerstreak@30 2417 local skipNext = false
flickerstreak@30 2418
flickerstreak@30 2419 function editBox:SpecialSetText(text)
flickerstreak@30 2420 local oldText = editBox:GetText() or ""
flickerstreak@30 2421 if not text then
flickerstreak@30 2422 text = ""
flickerstreak@30 2423 end
flickerstreak@30 2424 if text ~= oldText then
flickerstreak@30 2425 changing = true
flickerstreak@30 2426 self:SetText(tostring(text))
flickerstreak@30 2427 changing = false
flickerstreak@30 2428 skipNext = true
flickerstreak@30 2429 end
flickerstreak@30 2430 end
flickerstreak@30 2431
flickerstreak@30 2432 editBox:SetScript("OnTextChanged", function()
flickerstreak@30 2433 if skipNext then
flickerstreak@30 2434 skipNext = false
flickerstreak@30 2435 elseif not changing and editBoxFrame.parent and editBoxFrame.parent.editBoxChangeFunc then
flickerstreak@30 2436 local t
flickerstreak@30 2437 if editBox.realText ~= "NONE" then
flickerstreak@30 2438 t = editBox.realText or editBox:GetText() or ""
flickerstreak@30 2439 end
flickerstreak@30 2440 local text = editBoxFrame.parent.editBoxChangeFunc(getArgs(editBoxFrame.parent, 'editBoxChangeArg', 1, t))
flickerstreak@30 2441 if text then
flickerstreak@30 2442 editBox:SpecialSetText(text)
flickerstreak@30 2443 end
flickerstreak@30 2444 end
flickerstreak@30 2445 end)
flickerstreak@30 2446 editBoxFrame:SetScript("OnEnter", function()
flickerstreak@30 2447 StopCounting(self, editBoxFrame.level)
flickerstreak@30 2448 showGameTooltip(editBoxFrame.parent)
flickerstreak@30 2449 end)
flickerstreak@30 2450 editBoxFrame:SetScript("OnLeave", function()
flickerstreak@30 2451 GameTooltip:Hide()
flickerstreak@30 2452 end)
flickerstreak@30 2453 editBox:SetScript("OnEnter", function()
flickerstreak@30 2454 StopCounting(self, editBoxFrame.level)
flickerstreak@30 2455 showGameTooltip(editBoxFrame.parent)
flickerstreak@30 2456 end)
flickerstreak@30 2457 editBox:SetScript("OnLeave", function()
flickerstreak@30 2458 GameTooltip:Hide()
flickerstreak@30 2459 end)
flickerstreak@30 2460 editBoxFrame:SetScript("OnKeyDown", function(this, a1)
flickerstreak@30 2461 if not editBox.keybinding then
flickerstreak@30 2462 return
flickerstreak@30 2463 end
flickerstreak@30 2464 local arg1 = a1 or arg1
flickerstreak@30 2465 local screenshotKey = GetBindingKey("SCREENSHOT")
flickerstreak@30 2466 if screenshotKey and arg1 == screenshotKey then
flickerstreak@30 2467 Screenshot()
flickerstreak@30 2468 return
flickerstreak@30 2469 end
flickerstreak@30 2470
flickerstreak@30 2471 if arg1 == "LeftButton" then
flickerstreak@30 2472 arg1 = "BUTTON1"
flickerstreak@30 2473 elseif arg1 == "RightButton" then
flickerstreak@30 2474 arg1 = "BUTTON2"
flickerstreak@30 2475 elseif arg1 == "MiddleButton" then
flickerstreak@30 2476 arg1 = "BUTTON3"
flickerstreak@30 2477 elseif arg1 == "Button4" then
flickerstreak@30 2478 arg1 = "BUTTON4"
flickerstreak@30 2479 elseif arg1 == "Button5" then
flickerstreak@30 2480 arg1 = "BUTTON5"
flickerstreak@30 2481 end
flickerstreak@30 2482 if arg1 == "UNKNOWN" then
flickerstreak@30 2483 return
flickerstreak@30 2484 elseif arg1 == "SHIFT" or arg1 == "CTRL" or arg1 == "ALT" then
flickerstreak@30 2485 return
flickerstreak@30 2486 elseif arg1 == "ENTER" then
flickerstreak@30 2487 if editBox.keybindingOnly and not editBox.keybindingOnly[editBox.realText] then
flickerstreak@30 2488 return editBox:GetScript("OnEscapePressed")()
flickerstreak@30 2489 elseif editBox.keybindingExcept and editBox.keybindingExcept[editBox.realText] then
flickerstreak@30 2490 return editBox:GetScript("OnEscapePressed")()
flickerstreak@30 2491 else
flickerstreak@30 2492 return editBox:GetScript("OnEnterPressed")()
flickerstreak@30 2493 end
flickerstreak@30 2494 elseif arg1 == "ESCAPE" then
flickerstreak@30 2495 if editBox.realText == "NONE" then
flickerstreak@30 2496 return editBox:GetScript("OnEscapePressed")()
flickerstreak@30 2497 else
flickerstreak@30 2498 editBox:SpecialSetText(NONE or "NONE")
flickerstreak@30 2499 editBox.realText = "NONE"
flickerstreak@30 2500 return
flickerstreak@30 2501 end
flickerstreak@30 2502 elseif editBox.keybindingOnly and not editBox.keybindingOnly[arg1] then
flickerstreak@30 2503 return
flickerstreak@30 2504 elseif editBox.keybindingExcept and editBox.keybindingExcept[arg1] then
flickerstreak@30 2505 return
flickerstreak@30 2506 end
flickerstreak@30 2507 local s = GetBindingText(arg1, "KEY_")
flickerstreak@30 2508 if s == "BUTTON1" then
flickerstreak@30 2509 s = KEY_BUTTON1
flickerstreak@30 2510 elseif s == "BUTTON2" then
flickerstreak@30 2511 s = KEY_BUTTON2
flickerstreak@30 2512 end
flickerstreak@30 2513 local real = arg1
flickerstreak@30 2514 if IsShiftKeyDown() then
flickerstreak@30 2515 s = "Shift-" .. s
flickerstreak@30 2516 real = "SHIFT-" .. real
flickerstreak@30 2517 end
flickerstreak@30 2518 if IsControlKeyDown() then
flickerstreak@30 2519 s = "Ctrl-" .. s
flickerstreak@30 2520 real = "CTRL-" .. real
flickerstreak@30 2521 end
flickerstreak@30 2522 if IsAltKeyDown() then
flickerstreak@30 2523 s = "Alt-" .. s
flickerstreak@30 2524 real = "ALT-" .. real
flickerstreak@30 2525 end
flickerstreak@30 2526 if editBox:GetText() ~= s then
flickerstreak@30 2527 editBox:SpecialSetText("-")
flickerstreak@30 2528 editBox:SpecialSetText(s)
flickerstreak@30 2529 editBox.realText = real
flickerstreak@30 2530 return editBox:GetScript("OnTextChanged")()
flickerstreak@30 2531 end
flickerstreak@30 2532 end)
flickerstreak@30 2533 editBoxFrame:SetScript("OnMouseDown", editBoxFrame:GetScript("OnKeyDown"))
flickerstreak@30 2534 editBox:SetScript("OnMouseDown", function(this, ...)
flickerstreak@30 2535 if GetCursorInfo and (CursorHasItem() or CursorHasSpell()) then
flickerstreak@30 2536 return editBox:GetScript("OnReceiveDrag")(this, ...)
flickerstreak@30 2537 end
flickerstreak@30 2538 return editBoxFrame:GetScript("OnKeyDown")(this, ...)
flickerstreak@30 2539 end)
flickerstreak@30 2540 editBoxFrame:SetScript("OnMouseWheel", function(t, a1)
flickerstreak@30 2541 local arg1 = a1 or arg1
flickerstreak@30 2542 local up = arg1 > 0
flickerstreak@30 2543 arg1 = up and "MOUSEWHEELUP" or "MOUSEWHEELDOWN"
flickerstreak@30 2544 return editBoxFrame:GetScript("OnKeyDown")(t or this, arg1)
flickerstreak@30 2545 end)
flickerstreak@30 2546 editBox:SetScript("OnMouseWheel", editBoxFrame:GetScript("OnMouseWheel"))
flickerstreak@30 2547 end
flickerstreak@30 2548 editBoxFrame.parent = parent
flickerstreak@30 2549 editBoxFrame.level = parent.level.num + 1
flickerstreak@30 2550 editBoxFrame.parentValue = parent.level.value
flickerstreak@30 2551 editBoxFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3)
flickerstreak@30 2552 editBoxFrame.editBox:SetFrameLevel(editBoxFrame:GetFrameLevel() + 1)
flickerstreak@30 2553 editBoxFrame.editBox.realText = nil
flickerstreak@30 2554 editBoxFrame:SetClampedToScreen(false)
flickerstreak@30 2555
flickerstreak@30 2556 editBoxFrame.editBox:SpecialSetText("")
flickerstreak@30 2557 if parent.editBoxIsKeybinding then
flickerstreak@30 2558 local s = parent.editBoxText
flickerstreak@30 2559 if s == "" then
flickerstreak@30 2560 s = "NONE"
flickerstreak@30 2561 end
flickerstreak@30 2562 editBoxFrame.editBox.realText = s
flickerstreak@30 2563 if s and s ~= "NONE" then
flickerstreak@30 2564 local alpha,bravo = s:match("^(.+)%-(.+)$")
flickerstreak@30 2565 if not bravo then
flickerstreak@30 2566 alpha = nil
flickerstreak@30 2567 bravo = s
flickerstreak@30 2568 end
flickerstreak@30 2569 bravo = GetBindingText(bravo, "KEY_")
flickerstreak@30 2570 if alpha then
flickerstreak@30 2571 editBoxFrame.editBox:SpecialSetText(alpha:upper() .. "-" .. bravo)
flickerstreak@30 2572 else
flickerstreak@30 2573 editBoxFrame.editBox:SpecialSetText(bravo)
flickerstreak@30 2574 end
flickerstreak@30 2575 else
flickerstreak@30 2576 editBoxFrame.editBox:SpecialSetText(NONE or "NONE")
flickerstreak@30 2577 end
flickerstreak@30 2578 else
flickerstreak@30 2579 editBoxFrame.editBox:SpecialSetText(parent.editBoxText)
flickerstreak@30 2580 end
flickerstreak@30 2581
flickerstreak@30 2582 editBoxFrame.editBox.keybinding = parent.editBoxIsKeybinding
flickerstreak@30 2583 editBoxFrame.editBox.keybindingOnly = parent.editBoxKeybindingOnly
flickerstreak@30 2584 editBoxFrame.editBox.keybindingExcept = parent.editBoxKeybindingExcept
flickerstreak@30 2585 editBoxFrame.editBox:EnableKeyboard(not parent.editBoxIsKeybinding)
flickerstreak@30 2586 editBoxFrame:EnableKeyboard(parent.editBoxIsKeybinding)
flickerstreak@30 2587
flickerstreak@30 2588 if parent.arrow then
flickerstreak@30 2589 -- parent.arrow:SetVertexColor(0.2, 0.6, 0)
flickerstreak@30 2590 -- parent.arrow:SetHeight(24)
flickerstreak@30 2591 -- parent.arrow:SetWidth(24)
flickerstreak@30 2592 parent.selected = true
flickerstreak@30 2593 parent.highlight:Show()
flickerstreak@30 2594 end
flickerstreak@30 2595
flickerstreak@30 2596 local level = parent.level
flickerstreak@30 2597 editBoxFrame:Show()
flickerstreak@30 2598 editBoxFrame:ClearAllPoints()
flickerstreak@30 2599 if level.lastDirection == "RIGHT" then
flickerstreak@30 2600 if level.lastVDirection == "DOWN" then
flickerstreak@30 2601 editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 2602 else
flickerstreak@30 2603 editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 2604 end
flickerstreak@30 2605 else
flickerstreak@30 2606 if level.lastVDirection == "DOWN" then
flickerstreak@30 2607 editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 2608 else
flickerstreak@30 2609 editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 2610 end
flickerstreak@30 2611 end
flickerstreak@30 2612 local dirty
flickerstreak@30 2613 if level.lastDirection == "RIGHT" then
flickerstreak@30 2614 if editBoxFrame:GetRight() > GetScreenWidth() then
flickerstreak@30 2615 level.lastDirection = "LEFT"
flickerstreak@30 2616 dirty = true
flickerstreak@30 2617 end
flickerstreak@30 2618 elseif editBoxFrame:GetLeft() < 0 then
flickerstreak@30 2619 level.lastDirection = "RIGHT"
flickerstreak@30 2620 dirty = true
flickerstreak@30 2621 end
flickerstreak@30 2622 if level.lastVDirection == "DOWN" then
flickerstreak@30 2623 if editBoxFrame:GetBottom() < 0 then
flickerstreak@30 2624 level.lastVDirection = "UP"
flickerstreak@30 2625 dirty = true
flickerstreak@30 2626 end
flickerstreak@30 2627 elseif editBoxFrame:GetTop() > GetScreenWidth() then
flickerstreak@30 2628 level.lastVDirection = "DOWN"
flickerstreak@30 2629 dirty = true
flickerstreak@30 2630 end
flickerstreak@30 2631 if dirty then
flickerstreak@30 2632 editBoxFrame:ClearAllPoints()
flickerstreak@30 2633 if level.lastDirection == "RIGHT" then
flickerstreak@30 2634 if level.lastVDirection == "DOWN" then
flickerstreak@30 2635 editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
flickerstreak@30 2636 else
flickerstreak@30 2637 editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
flickerstreak@30 2638 end
flickerstreak@30 2639 else
flickerstreak@30 2640 if level.lastVDirection == "DOWN" then
flickerstreak@30 2641 editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
flickerstreak@30 2642 else
flickerstreak@30 2643 editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
flickerstreak@30 2644 end
flickerstreak@30 2645 end
flickerstreak@30 2646 end
flickerstreak@30 2647 local left, bottom = editBoxFrame:GetLeft(), editBoxFrame:GetBottom()
flickerstreak@30 2648 editBoxFrame:ClearAllPoints()
flickerstreak@30 2649 editBoxFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
flickerstreak@30 2650 if mod(level.num, 5) == 0 then
flickerstreak@30 2651 local left, bottom = level:GetLeft(), level:GetBottom()
flickerstreak@30 2652 level:ClearAllPoints()
flickerstreak@30 2653 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
flickerstreak@30 2654 end
flickerstreak@30 2655 editBoxFrame:SetClampedToScreen(true)
flickerstreak@30 2656 end
flickerstreak@30 2657
flickerstreak@30 2658 function Dewdrop:EncodeKeybinding(text)
flickerstreak@30 2659 if text == nil or text == "NONE" then
flickerstreak@30 2660 return nil
flickerstreak@30 2661 end
flickerstreak@30 2662 text = tostring(text):upper()
flickerstreak@30 2663 local shift, ctrl, alt
flickerstreak@30 2664 local modifier
flickerstreak@30 2665 while true do
flickerstreak@30 2666 if text == "-" then
flickerstreak@30 2667 break
flickerstreak@30 2668 end
flickerstreak@30 2669 modifier, text = strsplit('-', text, 2)
flickerstreak@30 2670 if text then
flickerstreak@30 2671 if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
flickerstreak@30 2672 return false
flickerstreak@30 2673 end
flickerstreak@30 2674 if modifier == "SHIFT" then
flickerstreak@30 2675 if shift then
flickerstreak@30 2676 return false
flickerstreak@30 2677 end
flickerstreak@30 2678 shift = true
flickerstreak@30 2679 end
flickerstreak@30 2680 if modifier == "CTRL" then
flickerstreak@30 2681 if ctrl then
flickerstreak@30 2682 return false
flickerstreak@30 2683 end
flickerstreak@30 2684 ctrl = true
flickerstreak@30 2685 end
flickerstreak@30 2686 if modifier == "ALT" then
flickerstreak@30 2687 if alt then
flickerstreak@30 2688 return false
flickerstreak@30 2689 end
flickerstreak@30 2690 alt = true
flickerstreak@30 2691 end
flickerstreak@30 2692 else
flickerstreak@30 2693 text = modifier
flickerstreak@30 2694 break
flickerstreak@30 2695 end
flickerstreak@30 2696 end
flickerstreak@30 2697 if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:len() == 0 or text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] and text ~= "BUTTON1" and text ~= "BUTTON2" then
flickerstreak@30 2698 return false
flickerstreak@30 2699 end
flickerstreak@30 2700 local s = GetBindingText(text, "KEY_")
flickerstreak@30 2701 if s == "BUTTON1" then
flickerstreak@30 2702 s = KEY_BUTTON1
flickerstreak@30 2703 elseif s == "BUTTON2" then
flickerstreak@30 2704 s = KEY_BUTTON2
flickerstreak@30 2705 end
flickerstreak@30 2706 if shift then
flickerstreak@30 2707 s = "Shift-" .. s
flickerstreak@30 2708 end
flickerstreak@30 2709 if ctrl then
flickerstreak@30 2710 s = "Ctrl-" .. s
flickerstreak@30 2711 end
flickerstreak@30 2712 if alt then
flickerstreak@30 2713 s = "Alt-" .. s
flickerstreak@30 2714 end
flickerstreak@30 2715 return s
flickerstreak@30 2716 end
flickerstreak@30 2717
flickerstreak@30 2718 function Dewdrop:IsOpen(parent)
flickerstreak@30 2719 self:argCheck(parent, 2, "table", "string", "nil")
flickerstreak@30 2720 return levels[1] and levels[1]:IsShown() and (not parent or parent == levels[1].parent or parent == levels[1]:GetParent())
flickerstreak@30 2721 end
flickerstreak@30 2722
flickerstreak@30 2723 function Dewdrop:GetOpenedParent()
flickerstreak@30 2724 return (levels[1] and levels[1]:IsShown()) and (levels[1].parent or levels[1]:GetParent())
flickerstreak@30 2725 end
flickerstreak@30 2726
flickerstreak@30 2727 function Open(self, parent, func, level, value, point, relativePoint, cursorX, cursorY)
flickerstreak@30 2728 self:Close(level)
flickerstreak@30 2729 if DewdropLib then
flickerstreak@30 2730 local d = DewdropLib:GetInstance('1.0')
flickerstreak@30 2731 local ret, val = pcall(d, IsOpen, d)
flickerstreak@30 2732 if ret and val then
flickerstreak@30 2733 DewdropLib:GetInstance('1.0'):Close()
flickerstreak@30 2734 end
flickerstreak@30 2735 end
flickerstreak@30 2736 if type(parent) == "table" then
flickerstreak@30 2737 parent:GetCenter()
flickerstreak@30 2738 end
flickerstreak@30 2739 local frame = AcquireLevel(self, level)
flickerstreak@30 2740 if level == 1 then
flickerstreak@30 2741 frame.lastDirection = "RIGHT"
flickerstreak@30 2742 frame.lastVDirection = "DOWN"
flickerstreak@30 2743 else
flickerstreak@30 2744 frame.lastDirection = levels[level - 1].lastDirection
flickerstreak@30 2745 frame.lastVDirection = levels[level - 1].lastVDirection
flickerstreak@30 2746 end
flickerstreak@30 2747 frame:SetFrameStrata("FULLSCREEN_DIALOG")
flickerstreak@30 2748 frame:ClearAllPoints()
flickerstreak@30 2749 frame.parent = parent
flickerstreak@30 2750 frame:SetPoint("LEFT", UIParent, "RIGHT", 10000, 0)
flickerstreak@30 2751 frame:Show()
flickerstreak@30 2752 if level == 1 then
flickerstreak@30 2753 baseFunc = func
flickerstreak@30 2754 end
flickerstreak@30 2755 levels[level].value = value
flickerstreak@30 2756 -- levels[level].parentText = parent.text and parent.text:GetText() or nil
flickerstreak@30 2757 -- levels[level].parentTooltipTitle = parent.tooltipTitle
flickerstreak@30 2758 -- levels[level].parentTooltipText = parent.tooltipText
flickerstreak@30 2759 -- levels[level].parentTooltipFunc = parent.tooltipFunc
flickerstreak@30 2760 if type(parent) == "table" and parent.arrow then
flickerstreak@30 2761 -- parent.arrow:SetVertexColor(0.2, 0.6, 0)
flickerstreak@30 2762 -- parent.arrow:SetHeight(24)
flickerstreak@30 2763 -- parent.arrow:SetWidth(24)
flickerstreak@30 2764 parent.selected = true
flickerstreak@30 2765 parent.highlight:Show()
flickerstreak@30 2766 end
flickerstreak@30 2767 relativePoint = relativePoint or point
flickerstreak@30 2768 Refresh(self, levels[level])
flickerstreak@30 2769 if point or (cursorX and cursorY) then
flickerstreak@30 2770 frame:ClearAllPoints()
flickerstreak@30 2771 if cursorX and cursorY then
flickerstreak@30 2772 local curX, curY = GetScaledCursorPosition()
flickerstreak@30 2773 if curY < GetScreenHeight() / 2 then
flickerstreak@30 2774 point, relativePoint = "BOTTOM", "BOTTOM"
flickerstreak@30 2775 else
flickerstreak@30 2776 point, relativePoint = "TOP", "TOP"
flickerstreak@30 2777 end
flickerstreak@30 2778 if curX < GetScreenWidth() / 2 then
flickerstreak@30 2779 point, relativePoint = point .. "LEFT", relativePoint .. "RIGHT"
flickerstreak@30 2780 else
flickerstreak@30 2781 point, relativePoint = point .. "RIGHT", relativePoint .. "LEFT"
flickerstreak@30 2782 end
flickerstreak@30 2783 end
flickerstreak@30 2784 frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint)
flickerstreak@30 2785 if cursorX and cursorY then
flickerstreak@30 2786 local left = frame:GetLeft()
flickerstreak@30 2787 local width = frame:GetWidth()
flickerstreak@30 2788 local bottom = frame:GetBottom()
flickerstreak@30 2789 local height = frame:GetHeight()
flickerstreak@30 2790 local curX, curY = GetScaledCursorPosition()
flickerstreak@30 2791 frame:ClearAllPoints()
flickerstreak@30 2792 relativePoint = relativePoint or point
flickerstreak@30 2793 if point == "BOTTOM" or point == "TOP" then
flickerstreak@30 2794 if curX < GetScreenWidth() / 2 then
flickerstreak@30 2795 point = point .. "LEFT"
flickerstreak@30 2796 else
flickerstreak@30 2797 point = point .. "RIGHT"
flickerstreak@30 2798 end
flickerstreak@30 2799 elseif point == "CENTER" then
flickerstreak@30 2800 if curX < GetScreenWidth() / 2 then
flickerstreak@30 2801 point = "LEFT"
flickerstreak@30 2802 else
flickerstreak@30 2803 point = "RIGHT"
flickerstreak@30 2804 end
flickerstreak@30 2805 end
flickerstreak@30 2806 local xOffset, yOffset = 0, 0
flickerstreak@30 2807 if curY > GetScreenHeight() / 2 then
flickerstreak@30 2808 yOffset = -height
flickerstreak@30 2809 end
flickerstreak@30 2810 if curX > GetScreenWidth() / 2 then
flickerstreak@30 2811 xOffset = -width
flickerstreak@30 2812 end
flickerstreak@30 2813 frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left + xOffset, curY - bottom + yOffset)
flickerstreak@30 2814 if level == 1 then
flickerstreak@30 2815 frame.lastDirection = "RIGHT"
flickerstreak@30 2816 end
flickerstreak@30 2817 elseif cursorX then
flickerstreak@30 2818 local left = frame:GetLeft()
flickerstreak@30 2819 local width = frame:GetWidth()
flickerstreak@30 2820 local curX, curY = GetScaledCursorPosition()
flickerstreak@30 2821 frame:ClearAllPoints()
flickerstreak@30 2822 relativePoint = relativePoint or point
flickerstreak@30 2823 if point == "BOTTOM" or point == "TOP" then
flickerstreak@30 2824 if curX < GetScreenWidth() / 2 then
flickerstreak@30 2825 point = point .. "LEFT"
flickerstreak@30 2826 else
flickerstreak@30 2827 point = point .. "RIGHT"
flickerstreak@30 2828 end
flickerstreak@30 2829 elseif point == "CENTER" then
flickerstreak@30 2830 if curX < GetScreenWidth() / 2 then
flickerstreak@30 2831 point = "LEFT"
flickerstreak@30 2832 else
flickerstreak@30 2833 point = "RIGHT"
flickerstreak@30 2834 end
flickerstreak@30 2835 end
flickerstreak@30 2836 frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left - width / 2, 0)
flickerstreak@30 2837 if level == 1 then
flickerstreak@30 2838 frame.lastDirection = "RIGHT"
flickerstreak@30 2839 end
flickerstreak@30 2840 elseif cursorY then
flickerstreak@30 2841 local bottom = frame:GetBottom()
flickerstreak@30 2842 local height = frame:GetHeight()
flickerstreak@30 2843 local curX, curY = GetScaledCursorPosition()
flickerstreak@30 2844 frame:ClearAllPoints()
flickerstreak@30 2845 relativePoint = relativePoint or point
flickerstreak@30 2846 if point == "LEFT" or point == "RIGHT" then
flickerstreak@30 2847 if curX < GetScreenHeight() / 2 then
flickerstreak@30 2848 point = point .. "BOTTOM"
flickerstreak@30 2849 else
flickerstreak@30 2850 point = point .. "TOP"
flickerstreak@30 2851 end
flickerstreak@30 2852 elseif point == "CENTER" then
flickerstreak@30 2853 if curX < GetScreenHeight() / 2 then
flickerstreak@30 2854 point = "BOTTOM"
flickerstreak@30 2855 else
flickerstreak@30 2856 point = "TOP"
flickerstreak@30 2857 end
flickerstreak@30 2858 end
flickerstreak@30 2859 frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, 0, curY - bottom - height / 2)
flickerstreak@30 2860 if level == 1 then
flickerstreak@30 2861 frame.lastDirection = "DOWN"
flickerstreak@30 2862 end
flickerstreak@30 2863 end
flickerstreak@30 2864 if (strsub(point, 1, 3) ~= strsub(relativePoint, 1, 3)) then
flickerstreak@30 2865 if frame:GetBottom() < 0 then
flickerstreak@30 2866 local point, parent, relativePoint, x, y = frame:GetPoint(1)
flickerstreak@30 2867 local change = GetScreenHeight() - frame:GetTop()
flickerstreak@30 2868 local otherChange = -frame:GetBottom()
flickerstreak@30 2869 if otherChange < change then
flickerstreak@30 2870 change = otherChange
flickerstreak@30 2871 end
flickerstreak@30 2872 frame:SetPoint(point, parent, relativePoint, x, y + change)
flickerstreak@30 2873 elseif frame:GetTop() > GetScreenHeight() then
flickerstreak@30 2874 local point, parent, relativePoint, x, y = frame:GetPoint(1)
flickerstreak@30 2875 local change = GetScreenHeight() - frame:GetTop()
flickerstreak@30 2876 local otherChange = -frame:GetBottom()
flickerstreak@30 2877 if otherChange < change then
flickerstreak@30 2878 change = otherChange
flickerstreak@30 2879 end
flickerstreak@30 2880 frame:SetPoint(point, parent, relativePoint, x, y + change)
flickerstreak@30 2881 end
flickerstreak@30 2882 end
flickerstreak@30 2883 end
flickerstreak@30 2884 CheckDualMonitor(self, frame)
flickerstreak@30 2885 frame:SetClampedToScreen(true)
flickerstreak@30 2886 frame:SetClampedToScreen(false)
flickerstreak@30 2887 StartCounting(self, level)
flickerstreak@30 2888 end
flickerstreak@30 2889
flickerstreak@30 2890 function Dewdrop:IsRegistered(parent)
flickerstreak@30 2891 self:argCheck(parent, 2, "table", "string")
flickerstreak@30 2892 return not not self.registry[parent]
flickerstreak@30 2893 end
flickerstreak@30 2894
flickerstreak@30 2895 function Dewdrop:Register(parent, ...)
flickerstreak@30 2896 self:argCheck(parent, 2, "table", "string")
flickerstreak@30 2897 if self.registry[parent] then
flickerstreak@30 2898 self:Unregister(parent)
flickerstreak@30 2899 end
flickerstreak@30 2900 local info = new(...)
flickerstreak@30 2901 if type(info.children) == "table" then
flickerstreak@30 2902 local err, position = validateOptions(info.children)
flickerstreak@30 2903
flickerstreak@30 2904 if err then
flickerstreak@30 2905 if position then
flickerstreak@30 2906 Dewdrop:error(position .. ": " .. err)
flickerstreak@30 2907 else
flickerstreak@30 2908 Dewdrop:error(err)
flickerstreak@30 2909 end
flickerstreak@30 2910 end
flickerstreak@30 2911 end
flickerstreak@30 2912 self.registry[parent] = info
flickerstreak@30 2913 if not info.dontHook and not self.onceRegistered[parent] and type(parent) == "table" then
flickerstreak@30 2914 if parent:HasScript("OnMouseUp") then
flickerstreak@30 2915 local script = parent:GetScript("OnMouseUp")
flickerstreak@30 2916 parent:SetScript("OnMouseUp", function(this, ...)
flickerstreak@30 2917 if script then
flickerstreak@30 2918 script(this, ...)
flickerstreak@30 2919 end
flickerstreak@30 2920 if arg1 == "RightButton" and self.registry[parent] then
flickerstreak@30 2921 if self:IsOpen(parent) then
flickerstreak@30 2922 self:Close()
flickerstreak@30 2923 else
flickerstreak@30 2924 self:Open(parent)
flickerstreak@30 2925 end
flickerstreak@30 2926 end
flickerstreak@30 2927 end)
flickerstreak@30 2928 end
flickerstreak@30 2929 if parent:HasScript("OnMouseDown") then
flickerstreak@30 2930 local script = parent:GetScript("OnMouseDown")
flickerstreak@30 2931 parent:SetScript("OnMouseDown", function(this, ...)
flickerstreak@30 2932 if script then
flickerstreak@30 2933 script(this, ...)
flickerstreak@30 2934 end
flickerstreak@30 2935 if self.registry[parent] then
flickerstreak@30 2936 self:Close()
flickerstreak@30 2937 end
flickerstreak@30 2938 end)
flickerstreak@30 2939 end
flickerstreak@30 2940 end
flickerstreak@30 2941 self.onceRegistered[parent] = true
flickerstreak@30 2942 end
flickerstreak@30 2943
flickerstreak@30 2944 function Dewdrop:Unregister(parent)
flickerstreak@30 2945 self:argCheck(parent, 2, "table", "string")
flickerstreak@30 2946 self.registry[parent] = nil
flickerstreak@30 2947 end
flickerstreak@30 2948
flickerstreak@30 2949 function Dewdrop:Open(parent, ...)
flickerstreak@30 2950 self:argCheck(parent, 2, "table", "string")
flickerstreak@30 2951 local info
flickerstreak@30 2952 local k1 = ...
flickerstreak@30 2953 if type(k1) == "table" and k1[0] and k1.IsFrameType and self.registry[k1] then
flickerstreak@30 2954 info = tmp(select(2, ...))
flickerstreak@30 2955 for k,v in pairs(self.registry[k1]) do
flickerstreak@30 2956 if info[k] == nil then
flickerstreak@30 2957 info[k] = v
flickerstreak@30 2958 end
flickerstreak@30 2959 end
flickerstreak@30 2960 else
flickerstreak@30 2961 info = tmp(...)
flickerstreak@30 2962 if self.registry[parent] then
flickerstreak@30 2963 for k,v in pairs(self.registry[parent]) do
flickerstreak@30 2964 if info[k] == nil then
flickerstreak@30 2965 info[k] = v
flickerstreak@30 2966 end
flickerstreak@30 2967 end
flickerstreak@30 2968 end
flickerstreak@30 2969 end
flickerstreak@30 2970 local point = info.point
flickerstreak@30 2971 local relativePoint = info.relativePoint
flickerstreak@30 2972 local cursorX = info.cursorX
flickerstreak@30 2973 local cursorY = info.cursorY
flickerstreak@30 2974 if type(point) == "function" then
flickerstreak@30 2975 local b
flickerstreak@30 2976 point, b = point(parent)
flickerstreak@30 2977 if b then
flickerstreak@30 2978 relativePoint = b
flickerstreak@30 2979 end
flickerstreak@30 2980 end
flickerstreak@30 2981 if type(relativePoint) == "function" then
flickerstreak@30 2982 relativePoint = relativePoint(parent)
flickerstreak@30 2983 end
flickerstreak@30 2984 Open(self, parent, info.children, 1, nil, point, relativePoint, cursorX, cursorY)
flickerstreak@30 2985 end
flickerstreak@30 2986
flickerstreak@30 2987 function Clear(self, level)
flickerstreak@30 2988 if level then
flickerstreak@30 2989 if level.buttons then
flickerstreak@30 2990 for i = #level.buttons, 1, -1 do
flickerstreak@30 2991 ReleaseButton(self, level, i)
flickerstreak@30 2992 end
flickerstreak@30 2993 end
flickerstreak@30 2994 end
flickerstreak@30 2995 end
flickerstreak@30 2996
flickerstreak@30 2997 function Dewdrop:Close(level)
flickerstreak@30 2998 if DropDownList1:IsShown() then
flickerstreak@30 2999 DropDownList1:Hide()
flickerstreak@30 3000 end
flickerstreak@30 3001 if DewdropLib then
flickerstreak@30 3002 local d = DewdropLib:GetInstance('1.0')
flickerstreak@30 3003 local ret, val = pcall(d, IsOpen, d)
flickerstreak@30 3004 if ret and val then
flickerstreak@30 3005 DewdropLib:GetInstance('1.0'):Close()
flickerstreak@30 3006 end
flickerstreak@30 3007 end
flickerstreak@30 3008 self:argCheck(level, 2, "number", "nil")
flickerstreak@30 3009 if not level then
flickerstreak@30 3010 level = 1
flickerstreak@30 3011 end
flickerstreak@30 3012 if level == 1 and levels[level] then
flickerstreak@30 3013 levels[level].parented = false
flickerstreak@30 3014 end
flickerstreak@30 3015 if level > 1 and levels[level-1].buttons then
flickerstreak@30 3016 local buttons = levels[level-1].buttons
flickerstreak@30 3017 for _,button in ipairs(buttons) do
flickerstreak@30 3018 -- button.arrow:SetWidth(16)
flickerstreak@30 3019 -- button.arrow:SetHeight(16)
flickerstreak@30 3020 button.selected = nil
flickerstreak@30 3021 button.highlight:Hide()
flickerstreak@30 3022 -- button.arrow:SetVertexColor(1, 1, 1)
flickerstreak@30 3023 end
flickerstreak@30 3024 end
flickerstreak@30 3025 if sliderFrame and sliderFrame.level >= level then
flickerstreak@30 3026 sliderFrame:Hide()
flickerstreak@30 3027 end
flickerstreak@30 3028 if editBoxFrame and editBoxFrame.level >= level then
flickerstreak@30 3029 editBoxFrame:Hide()
flickerstreak@30 3030 end
flickerstreak@30 3031 for i = level, #levels do
flickerstreak@30 3032 Clear(self, levels[level])
flickerstreak@30 3033 levels[i]:Hide()
flickerstreak@30 3034 levels[i]:ClearAllPoints()
flickerstreak@30 3035 levels[i]:SetPoint("CENTER", UIParent, "CENTER")
flickerstreak@30 3036 levels[i].value = nil
flickerstreak@30 3037 end
flickerstreak@30 3038 end
flickerstreak@30 3039
flickerstreak@30 3040 function Dewdrop:AddSeparator(level)
flickerstreak@30 3041 level = levels[level or currentLevel]
flickerstreak@30 3042 if not level or not level.buttons then return; end
flickerstreak@30 3043
flickerstreak@30 3044 local prevbutton = level.buttons[#level.buttons]
flickerstreak@30 3045 if not prevbutton then return; end
flickerstreak@30 3046
flickerstreak@30 3047 if prevbutton.disabled and prevbutton.text:GetText() == "" then
flickerstreak@30 3048 return
flickerstreak@30 3049 end
flickerstreak@30 3050 self:AddLine("text", "", "disabled", true)
flickerstreak@30 3051 end
flickerstreak@30 3052
flickerstreak@30 3053 function Dewdrop:AddLine(...)
flickerstreak@30 3054 local info = tmp(...)
flickerstreak@30 3055 local level = info.level or currentLevel
flickerstreak@30 3056 info.level = nil
flickerstreak@30 3057 local button = AcquireButton(self, level)
flickerstreak@30 3058 if not next(info) then
flickerstreak@30 3059 info.disabled = true
flickerstreak@30 3060 end
flickerstreak@30 3061 button.disabled = info.isTitle or info.notClickable or info.disabled or (self.combat and info.secure)
flickerstreak@30 3062 button.isTitle = info.isTitle
flickerstreak@30 3063 button.notClickable = info.notClickable
flickerstreak@30 3064 if button.isTitle then
flickerstreak@30 3065 button.text:SetFontObject(GameFontNormalSmall)
flickerstreak@30 3066 elseif button.notClickable then
flickerstreak@30 3067 button.text:SetFontObject(GameFontHighlightSmall)
flickerstreak@30 3068 elseif button.disabled then
flickerstreak@30 3069 button.text:SetFontObject(GameFontDisableSmall)
flickerstreak@30 3070 else
flickerstreak@30 3071 button.text:SetFontObject(GameFontHighlightSmall)
flickerstreak@30 3072 end
flickerstreak@30 3073 if info.disabled then
flickerstreak@30 3074 button.arrow:SetDesaturated(true)
flickerstreak@30 3075 button.check:SetDesaturated(true)
flickerstreak@30 3076 else
flickerstreak@30 3077 button.arrow:SetDesaturated(false)
flickerstreak@30 3078 button.check:SetDesaturated(false)
flickerstreak@30 3079 end
flickerstreak@30 3080 if info.textR and info.textG and info.textB then
flickerstreak@30 3081 button.textR = info.textR
flickerstreak@30 3082 button.textG = info.textG
flickerstreak@30 3083 button.textB = info.textB
flickerstreak@30 3084 button.text:SetTextColor(button.textR, button.textG, button.textB)
flickerstreak@30 3085 else
flickerstreak@30 3086 button.text:SetTextColor(button.text:GetFontObject():GetTextColor())
flickerstreak@30 3087 end
flickerstreak@30 3088 button.notCheckable = info.notCheckable
flickerstreak@30 3089 button.text:SetPoint("LEFT", button, "LEFT", button.notCheckable and 0 or 24, 0)
flickerstreak@30 3090 button.checked = not info.notCheckable and info.checked
flickerstreak@30 3091 button.mouseoverUnderline = info.mouseoverUnderline
flickerstreak@30 3092 button.isRadio = not info.notCheckable and info.isRadio
flickerstreak@30 3093 if info.isRadio then
flickerstreak@30 3094 button.check:Show()
flickerstreak@30 3095 button.check:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
flickerstreak@30 3096 if button.checked then
flickerstreak@30 3097 button.check:SetTexCoord(0.25, 0.5, 0, 1)
flickerstreak@30 3098 button.check:SetVertexColor(1, 1, 1, 1)
flickerstreak@30 3099 else
flickerstreak@30 3100 button.check:SetTexCoord(0, 0.25, 0, 1)
flickerstreak@30 3101 button.check:SetVertexColor(1, 1, 1, 0.5)
flickerstreak@30 3102 end
flickerstreak@30 3103 button.radioHighlight:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
flickerstreak@30 3104 button.check:SetWidth(16)
flickerstreak@30 3105 button.check:SetHeight(16)
flickerstreak@30 3106 elseif info.icon then
flickerstreak@30 3107 button.check:Show()
flickerstreak@30 3108 button.check:SetTexture(info.icon)
flickerstreak@30 3109 if info.iconWidth and info.iconHeight then
flickerstreak@30 3110 button.check:SetWidth(info.iconWidth)
flickerstreak@30 3111 button.check:SetHeight(info.iconHeight)
flickerstreak@30 3112 else
flickerstreak@30 3113 button.check:SetWidth(16)
flickerstreak@30 3114 button.check:SetHeight(16)
flickerstreak@30 3115 end
flickerstreak@30 3116 if info.iconCoordLeft and info.iconCoordRight and info.iconCoordTop and info.iconCoordBottom then
flickerstreak@30 3117 button.check:SetTexCoord(info.iconCoordLeft, info.iconCoordRight, info.iconCoordTop, info.iconCoordBottom)
flickerstreak@30 3118 elseif info.icon:find("^Interface\\Icons\\") then
flickerstreak@30 3119 button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
flickerstreak@30 3120 else
flickerstreak@30 3121 button.check:SetTexCoord(0, 1, 0, 1)
flickerstreak@30 3122 end
flickerstreak@30 3123 button.check:SetVertexColor(1, 1, 1, 1)
flickerstreak@30 3124 else
flickerstreak@30 3125 if button.checked then
flickerstreak@30 3126 if info.checkIcon then
flickerstreak@30 3127 button.check:SetWidth(16)
flickerstreak@30 3128 button.check:SetHeight(16)
flickerstreak@30 3129 button.check:SetTexture(info.checkIcon)
flickerstreak@30 3130 if info.checkIcon:find("^Interface\\Icons\\") then
flickerstreak@30 3131 button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
flickerstreak@30 3132 else
flickerstreak@30 3133 button.check:SetTexCoord(0, 1, 0, 1)
flickerstreak@30 3134 end
flickerstreak@30 3135 else
flickerstreak@30 3136 button.check:SetWidth(24)
flickerstreak@30 3137 button.check:SetHeight(24)
flickerstreak@30 3138 button.check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
flickerstreak@30 3139 button.check:SetTexCoord(0, 1, 0, 1)
flickerstreak@30 3140 end
flickerstreak@30 3141 button.check:SetVertexColor(1, 1, 1, 1)
flickerstreak@30 3142 else
flickerstreak@30 3143 button.check:SetVertexColor(1, 1, 1, 0)
flickerstreak@30 3144 end
flickerstreak@30 3145 end
flickerstreak@30 3146 if not button.disabled then
flickerstreak@30 3147 button.func = info.func
flickerstreak@30 3148 button.secure = info.secure
flickerstreak@30 3149 end
flickerstreak@30 3150 button.hasColorSwatch = info.hasColorSwatch
flickerstreak@30 3151 if button.hasColorSwatch then
flickerstreak@30 3152 button.colorSwatch:Show()
flickerstreak@30 3153 button.colorSwatch.texture:Show()
flickerstreak@30 3154 button.r = info.r or 1
flickerstreak@30 3155 button.g = info.g or 1
flickerstreak@30 3156 button.b = info.b or 1
flickerstreak@30 3157 button.colorSwatch.texture:SetVertexColor(button.r, button.g, button.b)
flickerstreak@30 3158 button.checked = false
flickerstreak@30 3159 button.func = nil
flickerstreak@30 3160 button.colorFunc = info.colorFunc
flickerstreak@30 3161 local i = 1
flickerstreak@30 3162 while true do
flickerstreak@30 3163 local k = "colorArg" .. i
flickerstreak@30 3164 local x = info[k]
flickerstreak@30 3165 if x == nil then
flickerstreak@30 3166 break
flickerstreak@30 3167 end
flickerstreak@30 3168 button[k] = x
flickerstreak@30 3169 i = i + 1
flickerstreak@30 3170 end
flickerstreak@30 3171 button.hasOpacity = info.hasOpacity
flickerstreak@30 3172 button.opacity = info.opacity or 1
flickerstreak@30 3173 else
flickerstreak@30 3174 button.colorSwatch:Hide()
flickerstreak@30 3175 button.colorSwatch.texture:Hide()
flickerstreak@30 3176 end
flickerstreak@30 3177 button.hasArrow = not button.hasColorSwatch and (info.value or info.hasSlider or info.hasEditBox) and info.hasArrow
flickerstreak@30 3178 if button.hasArrow then
flickerstreak@30 3179 button.arrow:SetAlpha(1)
flickerstreak@30 3180 if info.hasSlider then
flickerstreak@30 3181 button.hasSlider = true
flickerstreak@30 3182 button.sliderMin = info.sliderMin or 0
flickerstreak@30 3183 button.sliderMax = info.sliderMax or 1
flickerstreak@30 3184 button.sliderStep = info.sliderStep or 0
flickerstreak@30 3185 button.sliderBigStep = info.sliderBigStep or button.sliderStep
flickerstreak@30 3186 if button.sliderBigStep < button.sliderStep then
flickerstreak@30 3187 button.sliderBigStep = button.sliderStep
flickerstreak@30 3188 end
flickerstreak@30 3189 button.sliderIsPercent = info.sliderIsPercent and true or false
flickerstreak@30 3190 button.sliderMinText = info.sliderMinText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMin * 100) or button.sliderMin
flickerstreak@30 3191 button.sliderMaxText = info.sliderMaxText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMax * 100) or button.sliderMax
flickerstreak@30 3192 button.sliderFunc = info.sliderFunc
flickerstreak@30 3193 button.sliderValue = info.sliderValue
flickerstreak@30 3194 button.fromAceOptions = info.fromAceOptions
flickerstreak@30 3195 local i = 1
flickerstreak@30 3196 while true do
flickerstreak@30 3197 local k = "sliderArg" .. i
flickerstreak@30 3198 local x = info[k]
flickerstreak@30 3199 if x == nil then
flickerstreak@30 3200 break
flickerstreak@30 3201 end
flickerstreak@30 3202 button[k] = x
flickerstreak@30 3203 i = i + 1
flickerstreak@30 3204 end
flickerstreak@30 3205 elseif info.hasEditBox then
flickerstreak@30 3206 button.hasEditBox = true
flickerstreak@30 3207 button.editBoxText = info.editBoxText or ""
flickerstreak@30 3208 button.editBoxFunc = info.editBoxFunc
flickerstreak@30 3209 local i = 1
flickerstreak@30 3210 while true do
flickerstreak@30 3211 local k = "editBoxArg" .. i
flickerstreak@30 3212 local x = info[k]
flickerstreak@30 3213 if x == nil then
flickerstreak@30 3214 break
flickerstreak@30 3215 end
flickerstreak@30 3216 button[k] = x
flickerstreak@30 3217 i = i + 1
flickerstreak@30 3218 end
flickerstreak@30 3219 button.editBoxChangeFunc = info.editBoxChangeFunc
flickerstreak@30 3220 local i = 1
flickerstreak@30 3221 while true do
flickerstreak@30 3222 local k = "editBoxChangeArg" .. i
flickerstreak@30 3223 local x = info[k]
flickerstreak@30 3224 if x == nil then
flickerstreak@30 3225 break
flickerstreak@30 3226 end
flickerstreak@30 3227 button[k] = x
flickerstreak@30 3228 i = i + 1
flickerstreak@30 3229 end
flickerstreak@30 3230 button.editBoxValidateFunc = info.editBoxValidateFunc
flickerstreak@30 3231 local i = 1
flickerstreak@30 3232 while true do
flickerstreak@30 3233 local k = "editBoxValidateArg" .. i
flickerstreak@30 3234 local x = info[k]
flickerstreak@30 3235 if x == nil then
flickerstreak@30 3236 break
flickerstreak@30 3237 end
flickerstreak@30 3238 button[k] = x
flickerstreak@30 3239 i = i + 1
flickerstreak@30 3240 end
flickerstreak@30 3241 button.editBoxIsKeybinding = info.editBoxIsKeybinding
flickerstreak@30 3242 button.editBoxKeybindingOnly = info.editBoxKeybindingOnly
flickerstreak@30 3243 button.editBoxKeybindingExcept = info.editBoxKeybindingExcept
flickerstreak@30 3244 else
flickerstreak@30 3245 button.value = info.value
flickerstreak@30 3246 local l = levels[level+1]
flickerstreak@30 3247 if l and info.value == l.value then
flickerstreak@30 3248 -- button.arrow:SetWidth(24)
flickerstreak@30 3249 -- button.arrow:SetHeight(24)
flickerstreak@30 3250 button.selected = true
flickerstreak@30 3251 button.highlight:Show()
flickerstreak@30 3252 end
flickerstreak@30 3253 end
flickerstreak@30 3254 else
flickerstreak@30 3255 button.arrow:SetAlpha(0)
flickerstreak@30 3256 end
flickerstreak@30 3257 local i = 1
flickerstreak@30 3258 while true do
flickerstreak@30 3259 local k = "arg" .. i
flickerstreak@30 3260 local x = info[k]
flickerstreak@30 3261 if x == nil then
flickerstreak@30 3262 break
flickerstreak@30 3263 end
flickerstreak@30 3264 button[k] = x
flickerstreak@30 3265 i = i + 1
flickerstreak@30 3266 end
flickerstreak@30 3267 button.closeWhenClicked = info.closeWhenClicked
flickerstreak@30 3268 button.textHeight = info.textHeight or UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT or 10
flickerstreak@30 3269 local font,_ = button.text:GetFont()
flickerstreak@30 3270 button.text:SetFont(STANDARD_TEXT_FONT or "Fonts\\FRIZQT__.TTF", button.textHeight)
flickerstreak@30 3271 button:SetHeight(button.textHeight + 6)
flickerstreak@30 3272 button.text:SetPoint("RIGHT", button.arrow, (button.hasColorSwatch or button.hasArrow) and "LEFT" or "RIGHT")
flickerstreak@30 3273 button.text:SetJustifyH(info.justifyH or "LEFT")
flickerstreak@30 3274 button.text:SetText(info.text)
flickerstreak@30 3275 button.tooltipTitle = info.tooltipTitle
flickerstreak@30 3276 button.tooltipText = info.tooltipText
flickerstreak@30 3277 button.tooltipFunc = info.tooltipFunc
flickerstreak@30 3278 local i = 1
flickerstreak@30 3279 while true do
flickerstreak@30 3280 local k = "tooltipArg" .. i
flickerstreak@30 3281 local x = info[k]
flickerstreak@30 3282 if x == nil then
flickerstreak@30 3283 break
flickerstreak@30 3284 end
flickerstreak@30 3285 button[k] = x
flickerstreak@30 3286 i = i + 1
flickerstreak@30 3287 end
flickerstreak@30 3288 if not button.tooltipTitle and not button.tooltipText and not button.tooltipFunc and not info.isTitle then
flickerstreak@30 3289 button.tooltipTitle = info.text
flickerstreak@30 3290 end
flickerstreak@30 3291 if type(button.func) == "string" then
flickerstreak@30 3292 if type(button.arg1) ~= "table" then
flickerstreak@30 3293 self:error("Cannot call method %q on a non-table", button.func)
flickerstreak@30 3294 end
flickerstreak@30 3295 if type(button.arg1[button.func]) ~= "function" then
flickerstreak@30 3296 self:error("Method %q nonexistant.", button.func)
flickerstreak@30 3297 end
flickerstreak@30 3298 end
flickerstreak@30 3299 end
flickerstreak@30 3300
flickerstreak@30 3301 function Dewdrop:InjectAceOptionsTable(handler, options)
flickerstreak@30 3302 self:argCheck(handler, 2, "table")
flickerstreak@30 3303 self:argCheck(options, 3, "table")
flickerstreak@30 3304 if tostring(options.type):lower() ~= "group" then
flickerstreak@30 3305 self:error('Cannot inject into options table argument #3 if its type is not "group"')
flickerstreak@30 3306 end
flickerstreak@30 3307 if options.handler ~= nil and options.handler ~= handler then
flickerstreak@30 3308 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2")
flickerstreak@30 3309 end
flickerstreak@30 3310 options.handler = handler
flickerstreak@30 3311 local class = handler.class
flickerstreak@30 3312 if not AceLibrary:HasInstance("AceOO-2.0") or not class then
flickerstreak@30 3313 if Rock then
flickerstreak@30 3314 -- possible Rock object
flickerstreak@30 3315 for mixin in Rock:IterateObjectMixins(handler) do
flickerstreak@30 3316 if type(mixin.GetAceOptionsDataTable) == "function" then
flickerstreak@30 3317 local t = mixin:GetAceOptionsDataTable(handler)
flickerstreak@30 3318 for k,v in pairs(t) do
flickerstreak@30 3319 if type(options.args) ~= "table" then
flickerstreak@30 3320 options.args = {}
flickerstreak@30 3321 end
flickerstreak@30 3322 if options.args[k] == nil then
flickerstreak@30 3323 options.args[k] = v
flickerstreak@30 3324 end
flickerstreak@30 3325 end
flickerstreak@30 3326 end
flickerstreak@30 3327 end
flickerstreak@30 3328 end
flickerstreak@30 3329 else
flickerstreak@30 3330 -- Ace2 object
flickerstreak@30 3331 while class and class ~= AceLibrary("AceOO-2.0").Class do
flickerstreak@30 3332 if type(class.GetAceOptionsDataTable) == "function" then
flickerstreak@30 3333 local t = class:GetAceOptionsDataTable(handler)
flickerstreak@30 3334 for k,v in pairs(t) do
flickerstreak@30 3335 if type(options.args) ~= "table" then
flickerstreak@30 3336 options.args = {}
flickerstreak@30 3337 end
flickerstreak@30 3338 if options.args[k] == nil then
flickerstreak@30 3339 options.args[k] = v
flickerstreak@30 3340 end
flickerstreak@30 3341 end
flickerstreak@30 3342 end
flickerstreak@30 3343 local mixins = class.mixins
flickerstreak@30 3344 if mixins then
flickerstreak@30 3345 for mixin in pairs(mixins) do
flickerstreak@30 3346 if type(mixin.GetAceOptionsDataTable) == "function" then
flickerstreak@30 3347 local t = mixin:GetAceOptionsDataTable(handler)
flickerstreak@30 3348 for k,v in pairs(t) do
flickerstreak@30 3349 if type(options.args) ~= "table" then
flickerstreak@30 3350 options.args = {}
flickerstreak@30 3351 end
flickerstreak@30 3352 if options.args[k] == nil then
flickerstreak@30 3353 options.args[k] = v
flickerstreak@30 3354 end
flickerstreak@30 3355 end
flickerstreak@30 3356 end
flickerstreak@30 3357 end
flickerstreak@30 3358 end
flickerstreak@30 3359 class = class.super
flickerstreak@30 3360 end
flickerstreak@30 3361 end
flickerstreak@30 3362 return options
flickerstreak@30 3363 end
flickerstreak@30 3364
flickerstreak@30 3365 function Dewdrop:OnTooltipHide()
flickerstreak@30 3366 if lastSetFont then
flickerstreak@30 3367 if lastSetFont == normalFont then
flickerstreak@30 3368 lastSetFont = nil
flickerstreak@30 3369 return
flickerstreak@30 3370 end
flickerstreak@30 3371 fillRegionTmp(GameTooltip:GetRegions())
flickerstreak@30 3372 for i,v in ipairs(regionTmp) do
flickerstreak@30 3373 if v.GetFont then
flickerstreak@30 3374 local font,size,outline = v:GetFont()
flickerstreak@30 3375 if font == lastSetFont then
flickerstreak@30 3376 v:SetFont(normalFont, size, outline)
flickerstreak@30 3377 end
flickerstreak@30 3378 end
flickerstreak@30 3379 regionTmp[i] = nil
flickerstreak@30 3380 end
flickerstreak@30 3381 lastSetFont = nil
flickerstreak@30 3382 end
flickerstreak@30 3383 end
flickerstreak@30 3384
flickerstreak@30 3385 local function activate(self, oldLib, oldDeactivate)
flickerstreak@30 3386 Dewdrop = self
flickerstreak@30 3387 if oldLib and oldLib.registry then
flickerstreak@30 3388 self.registry = oldLib.registry
flickerstreak@30 3389 self.onceRegistered = oldLib.onceRegistered
flickerstreak@30 3390 else
flickerstreak@30 3391 self.registry = {}
flickerstreak@30 3392 self.onceRegistered = {}
flickerstreak@30 3393
flickerstreak@30 3394 local WorldFrame_OnMouseDown = WorldFrame:GetScript("OnMouseDown")
flickerstreak@30 3395 local WorldFrame_OnMouseUp = WorldFrame:GetScript("OnMouseUp")
flickerstreak@30 3396 local oldX, oldY, clickTime
flickerstreak@30 3397 WorldFrame:SetScript("OnMouseDown", function(this, ...)
flickerstreak@30 3398 oldX,oldY = GetCursorPosition()
flickerstreak@30 3399 clickTime = GetTime()
flickerstreak@30 3400 if WorldFrame_OnMouseDown then
flickerstreak@30 3401 WorldFrame_OnMouseDown(this, ...)
flickerstreak@30 3402 end
flickerstreak@30 3403 end)
flickerstreak@30 3404
flickerstreak@30 3405 WorldFrame:SetScript("OnMouseUp", function(this, ...)
flickerstreak@30 3406 local x,y = GetCursorPosition()
flickerstreak@30 3407 if not oldX or not oldY or not x or not y or not clickTime then
flickerstreak@30 3408 self:Close()
flickerstreak@30 3409 if WorldFrame_OnMouseUp then
flickerstreak@30 3410 WorldFrame_OnMouseUp(this, ...)
flickerstreak@30 3411 end
flickerstreak@30 3412 return
flickerstreak@30 3413 end
flickerstreak@30 3414 local d = math.abs(x - oldX) + math.abs(y - oldY)
flickerstreak@30 3415 if d <= 5 and GetTime() - clickTime < 0.5 then
flickerstreak@30 3416 self:Close()
flickerstreak@30 3417 end
flickerstreak@30 3418 if WorldFrame_OnMouseUp then
flickerstreak@30 3419 WorldFrame_OnMouseUp(this, ...)
flickerstreak@30 3420 end
flickerstreak@30 3421 end)
flickerstreak@30 3422
flickerstreak@30 3423 hooksecurefunc(DropDownList1, "Show", function()
flickerstreak@30 3424 if levels[1] and levels[1]:IsVisible() then
flickerstreak@30 3425 self:Close()
flickerstreak@30 3426 end
flickerstreak@30 3427 end)
flickerstreak@30 3428
flickerstreak@30 3429 hooksecurefunc("HideDropDownMenu", function()
flickerstreak@30 3430 if levels[1] and levels[1]:IsVisible() then
flickerstreak@30 3431 self:Close()
flickerstreak@30 3432 end
flickerstreak@30 3433 end)
flickerstreak@30 3434
flickerstreak@30 3435 hooksecurefunc("CloseDropDownMenus", function()
flickerstreak@30 3436 if levels[1] and levels[1]:IsVisible() then
flickerstreak@30 3437 local stack = debugstack()
flickerstreak@30 3438 if not stack:find("`TargetFrame_OnHide'") then
flickerstreak@30 3439 self:Close()
flickerstreak@30 3440 end
flickerstreak@30 3441 end
flickerstreak@30 3442 end)
flickerstreak@30 3443 end
flickerstreak@30 3444 self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
flickerstreak@30 3445 self.frame:UnregisterAllEvents()
flickerstreak@30 3446 self.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
flickerstreak@30 3447 self.frame:RegisterEvent("PLAYER_REGEN_DISABLED")
flickerstreak@30 3448 self.frame:Hide()
flickerstreak@30 3449 self.frame:SetScript("OnEvent", function(this, event)
flickerstreak@30 3450 this:Show()
flickerstreak@30 3451 if event=="PLAYER_REGEN_ENABLED" then -- track combat state for secure frame operations
flickerstreak@30 3452 self.combat = false
flickerstreak@30 3453 elseif event=="PLAYER_REGEN_DISABLED" then
flickerstreak@30 3454 self.combat = true
flickerstreak@30 3455 end
flickerstreak@30 3456 end)
flickerstreak@30 3457 self.frame:SetScript("OnUpdate", function(this)
flickerstreak@30 3458 this:Hide()
flickerstreak@30 3459 self:Refresh(1)
flickerstreak@30 3460 end)
flickerstreak@30 3461 self.hookedTooltip = true
flickerstreak@30 3462 if not oldLib or not oldLib.hookedTooltip then
flickerstreak@30 3463 local OnTooltipHide = GameTooltip:GetScript("OnHide")
flickerstreak@30 3464 GameTooltip:SetScript("OnHide", function(this, ...)
flickerstreak@30 3465 if OnTooltipHide then
flickerstreak@30 3466 OnTooltipHide(this, ...)
flickerstreak@30 3467 end
flickerstreak@30 3468 if type(self.OnTooltipHide) == "function" then
flickerstreak@30 3469 self:OnTooltipHide()
flickerstreak@30 3470 end
flickerstreak@30 3471 end)
flickerstreak@30 3472 end
flickerstreak@30 3473 levels = {}
flickerstreak@30 3474 buttons = {}
flickerstreak@30 3475
flickerstreak@30 3476 if oldDeactivate then
flickerstreak@30 3477 oldDeactivate(oldLib)
flickerstreak@30 3478 end
flickerstreak@30 3479 end
flickerstreak@30 3480
flickerstreak@30 3481 local function external(lib, major, instance)
flickerstreak@30 3482 if major == "SharedMedia-1.0" then
flickerstreak@30 3483 SharedMedia = instance
flickerstreak@30 3484 end
flickerstreak@30 3485 end
flickerstreak@30 3486
flickerstreak@30 3487 AceLibrary:Register(Dewdrop, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)