Mercurial > wow > reaction
comparison libs/Dewdrop-2.0/Dewdrop-2.0.lua @ 1:c11ca1d8ed91
Version 0.1
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Tue, 20 Mar 2007 21:03:57 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:4e2ce2894c21 | 1:c11ca1d8ed91 |
|---|---|
| 1 --[[ | |
| 2 Name: Dewdrop-2.0 | |
| 3 Revision: $Rev: 19976 $ | |
| 4 Author(s): ckknight (ckknight@gmail.com) | |
| 5 Website: http://ckknight.wowinterface.com/ | |
| 6 Documentation: http://wiki.wowace.com/index.php/Dewdrop-2.0 | |
| 7 SVN: http://svn.wowace.com/root/trunk/DewdropLib/Dewdrop-2.0 | |
| 8 Description: A library to provide a clean dropdown menu interface. | |
| 9 Dependencies: AceLibrary | |
| 10 ]] | |
| 11 | |
| 12 local MAJOR_VERSION = "Dewdrop-2.0" | |
| 13 local MINOR_VERSION = "$Revision: 19976 $" | |
| 14 | |
| 15 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end | |
| 16 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end | |
| 17 | |
| 18 local Dewdrop = {} | |
| 19 | |
| 20 local CLOSE = "Close" | |
| 21 local CLOSE_DESC = "Close the menu." | |
| 22 local VALIDATION_ERROR = "Validation error." | |
| 23 local RESET_KEYBINDING_DESC = "Hit escape to clear the keybinding." | |
| 24 | |
| 25 if GetLocale() == "deDE" then | |
| 26 -- VALIDATION_ERROR = "some message here..." | |
| 27 end | |
| 28 | |
| 29 local function new(...) | |
| 30 local t = {} | |
| 31 for i = 1, select('#', ...), 2 do | |
| 32 local k = select(i, ...) | |
| 33 if k then | |
| 34 t[k] = select(i+1, ...) | |
| 35 else | |
| 36 break | |
| 37 end | |
| 38 end | |
| 39 return t | |
| 40 end | |
| 41 | |
| 42 local tmp | |
| 43 do | |
| 44 local t = {} | |
| 45 function tmp(...) | |
| 46 for k in pairs(t) do | |
| 47 t[k] = nil | |
| 48 end | |
| 49 for i = 1, select('#', ...), 2 do | |
| 50 local k = select(i, ...) | |
| 51 if k then | |
| 52 t[k] = select(i+1, ...) | |
| 53 else | |
| 54 break | |
| 55 end | |
| 56 end | |
| 57 return t | |
| 58 end | |
| 59 end | |
| 60 local tmp2 | |
| 61 do | |
| 62 local t = {} | |
| 63 function tmp2(...) | |
| 64 for k in pairs(t) do | |
| 65 t[k] = nil | |
| 66 end | |
| 67 for i = 1, select('#', ...), 2 do | |
| 68 local k = select(i, ...) | |
| 69 if k then | |
| 70 t[k] = select(i+1, ...) | |
| 71 else | |
| 72 break | |
| 73 end | |
| 74 end | |
| 75 return t | |
| 76 end | |
| 77 end | |
| 78 local levels | |
| 79 local buttons | |
| 80 | |
| 81 local function GetScaledCursorPosition() | |
| 82 local x, y = GetCursorPosition() | |
| 83 local scale = UIParent:GetEffectiveScale() | |
| 84 return x / scale, y / scale | |
| 85 end | |
| 86 | |
| 87 local function StartCounting(self, levelNum) | |
| 88 for i = levelNum, #levels do | |
| 89 if levels[i] then | |
| 90 levels[i].count = 3 | |
| 91 end | |
| 92 end | |
| 93 end | |
| 94 | |
| 95 local function StopCounting(self, level) | |
| 96 for i = level, 1, -1 do | |
| 97 if levels[i] then | |
| 98 levels[i].count = nil | |
| 99 end | |
| 100 end | |
| 101 end | |
| 102 | |
| 103 local function OnUpdate(self, arg1) | |
| 104 for _,level in ipairs(levels) do | |
| 105 if level.count then | |
| 106 level.count = level.count - arg1 | |
| 107 if level.count < 0 then | |
| 108 level.count = nil | |
| 109 self:Close(level.num) | |
| 110 end | |
| 111 end | |
| 112 end | |
| 113 end | |
| 114 | |
| 115 local function CheckDualMonitor(self, frame) | |
| 116 local ratio = GetScreenWidth() / GetScreenHeight() | |
| 117 if ratio >= 2.4 and frame:GetRight() > GetScreenWidth() / 2 and frame:GetLeft() < GetScreenWidth() / 2 then | |
| 118 local offsetx | |
| 119 if GetCursorPosition() / GetScreenHeight() * 768 < GetScreenWidth() / 2 then | |
| 120 offsetx = GetScreenWidth() / 2 - frame:GetRight() | |
| 121 else | |
| 122 offsetx = GetScreenWidth() / 2 - frame:GetLeft() | |
| 123 end | |
| 124 local point, parent, relativePoint, x, y = frame:GetPoint(1) | |
| 125 frame:SetPoint(point, parent, relativePoint, (x or 0) + offsetx, y or 0) | |
| 126 end | |
| 127 end | |
| 128 | |
| 129 local function CheckSize(self, level) | |
| 130 if not level.buttons then | |
| 131 return | |
| 132 end | |
| 133 local height = 20 | |
| 134 for _, button in ipairs(level.buttons) do | |
| 135 height = height + button:GetHeight() | |
| 136 end | |
| 137 level:SetHeight(height) | |
| 138 local width = 160 | |
| 139 for _, button in ipairs(level.buttons) do | |
| 140 local extra = 1 | |
| 141 if button.hasArrow or button.hasColorSwatch then | |
| 142 extra = extra + 16 | |
| 143 end | |
| 144 if not button.notCheckable then | |
| 145 extra = extra + 24 | |
| 146 end | |
| 147 button.text:SetFont(STANDARD_TEXT_FONT, button.textHeight) | |
| 148 if button.text:GetWidth() + extra > width then | |
| 149 width = button.text:GetWidth() + extra | |
| 150 end | |
| 151 end | |
| 152 level:SetWidth(width + 20) | |
| 153 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 | |
| 154 level:ClearAllPoints() | |
| 155 if level.lastDirection == "RIGHT" then | |
| 156 if level.lastVDirection == "DOWN" then | |
| 157 level:SetPoint("TOPLEFT", level.parent or level:GetParent(), "TOPRIGHT", 5, 10) | |
| 158 else | |
| 159 level:SetPoint("BOTTOMLEFT", level.parent or level:GetParent(), "BOTTOMRIGHT", 5, -10) | |
| 160 end | |
| 161 else | |
| 162 if level.lastVDirection == "DOWN" then | |
| 163 level:SetPoint("TOPRIGHT", level.parent or level:GetParent(), "TOPLEFT", -5, 10) | |
| 164 else | |
| 165 level:SetPoint("BOTTOMRIGHT", level.parent or level:GetParent(), "BOTTOMLEFT", -5, -10) | |
| 166 end | |
| 167 end | |
| 168 end | |
| 169 local dirty = false | |
| 170 if not level:GetRight() then | |
| 171 self:Close() | |
| 172 return | |
| 173 end | |
| 174 if level:GetRight() > GetScreenWidth() and level.lastDirection == "RIGHT" then | |
| 175 level.lastDirection = "LEFT" | |
| 176 dirty = true | |
| 177 elseif level:GetLeft() < 0 and level.lastDirection == "LEFT" then | |
| 178 level.lastDirection = "RIGHT" | |
| 179 dirty = true | |
| 180 end | |
| 181 if level:GetTop() > GetScreenHeight() and level.lastVDirection == "UP" then | |
| 182 level.lastVDirection = "DOWN" | |
| 183 dirty = true | |
| 184 elseif level:GetBottom() < 0 and level.lastVDirection == "DOWN" then | |
| 185 level.lastVDirection = "UP" | |
| 186 dirty = true | |
| 187 end | |
| 188 if dirty then | |
| 189 level:ClearAllPoints() | |
| 190 if level.lastDirection == "RIGHT" then | |
| 191 if level.lastVDirection == "DOWN" then | |
| 192 level:SetPoint("TOPLEFT", level.parent or level:GetParent(), "TOPRIGHT", 5, 10) | |
| 193 else | |
| 194 level:SetPoint("BOTTOMLEFT", level.parent or level:GetParent(), "BOTTOMRIGHT", 5, -10) | |
| 195 end | |
| 196 else | |
| 197 if level.lastVDirection == "DOWN" then | |
| 198 level:SetPoint("TOPRIGHT", level.parent or level:GetParent(), "TOPLEFT", -5, 10) | |
| 199 else | |
| 200 level:SetPoint("BOTTOMRIGHT", level.parent or level:GetParent(), "BOTTOMLEFT", -5, -10) | |
| 201 end | |
| 202 end | |
| 203 end | |
| 204 if level:GetTop() > GetScreenHeight() then | |
| 205 local top = level:GetTop() | |
| 206 local point, parent, relativePoint, x, y = level:GetPoint(1) | |
| 207 level:ClearAllPoints() | |
| 208 level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) + GetScreenHeight() - top) | |
| 209 elseif level:GetBottom() < 0 then | |
| 210 local bottom = level:GetBottom() | |
| 211 local point, parent, relativePoint, x, y = level:GetPoint(1) | |
| 212 level:ClearAllPoints() | |
| 213 level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) - bottom) | |
| 214 end | |
| 215 CheckDualMonitor(self, level) | |
| 216 if mod(level.num, 5) == 0 then | |
| 217 local left, bottom = level:GetLeft(), level:GetBottom() | |
| 218 level:ClearAllPoints() | |
| 219 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom) | |
| 220 end | |
| 221 end | |
| 222 | |
| 223 local Open | |
| 224 local OpenSlider | |
| 225 local OpenEditBox | |
| 226 local Refresh | |
| 227 local Clear | |
| 228 local function ReleaseButton(self, level, index) | |
| 229 if not level.buttons then | |
| 230 return | |
| 231 end | |
| 232 if not level.buttons[index] then | |
| 233 return | |
| 234 end | |
| 235 local button = level.buttons[index] | |
| 236 button:Hide() | |
| 237 if button.highlight then | |
| 238 button.highlight:Hide() | |
| 239 end | |
| 240 -- button.arrow:SetVertexColor(1, 1, 1) | |
| 241 -- button.arrow:SetHeight(16) | |
| 242 -- button.arrow:SetWidth(16) | |
| 243 table.remove(level.buttons, index) | |
| 244 table.insert(buttons, button) | |
| 245 for k in pairs(button) do | |
| 246 if k ~= 0 and k ~= "text" and k ~= "check" and k ~= "arrow" and k ~= "colorSwatch" and k ~= "highlight" and k ~= "radioHighlight" then | |
| 247 button[k] = nil | |
| 248 end | |
| 249 end | |
| 250 return true | |
| 251 end | |
| 252 | |
| 253 local function Scroll(self, level, down) | |
| 254 if down then | |
| 255 if level:GetBottom() < 0 then | |
| 256 local point, parent, relativePoint, x, y = level:GetPoint(1) | |
| 257 level:SetPoint(point, parent, relativePoint, x, y + 50) | |
| 258 if level:GetBottom() > 0 then | |
| 259 level:SetPoint(point, parent, relativePoint, x, y + 50 - level:GetBottom()) | |
| 260 end | |
| 261 end | |
| 262 else | |
| 263 if level:GetTop() > GetScreenHeight() then | |
| 264 local point, parent, relativePoint, x, y = level:GetPoint(1) | |
| 265 level:SetPoint(point, parent, relativePoint, x, y - 50) | |
| 266 if level:GetTop() < GetScreenHeight() then | |
| 267 level:SetPoint(point, parent, relativePoint, x, y - 50 + GetScreenHeight() - level:GetTop()) | |
| 268 end | |
| 269 end | |
| 270 end | |
| 271 end | |
| 272 | |
| 273 local sliderFrame | |
| 274 local editBoxFrame | |
| 275 | |
| 276 local function showGameTooltip(this) | |
| 277 if this.tooltipTitle or this.tooltipText then | |
| 278 GameTooltip_SetDefaultAnchor(GameTooltip, this) | |
| 279 local disabled = not this.isTitle and this.disabled | |
| 280 if this.tooltipTitle then | |
| 281 if disabled then | |
| 282 GameTooltip:SetText(this.tooltipTitle, 0.5, 0.5, 0.5, 1) | |
| 283 else | |
| 284 GameTooltip:SetText(this.tooltipTitle, 1, 1, 1, 1) | |
| 285 end | |
| 286 if this.tooltipText then | |
| 287 if disabled then | |
| 288 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) | |
| 289 else | |
| 290 GameTooltip:AddLine(this.tooltipText, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1) | |
| 291 end | |
| 292 end | |
| 293 else | |
| 294 if disabled then | |
| 295 GameTooltip:SetText(this.tooltipText, 0.5, 0.5, 0.5, 1) | |
| 296 else | |
| 297 GameTooltip:SetText(this.tooltipText, 1, 1, 1, 1) | |
| 298 end | |
| 299 end | |
| 300 GameTooltip:Show() | |
| 301 end | |
| 302 if this.tooltipFunc then | |
| 303 GameTooltip:SetOwner(this, "ANCHOR_NONE") | |
| 304 GameTooltip:SetPoint("TOPLEFT", this, "TOPRIGHT", 5, 0) | |
| 305 this.tooltipFunc(this.tooltipArg1, this.tooltipArg2, this.tooltipArg3, this.tooltipArg4) | |
| 306 GameTooltip:Show() | |
| 307 end | |
| 308 end | |
| 309 | |
| 310 local numButtons = 0 | |
| 311 local function AcquireButton(self, level) | |
| 312 if not levels[level] then | |
| 313 return | |
| 314 end | |
| 315 level = levels[level] | |
| 316 if not level.buttons then | |
| 317 level.buttons = {} | |
| 318 end | |
| 319 local button | |
| 320 if #buttons == 0 then | |
| 321 numButtons = numButtons + 1 | |
| 322 button = CreateFrame("Button", "Dewdrop20Button" .. numButtons, nil) | |
| 323 button:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 324 button:SetHeight(16) | |
| 325 local highlight = button:CreateTexture(nil, "BACKGROUND") | |
| 326 highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") | |
| 327 button.highlight = highlight | |
| 328 highlight:SetBlendMode("ADD") | |
| 329 highlight:SetAllPoints(button) | |
| 330 highlight:Hide() | |
| 331 local check = button:CreateTexture(nil, "ARTWORK") | |
| 332 button.check = check | |
| 333 check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") | |
| 334 check:SetPoint("CENTER", button, "LEFT", 12, 0) | |
| 335 check:SetWidth(24) | |
| 336 check:SetHeight(24) | |
| 337 local radioHighlight = button:CreateTexture(nil, "ARTWORK") | |
| 338 button.radioHighlight = radioHighlight | |
| 339 radioHighlight:SetTexture("Interface\\Buttons\\UI-RadioButton") | |
| 340 radioHighlight:SetAllPoints(check) | |
| 341 radioHighlight:SetBlendMode("ADD") | |
| 342 radioHighlight:SetTexCoord(0.5, 0.75, 0, 1) | |
| 343 radioHighlight:Hide() | |
| 344 button:SetScript("OnEnter", function() | |
| 345 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 | |
| 346 for i = 1, this.level.num do | |
| 347 Refresh(self, levels[i]) | |
| 348 end | |
| 349 return | |
| 350 end | |
| 351 self:Close(this.level.num + 1) | |
| 352 if not this.disabled then | |
| 353 if this.hasSlider then | |
| 354 OpenSlider(self, this) | |
| 355 elseif this.hasEditBox then | |
| 356 OpenEditBox(self, this) | |
| 357 elseif this.hasArrow then | |
| 358 Open(self, this, nil, this.level.num + 1, this.value) | |
| 359 end | |
| 360 end | |
| 361 if not this.level then -- button reclaimed | |
| 362 return | |
| 363 end | |
| 364 StopCounting(self, this.level.num + 1) | |
| 365 if not this.disabled then | |
| 366 highlight:Show() | |
| 367 if this.isRadio then | |
| 368 button.radioHighlight:Show() | |
| 369 end | |
| 370 end | |
| 371 showGameTooltip(this) | |
| 372 end) | |
| 373 button:SetScript("OnLeave", function() | |
| 374 if not this.selected then | |
| 375 highlight:Hide() | |
| 376 end | |
| 377 button.radioHighlight:Hide() | |
| 378 if this.level then | |
| 379 StartCounting(self, this.level.num) | |
| 380 end | |
| 381 GameTooltip:Hide() | |
| 382 end) | |
| 383 button:SetScript("OnClick", function() | |
| 384 if not this.disabled then | |
| 385 if this.hasColorSwatch then | |
| 386 local func = button.colorFunc | |
| 387 local a1,a2,a3,a4 = button.colorArg1, button.colorArg2, button.colorArg3, button.colorArg4 | |
| 388 local hasOpacity = this.hasOpacity | |
| 389 ColorPickerFrame.func = function() | |
| 390 if func then | |
| 391 local r,g,b = ColorPickerFrame:GetColorRGB() | |
| 392 local a = hasOpacity and 1 - OpacitySliderFrame:GetValue() or nil | |
| 393 if a1 == nil then | |
| 394 func(r, g, b, a) | |
| 395 elseif a2 == nil then | |
| 396 func(a1, r, g, b, a) | |
| 397 elseif a3 == nil then | |
| 398 func(a1, a2, r, g, b, a) | |
| 399 elseif a4 == nil then | |
| 400 func(a1, a2, a3, r, g, b, a) | |
| 401 else | |
| 402 func(a1, a2, a3, a4, r, g, b, a) | |
| 403 end | |
| 404 end | |
| 405 end | |
| 406 ColorPickerFrame.hasOpacity = this.hasOpacity | |
| 407 ColorPickerFrame.opacityFunc = ColorPickerFrame.func | |
| 408 ColorPickerFrame.opacity = 1 - this.opacity | |
| 409 ColorPickerFrame:SetColorRGB(this.r, this.g, this.b) | |
| 410 local r, g, b, a = this.r, this.g, this.b, this.opacity | |
| 411 ColorPickerFrame.cancelFunc = function() | |
| 412 if a1 == nil then | |
| 413 func(r, g, b, a) | |
| 414 elseif a2 == nil then | |
| 415 func(a1, r, g, b, a) | |
| 416 elseif a3 == nil then | |
| 417 func(a1, a2, r, g, b, a) | |
| 418 else | |
| 419 func(a1, a2, a3, r, g, b, a) | |
| 420 end | |
| 421 end | |
| 422 self:Close(1) | |
| 423 ShowUIPanel(ColorPickerFrame) | |
| 424 elseif this.func then | |
| 425 local level = button.level | |
| 426 if type(this.func) == "string" then | |
| 427 self:assert(type(this.arg1[this.func]) == "function", "Cannot call method " .. this.func) | |
| 428 this.arg1[this.func](this.arg1, this.arg2, this.arg3, this.arg4) | |
| 429 else | |
| 430 this.func(this.arg1, this.arg2, this.arg3, this.arg4) | |
| 431 end | |
| 432 if this.closeWhenClicked then | |
| 433 self:Close() | |
| 434 elseif level:IsShown() then | |
| 435 for i = 1, level.num do | |
| 436 Refresh(self, levels[i]) | |
| 437 end | |
| 438 end | |
| 439 elseif this.closeWhenClicked then | |
| 440 self:Close() | |
| 441 end | |
| 442 end | |
| 443 end) | |
| 444 local text = button:CreateFontString(nil, "ARTWORK") | |
| 445 button.text = text | |
| 446 text:SetFontObject(GameFontHighlightSmall) | |
| 447 button.text:SetFont(STANDARD_TEXT_FONT, UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT) | |
| 448 button:SetScript("OnMouseDown", function() | |
| 449 if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then | |
| 450 text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 1 or 25, -1) | |
| 451 end | |
| 452 end) | |
| 453 button:SetScript("OnMouseUp", function() | |
| 454 if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then | |
| 455 text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 0 or 24, 0) | |
| 456 end | |
| 457 end) | |
| 458 local arrow = button:CreateTexture(nil, "ARTWORK") | |
| 459 button.arrow = arrow | |
| 460 arrow:SetPoint("LEFT", button, "RIGHT", -16, 0) | |
| 461 arrow:SetWidth(16) | |
| 462 arrow:SetHeight(16) | |
| 463 arrow:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") | |
| 464 local colorSwatch = button:CreateTexture(nil, "OVERLAY") | |
| 465 button.colorSwatch = colorSwatch | |
| 466 colorSwatch:SetWidth(20) | |
| 467 colorSwatch:SetHeight(20) | |
| 468 colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") | |
| 469 local texture = button:CreateTexture(nil, "OVERLAY") | |
| 470 colorSwatch.texture = texture | |
| 471 texture:SetTexture(1, 1, 1) | |
| 472 texture:SetWidth(11.5) | |
| 473 texture:SetHeight(11.5) | |
| 474 texture:Show() | |
| 475 texture:SetPoint("CENTER", colorSwatch, "CENTER") | |
| 476 colorSwatch:SetPoint("RIGHT", button, "RIGHT", 0, 0) | |
| 477 else | |
| 478 button = table.remove(buttons) | |
| 479 end | |
| 480 button:ClearAllPoints() | |
| 481 button:SetParent(level) | |
| 482 button:SetFrameStrata(level:GetFrameStrata()) | |
| 483 button:SetFrameLevel(level:GetFrameLevel() + 1) | |
| 484 button:SetPoint("LEFT", level, "LEFT", 10, 0) | |
| 485 button:SetPoint("RIGHT", level, "RIGHT", -10, 0) | |
| 486 if #level.buttons == 0 then | |
| 487 button:SetPoint("TOP", level, "TOP", 0, -10) | |
| 488 else | |
| 489 button:SetPoint("TOP", level.buttons[#level.buttons], "BOTTOM", 0, 0) | |
| 490 end | |
| 491 button.text:SetPoint("LEFT", button, "LEFT", 24, 0) | |
| 492 button:Show() | |
| 493 button.level = level | |
| 494 table.insert(level.buttons, button) | |
| 495 if not level.parented then | |
| 496 level.parented = true | |
| 497 level:ClearAllPoints() | |
| 498 if level.num == 1 then | |
| 499 if level.parent ~= UIParent then | |
| 500 level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT") | |
| 501 else | |
| 502 level:SetPoint("CENTER", level.parent, "CENTER") | |
| 503 end | |
| 504 else | |
| 505 if level.lastDirection == "RIGHT" then | |
| 506 if level.lastVDirection == "DOWN" then | |
| 507 level:SetPoint("TOPLEFT", level.parent, "TOPRIGHT", 5, 10) | |
| 508 else | |
| 509 level:SetPoint("BOTTOMLEFT", level.parent, "BOTTOMRIGHT", 5, -10) | |
| 510 end | |
| 511 else | |
| 512 if level.lastVDirection == "DOWN" then | |
| 513 level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT", -5, 10) | |
| 514 else | |
| 515 level:SetPoint("BOTTOMRIGHT", level.parent, "BOTTOMLEFT", -5, -10) | |
| 516 end | |
| 517 end | |
| 518 end | |
| 519 level:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 520 end | |
| 521 button:SetAlpha(1) | |
| 522 return button | |
| 523 end | |
| 524 | |
| 525 local numLevels = 0 | |
| 526 local function AcquireLevel(self, level) | |
| 527 if not levels[level] then | |
| 528 for i = #levels + 1, level, -1 do | |
| 529 local i = i | |
| 530 numLevels = numLevels + 1 | |
| 531 local frame = CreateFrame("Button", "Dewdrop20Level" .. numLevels, nil) | |
| 532 if i == 1 then | |
| 533 local old_CloseSpecialWindows = CloseSpecialWindows | |
| 534 function CloseSpecialWindows() | |
| 535 local found = old_CloseSpecialWindows() | |
| 536 if levels[1]:IsShown() then | |
| 537 self:Close() | |
| 538 return 1 | |
| 539 end | |
| 540 return found | |
| 541 end | |
| 542 end | |
| 543 levels[i] = frame | |
| 544 frame.num = i | |
| 545 frame:SetParent(UIParent) | |
| 546 frame:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 547 frame:Hide() | |
| 548 frame:SetWidth(180) | |
| 549 frame:SetHeight(10) | |
| 550 frame:SetFrameLevel(i * 3) | |
| 551 frame:SetScript("OnHide", function() | |
| 552 self:Close(level + 1) | |
| 553 end) | |
| 554 if frame.SetTopLevel then | |
| 555 frame:SetTopLevel(true) | |
| 556 end | |
| 557 frame:EnableMouse(true) | |
| 558 frame:EnableMouseWheel(true) | |
| 559 local backdrop = CreateFrame("Frame", nil, frame) | |
| 560 backdrop:SetAllPoints(frame) | |
| 561 backdrop:SetBackdrop(tmp( | |
| 562 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background", | |
| 563 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border", | |
| 564 'tile', true, | |
| 565 'insets', tmp2( | |
| 566 'left', 5, | |
| 567 'right', 5, | |
| 568 'top', 5, | |
| 569 'bottom', 5 | |
| 570 ), | |
| 571 'tileSize', 16, | |
| 572 'edgeSize', 16 | |
| 573 )) | |
| 574 backdrop:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b) | |
| 575 backdrop:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) | |
| 576 frame:SetScript("OnClick", function() | |
| 577 self:Close(i) | |
| 578 end) | |
| 579 frame:SetScript("OnEnter", function() | |
| 580 StopCounting(self, i) | |
| 581 end) | |
| 582 frame:SetScript("OnLeave", function() | |
| 583 StartCounting(self, i) | |
| 584 end) | |
| 585 frame:SetScript("OnMouseWheel", function() | |
| 586 Scroll(self, frame, arg1 < 0) | |
| 587 end) | |
| 588 if i == 1 then | |
| 589 frame:SetScript("OnUpdate", function() | |
| 590 OnUpdate(self, arg1) | |
| 591 end) | |
| 592 levels[1].lastDirection = "RIGHT" | |
| 593 levels[1].lastVDirection = "DOWN" | |
| 594 else | |
| 595 levels[i].lastDirection = levels[i - 1].lastDirection | |
| 596 levels[i].lastVDirection = levels[i - 1].lastVDirection | |
| 597 end | |
| 598 end | |
| 599 end | |
| 600 local fullscreenFrame = GetFullScreenFrame() | |
| 601 local l = levels[level] | |
| 602 local strata, framelevel = l:GetFrameStrata(), l:GetFrameLevel() | |
| 603 if fullscreenFrame then | |
| 604 l:SetParent(fullscreenFrame) | |
| 605 else | |
| 606 l:SetParent(UIParent) | |
| 607 end | |
| 608 l:SetFrameStrata(strata) | |
| 609 l:SetFrameLevel(framelevel) | |
| 610 l:SetAlpha(1) | |
| 611 return l | |
| 612 end | |
| 613 | |
| 614 local function checkValidate(validateFunc, func, arg1, arg2, arg3) | |
| 615 local text | |
| 616 if arg3 ~= nil then | |
| 617 text = arg3 | |
| 618 elseif arg2 ~= nil then | |
| 619 text = arg2 | |
| 620 else | |
| 621 text = arg1 | |
| 622 end | |
| 623 if not validateFunc(text) then | |
| 624 DEFAULT_CHAT_FRAME:AddMessage("|cffffff7fValidation error: [|r" .. tostring(text) .. "|cffffff7f]|r") | |
| 625 else | |
| 626 func(arg1, arg2, arg3) | |
| 627 end | |
| 628 end | |
| 629 | |
| 630 local function validateOptions(options, position, baseOptions, fromPass) | |
| 631 if not baseOptions then | |
| 632 baseOptions = options | |
| 633 end | |
| 634 if type(options) ~= "table" then | |
| 635 return "Options must be a table.", position | |
| 636 end | |
| 637 local kind = options.type | |
| 638 if type(kind) ~= "string" then | |
| 639 return '"type" must be a string.', position | |
| 640 elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then | |
| 641 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position | |
| 642 end | |
| 643 if options.aliases then | |
| 644 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then | |
| 645 return '"alias" must be a table or string', position | |
| 646 end | |
| 647 end | |
| 648 if not fromPass then | |
| 649 if kind == "execute" then | |
| 650 if type(options.func) ~= "string" and type(options.func) ~= "function" then | |
| 651 return '"func" must be a string or function', position | |
| 652 end | |
| 653 elseif kind == "range" or kind == "text" or kind == "toggle" then | |
| 654 if type(options.set) ~= "string" and type(options.set) ~= "function" then | |
| 655 return '"set" must be a string or function', position | |
| 656 end | |
| 657 if kind == "text" and options.get == false then | |
| 658 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then | |
| 659 return '"get" must be a string or function', position | |
| 660 end | |
| 661 elseif kind == "group" and options.pass then | |
| 662 if options.pass ~= true then | |
| 663 return '"pass" must be either nil, true, or false', position | |
| 664 end | |
| 665 if not options.func then | |
| 666 if type(options.set) ~= "string" and type(options.set) ~= "function" then | |
| 667 return '"set" must be a string or function', position | |
| 668 end | |
| 669 if type(options.get) ~= "string" and type(options.get) ~= "function" then | |
| 670 return '"get" must be a string or function', position | |
| 671 end | |
| 672 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then | |
| 673 return '"func" must be a string or function', position | |
| 674 end | |
| 675 end | |
| 676 else | |
| 677 if kind == "group" then | |
| 678 return 'cannot have "type" = "group" as a subgroup of a passing group', position | |
| 679 end | |
| 680 end | |
| 681 if options ~= baseOptions then | |
| 682 if kind == "header" then | |
| 683 elseif type(options.desc) ~= "string" then | |
| 684 return '"desc" must be a string', position | |
| 685 elseif options.desc:len() == 0 then | |
| 686 return '"desc" cannot be a 0-length string', position | |
| 687 end | |
| 688 end | |
| 689 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then | |
| 690 if options.type == "header" and not options.cmdName and not options.name then | |
| 691 elseif options.cmdName then | |
| 692 if type(options.cmdName) ~= "string" then | |
| 693 return '"cmdName" must be a string or nil', position | |
| 694 elseif options.cmdName:len() == 0 then | |
| 695 return '"cmdName" cannot be a 0-length string', position | |
| 696 end | |
| 697 if type(options.guiName) ~= "string" then | |
| 698 if not options.guiNameIsMap then | |
| 699 return '"guiName" must be a string or nil', position | |
| 700 end | |
| 701 elseif options.guiName:len() == 0 then | |
| 702 return '"guiName" cannot be a 0-length string', position | |
| 703 end | |
| 704 else | |
| 705 if type(options.name) ~= "string" then | |
| 706 return '"name" must be a string', position | |
| 707 elseif options.name:len() == 0 then | |
| 708 return '"name" cannot be a 0-length string', position | |
| 709 end | |
| 710 end | |
| 711 end | |
| 712 if options.guiNameIsMap then | |
| 713 if type(options.guiNameIsMap) ~= "boolean" then | |
| 714 return '"guiNameIsMap" must be a boolean or nil', position | |
| 715 elseif options.type ~= "toggle" then | |
| 716 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position | |
| 717 elseif type(options.map) ~= "table" then | |
| 718 return '"map" must be a table', position | |
| 719 end | |
| 720 end | |
| 721 if options.message and type(options.message) ~= "string" then | |
| 722 return '"message" must be a string or nil', position | |
| 723 end | |
| 724 if options.error and type(options.error) ~= "string" then | |
| 725 return '"error" must be a string or nil', position | |
| 726 end | |
| 727 if options.current and type(options.current) ~= "string" then | |
| 728 return '"current" must be a string or nil', position | |
| 729 end | |
| 730 if options.order then | |
| 731 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then | |
| 732 return '"order" must be a non-zero number or nil', position | |
| 733 end | |
| 734 end | |
| 735 if options.disabled then | |
| 736 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then | |
| 737 return '"disabled" must be a function, string, or boolean', position | |
| 738 end | |
| 739 end | |
| 740 if options.cmdHidden then | |
| 741 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then | |
| 742 return '"cmdHidden" must be a function, string, or boolean', position | |
| 743 end | |
| 744 end | |
| 745 if options.guiHidden then | |
| 746 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then | |
| 747 return '"guiHidden" must be a function, string, or boolean', position | |
| 748 end | |
| 749 end | |
| 750 if options.hidden then | |
| 751 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then | |
| 752 return '"hidden" must be a function, string, or boolean', position | |
| 753 end | |
| 754 end | |
| 755 if kind == "text" then | |
| 756 if type(options.validate) == "table" then | |
| 757 local t = options.validate | |
| 758 local iTable = nil | |
| 759 for k,v in pairs(t) do | |
| 760 if type(k) == "number" then | |
| 761 if iTable == nil then | |
| 762 iTable = true | |
| 763 elseif not iTable then | |
| 764 return '"validate" must either have all keys be indexed numbers or strings', position | |
| 765 elseif k < 1 or k > #t then | |
| 766 return '"validate" numeric keys must be indexed properly. >= 1 and <= #t', position | |
| 767 end | |
| 768 else | |
| 769 if iTable == nil then | |
| 770 iTable = false | |
| 771 elseif iTable then | |
| 772 return '"validate" must either have all keys be indexed numbers or strings', position | |
| 773 end | |
| 774 end | |
| 775 if type(v) ~= "string" then | |
| 776 return '"validate" values must all be strings', position | |
| 777 end | |
| 778 end | |
| 779 elseif options.validate == "keybinding" then | |
| 780 -- no other checks | |
| 781 else | |
| 782 if type(options.usage) ~= "string" then | |
| 783 return '"usage" must be a string', position | |
| 784 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then | |
| 785 return '"validate" must be a string, function, or table', position | |
| 786 end | |
| 787 end | |
| 788 elseif kind == "range" then | |
| 789 if options.min or options.max then | |
| 790 if type(options.min) ~= "number" then | |
| 791 return '"min" must be a number', position | |
| 792 elseif type(options.max) ~= "number" then | |
| 793 return '"max" must be a number', position | |
| 794 elseif options.min >= options.max then | |
| 795 return '"min" must be less than "max"', position | |
| 796 end | |
| 797 end | |
| 798 if options.step then | |
| 799 if type(options.step) ~= "number" then | |
| 800 return '"step" must be a number', position | |
| 801 elseif options.step < 0 then | |
| 802 return '"step" must be nonnegative', position | |
| 803 end | |
| 804 end | |
| 805 if options.isPercent and options.isPercent ~= true then | |
| 806 return '"isPercent" must either be nil, true, or false', position | |
| 807 end | |
| 808 elseif kind == "toggle" then | |
| 809 if options.map then | |
| 810 if type(options.map) ~= "table" then | |
| 811 return '"map" must be a table', position | |
| 812 elseif type(options.map[true]) ~= "string" then | |
| 813 return '"map[true]" must be a string', position | |
| 814 elseif type(options.map[false]) ~= "string" then | |
| 815 return '"map[false]" must be a string', position | |
| 816 end | |
| 817 end | |
| 818 elseif kind == "color" then | |
| 819 if options.hasAlpha and options.hasAlpha ~= true then | |
| 820 return '"hasAlpha" must be nil, true, or false', position | |
| 821 end | |
| 822 elseif kind == "group" then | |
| 823 if options.pass and options.pass ~= true then | |
| 824 return '"pass" must be nil, true, or false', position | |
| 825 end | |
| 826 if type(options.args) ~= "table" then | |
| 827 return '"args" must be a table', position | |
| 828 end | |
| 829 for k,v in pairs(options.args) do | |
| 830 if type(k) ~= "string" then | |
| 831 return '"args" keys must be strings', position | |
| 832 elseif k:find("%s") then | |
| 833 return string.format('"args" keys must not include spaces. %q is not appropriate.', k), position | |
| 834 elseif k:len() == 0 then | |
| 835 return '"args" keys must not be 0-length strings.', position | |
| 836 end | |
| 837 if type(v) ~= "table" then | |
| 838 return '"args" values must be tables', position and position .. "." .. k or k | |
| 839 end | |
| 840 local newposition | |
| 841 if position then | |
| 842 newposition = position .. ".args." .. k | |
| 843 else | |
| 844 newposition = "args." .. k | |
| 845 end | |
| 846 local err, pos = validateOptions(v, newposition, baseOptions, options.pass) | |
| 847 if err then | |
| 848 return err, pos | |
| 849 end | |
| 850 end | |
| 851 end | |
| 852 if options.icon and type(options.icon) ~= "string" then | |
| 853 return'"icon" must be a string', position | |
| 854 end | |
| 855 if options.iconWidth or options.iconHeight then | |
| 856 if type(options.iconWidth) ~= "number" or type(options.iconHeight) ~= "number" then | |
| 857 return '"iconHeight" and "iconWidth" must be numbers', position | |
| 858 end | |
| 859 end | |
| 860 if options.iconCoordLeft or options.iconCoordRight or options.iconCoordTop or options.iconCoordBottom then | |
| 861 if type(options.iconCoordLeft) ~= "number" or type(options.iconCoordRight) ~= "number" or type(options.iconCoordTop) ~= "number" or type(options.iconCoordBottom) ~= "number" then | |
| 862 return '"iconCoordLeft", "iconCoordRight", "iconCoordTop", and "iconCoordBottom" must be numbers', position | |
| 863 end | |
| 864 end | |
| 865 end | |
| 866 | |
| 867 local validatedOptions | |
| 868 | |
| 869 local values | |
| 870 local mysort_args | |
| 871 local mysort | |
| 872 local othersort | |
| 873 local othersort_validate | |
| 874 | |
| 875 local baseFunc, currentLevel | |
| 876 | |
| 877 function Dewdrop:FeedAceOptionsTable(options, difference) | |
| 878 self:argCheck(options, 2, "table") | |
| 879 self:argCheck(difference, 3, "nil", "number") | |
| 880 self:assert(currentLevel, "Cannot call `FeedAceOptionsTable' outside of a Dewdrop declaration") | |
| 881 if not difference then | |
| 882 difference = 0 | |
| 883 end | |
| 884 if not validatedOptions then | |
| 885 validatedOptions = {} | |
| 886 end | |
| 887 if not validatedOptions[options] then | |
| 888 local err, position = validateOptions(options) | |
| 889 | |
| 890 if err then | |
| 891 if position then | |
| 892 Dewdrop:error(position .. ": " .. err) | |
| 893 else | |
| 894 Dewdrop:error(err) | |
| 895 end | |
| 896 end | |
| 897 | |
| 898 validatedOptions[options] = true | |
| 899 end | |
| 900 local level = levels[currentLevel] | |
| 901 self:assert(level, "Improper level given") | |
| 902 if not values then | |
| 903 values = {} | |
| 904 else | |
| 905 for k,v in pairs(values) do | |
| 906 values[k] = nil | |
| 907 end | |
| 908 end | |
| 909 | |
| 910 local current = level | |
| 911 while current do | |
| 912 if current.num == difference + 1 then | |
| 913 break | |
| 914 end | |
| 915 table.insert(values, current.value) | |
| 916 current = levels[current.num - 1] | |
| 917 end | |
| 918 | |
| 919 local realOptions = options | |
| 920 local handler = options.handler | |
| 921 local passTable | |
| 922 local passValue | |
| 923 while #values > 0 do | |
| 924 passTable = options.pass and current or nil | |
| 925 local value = table.remove(values) | |
| 926 options = options.args and options.args[value] | |
| 927 if not options then | |
| 928 return | |
| 929 end | |
| 930 handler = options.handler or handler | |
| 931 passValue = passTable and value or nil | |
| 932 end | |
| 933 | |
| 934 if options.type == "group" then | |
| 935 for k in pairs(options.args) do | |
| 936 table.insert(values, k) | |
| 937 end | |
| 938 if not mysort then | |
| 939 mysort = function(a, b) | |
| 940 local alpha, bravo = mysort_args[a], mysort_args[b] | |
| 941 local alpha_order = alpha.order or 100 | |
| 942 local bravo_order = bravo.order or 100 | |
| 943 local alpha_name = alpha.guiName or alpha.name | |
| 944 local bravo_name = bravo.guiName or bravo.name | |
| 945 if alpha_order == bravo_order then | |
| 946 if not alpha_name then | |
| 947 return true | |
| 948 elseif not bravo_name then | |
| 949 return false | |
| 950 else | |
| 951 return alpha_name:upper() < bravo_name:upper() | |
| 952 end | |
| 953 else | |
| 954 if alpha_order < 0 then | |
| 955 if bravo_order > 0 then | |
| 956 return false | |
| 957 end | |
| 958 else | |
| 959 if bravo_order < 0 then | |
| 960 return true | |
| 961 end | |
| 962 end | |
| 963 return alpha_order < bravo_order | |
| 964 end | |
| 965 end | |
| 966 end | |
| 967 mysort_args = options.args | |
| 968 table.sort(values, mysort) | |
| 969 mysort_args = nil | |
| 970 local hasBoth = #values >= 1 and (options.args[values[1]].order or 100) > 0 and (options.args[values[#values]].order or 100) < 0 | |
| 971 local last_order = 1 | |
| 972 for _,k in ipairs(values) do | |
| 973 local v = options.args[k] | |
| 974 local handler = v.handler or handler | |
| 975 if hasBoth and last_order > 0 and (v.order or 100) < 0 then | |
| 976 hasBoth = false | |
| 977 self:AddLine() | |
| 978 end | |
| 979 local hidden, disabled = v.guiHidden or v.hidden, v.disabled | |
| 980 if type(hidden) == "function" then | |
| 981 hidden = hidden() | |
| 982 elseif type(hidden) == "string" then | |
| 983 local f = hidden | |
| 984 local neg = f:match("^~(.-)$") | |
| 985 if neg then | |
| 986 f = neg | |
| 987 end | |
| 988 hidden = handler[f](handler) | |
| 989 if neg then | |
| 990 hidden = not hidden | |
| 991 end | |
| 992 end | |
| 993 if not hidden then | |
| 994 if type(disabled) == "function" then | |
| 995 disabled = disabled() | |
| 996 elseif type(disabled) == "string" then | |
| 997 local f = disabled | |
| 998 local neg = f:match("^~(.-)$") | |
| 999 if neg then | |
| 1000 f = neg | |
| 1001 end | |
| 1002 disabled = handler[f](handler) | |
| 1003 if neg then | |
| 1004 disabled = not disabled | |
| 1005 end | |
| 1006 end | |
| 1007 local name = (v.guiIconOnly and v.icon) and "" or (v.guiName or v.name) | |
| 1008 local desc = v.desc | |
| 1009 local iconHeight = v.iconHeight or 16 | |
| 1010 local iconWidth = v.iconWidth or 16 | |
| 1011 local iconCoordLeft = v.iconCoordLeft | |
| 1012 local iconCoordRight = v.iconCoordRight | |
| 1013 local iconCoordBottom = v.iconCoordBottom | |
| 1014 local iconCoordTop = v.iconCoordTop | |
| 1015 local tooltipTitle, tooltipText | |
| 1016 tooltipTitle = name | |
| 1017 if name ~= desc then | |
| 1018 tooltipText = desc | |
| 1019 end | |
| 1020 if v.type == "toggle" then | |
| 1021 local checked | |
| 1022 local checked_arg | |
| 1023 if type(v.get) == "function" then | |
| 1024 checked = v.get(passValue) | |
| 1025 checked_arg = checked | |
| 1026 else | |
| 1027 local f = v.get | |
| 1028 local neg = f:match("^~(.-)$") | |
| 1029 if neg then | |
| 1030 f = neg | |
| 1031 end | |
| 1032 if not handler[f] then | |
| 1033 Dewdrop:error("Handler %q not available", f) | |
| 1034 end | |
| 1035 checked = handler[f](handler, passValue) | |
| 1036 checked_arg = checked | |
| 1037 if neg then | |
| 1038 checked = not checked | |
| 1039 end | |
| 1040 end | |
| 1041 local func, arg1, arg2, arg3 | |
| 1042 if type(v.set) == "function" then | |
| 1043 func = v.set | |
| 1044 if passValue ~= nil then | |
| 1045 arg1 = passValue | |
| 1046 arg2 = not checked_arg | |
| 1047 else | |
| 1048 arg1 = not checked_arg | |
| 1049 end | |
| 1050 else | |
| 1051 if not handler[v.set] then | |
| 1052 Dewdrop:error("Handler %q not available", v.set) | |
| 1053 end | |
| 1054 func = handler[v.set] | |
| 1055 arg1 = handler | |
| 1056 if passValue ~= nil then | |
| 1057 arg2 = passValue | |
| 1058 arg3 = not checked_arg | |
| 1059 else | |
| 1060 arg2 = not checked_arg | |
| 1061 end | |
| 1062 end | |
| 1063 if v.guiNameIsMap then | |
| 1064 checked = checked and true or false | |
| 1065 name = tostring(v.map and v.map[checked]):gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1") | |
| 1066 checked = nil | |
| 1067 end | |
| 1068 self:AddLine( | |
| 1069 'text', name, | |
| 1070 'checked', checked, | |
| 1071 'isRadio', v.isRadio, | |
| 1072 'func', func, | |
| 1073 'arg1', arg1, | |
| 1074 'arg2', arg2, | |
| 1075 'arg3', arg3, | |
| 1076 'disabled', disabled, | |
| 1077 'tooltipTitle', tooltipTitle, | |
| 1078 'tooltipText', tooltipText | |
| 1079 ) | |
| 1080 elseif v.type == "execute" then | |
| 1081 local func, arg1, arg2 | |
| 1082 if type(v.func) == "function" then | |
| 1083 func = v.func | |
| 1084 arg1 = passValue | |
| 1085 else | |
| 1086 if not handler[v.func] then | |
| 1087 Dewdrop:error("Handler %q not available", v.func) | |
| 1088 end | |
| 1089 func = handler[v.func] | |
| 1090 arg1 = handler | |
| 1091 arg2 = passValue | |
| 1092 end | |
| 1093 self:AddLine( | |
| 1094 'text', name, | |
| 1095 'checked', checked, | |
| 1096 'func', func, | |
| 1097 'arg1', arg1, | |
| 1098 'arg2', arg2, | |
| 1099 'disabled', disabled, | |
| 1100 'tooltipTitle', tooltipTitle, | |
| 1101 'tooltipText', tooltipText, | |
| 1102 'icon', v.icon, | |
| 1103 'iconHeight', iconHeight, | |
| 1104 'iconWidth', iconWidth, | |
| 1105 'iconCoordLeft', iconCoordLeft, | |
| 1106 'iconCoordRight', iconCoordRight, | |
| 1107 'iconCoordTop', iconCoordTop, | |
| 1108 'iconCoordBottom', iconCoordBottom | |
| 1109 ) | |
| 1110 elseif v.type == "range" then | |
| 1111 local sliderValue | |
| 1112 if type(v.get) == "function" then | |
| 1113 sliderValue = v.get(passValue) | |
| 1114 else | |
| 1115 if not handler[v.get] then | |
| 1116 Dewdrop:error("Handler %q not available", v.get) | |
| 1117 end | |
| 1118 sliderValue = handler[v.get](handler, passValue) | |
| 1119 end | |
| 1120 local sliderFunc, sliderArg1, sliderArg2 | |
| 1121 if type(v.set) == "function" then | |
| 1122 sliderFunc = v.set | |
| 1123 sliderArg1 = passValue | |
| 1124 else | |
| 1125 if not handler[v.set] then | |
| 1126 Dewdrop:error("Handler %q not available", v.set) | |
| 1127 end | |
| 1128 sliderFunc = handler[v.set] | |
| 1129 sliderArg1 = handler | |
| 1130 sliderArg2 = passValue | |
| 1131 end | |
| 1132 self:AddLine( | |
| 1133 'text', name, | |
| 1134 'hasArrow', true, | |
| 1135 'hasSlider', true, | |
| 1136 'sliderMin', v.min or 0, | |
| 1137 'sliderMax', v.max or 1, | |
| 1138 'sliderStep', v.step or 0, | |
| 1139 'sliderIsPercent', v.isPercent or false, | |
| 1140 'sliderValue', sliderValue, | |
| 1141 'sliderFunc', sliderFunc, | |
| 1142 'sliderArg1', sliderArg1, | |
| 1143 'sliderArg2', sliderArg2, | |
| 1144 'disabled', disabled, | |
| 1145 'tooltipTitle', tooltipTitle, | |
| 1146 'tooltipText', tooltipText, | |
| 1147 'icon', v.icon, | |
| 1148 'iconHeight', iconHeight, | |
| 1149 'iconWidth', iconWidth, | |
| 1150 'iconCoordLeft', iconCoordLeft, | |
| 1151 'iconCoordRight', iconCoordRight, | |
| 1152 'iconCoordTop', iconCoordTop, | |
| 1153 'iconCoordBottom', iconCoordBottom | |
| 1154 ) | |
| 1155 elseif v.type == "color" then | |
| 1156 local r,g,b,a | |
| 1157 if type(v.get) == "function" then | |
| 1158 r,g,b,a = v.get(passValue) | |
| 1159 else | |
| 1160 if not handler[v.get] then | |
| 1161 Dewdrop:error("Handler %q not available", v.get) | |
| 1162 end | |
| 1163 r,g,b,a = handler[v.get](handler, passValue) | |
| 1164 end | |
| 1165 local colorFunc, colorArg1, colorArg2 | |
| 1166 if type(v.set) == "function" then | |
| 1167 colorFunc = v.set | |
| 1168 colorArg1 = passValue | |
| 1169 else | |
| 1170 if not handler[v.set] then | |
| 1171 Dewdrop:error("Handler %q not available", v.set) | |
| 1172 end | |
| 1173 colorFunc = handler[v.set] | |
| 1174 colorArg1 = handler | |
| 1175 colorArg2 = passValue | |
| 1176 end | |
| 1177 self:AddLine( | |
| 1178 'text', name, | |
| 1179 'hasArrow', true, | |
| 1180 'hasColorSwatch', true, | |
| 1181 'r', r, | |
| 1182 'g', g, | |
| 1183 'b', b, | |
| 1184 'opacity', v.hasAlpha and a or nil, | |
| 1185 'hasOpacity', v.hasAlpha, | |
| 1186 'colorFunc', colorFunc, | |
| 1187 'colorArg1', colorArg1, | |
| 1188 'colorArg2', colorArg2, | |
| 1189 'disabled', disabled, | |
| 1190 'tooltipTitle', tooltipTitle, | |
| 1191 'tooltipText', tooltipText | |
| 1192 ) | |
| 1193 elseif v.type == "text" then | |
| 1194 if type(v.validate) == "table" then | |
| 1195 self:AddLine( | |
| 1196 'text', name, | |
| 1197 'hasArrow', true, | |
| 1198 'value', k, | |
| 1199 'disabled', disabled, | |
| 1200 'tooltipTitle', tooltipTitle, | |
| 1201 'tooltipText', tooltipText, | |
| 1202 'icon', v.icon, | |
| 1203 'iconHeight', iconHeight, | |
| 1204 'iconWidth', iconWidth, | |
| 1205 'iconCoordLeft', iconCoordLeft, | |
| 1206 'iconCoordRight', iconCoordRight, | |
| 1207 'iconCoordTop', iconCoordTop, | |
| 1208 'iconCoordBottom', iconCoordBottom | |
| 1209 ) | |
| 1210 else | |
| 1211 local editBoxText | |
| 1212 if type(v.get) == "function" then | |
| 1213 editBoxText = v.get(passValue) | |
| 1214 elseif v.get == false then | |
| 1215 editBoxText = nil | |
| 1216 else | |
| 1217 if not handler[v.get] then | |
| 1218 Dewdrop:error("Handler %q not available", v.get) | |
| 1219 end | |
| 1220 editBoxText = handler[v.get](handler, passValue) | |
| 1221 end | |
| 1222 local editBoxFunc, editBoxArg1, editBoxArg2 | |
| 1223 if type(v.set) == "function" then | |
| 1224 editBoxFunc = v.set | |
| 1225 editBoxArg1 = passValue | |
| 1226 else | |
| 1227 if not handler[v.set] then | |
| 1228 Dewdrop:error("Handler %q not available", v.set) | |
| 1229 end | |
| 1230 editBoxFunc = handler[v.set] | |
| 1231 editBoxArg1 = handler | |
| 1232 editBoxArg2 = passValue | |
| 1233 end | |
| 1234 | |
| 1235 local editBoxValidateFunc, editBoxValidateArg1 | |
| 1236 | |
| 1237 if v.validate and v.validate ~= "keybinding" then | |
| 1238 if type(v.validate) == "function" then | |
| 1239 editBoxValidateFunc = v.validate | |
| 1240 else | |
| 1241 if not handler[v.validate] then | |
| 1242 Dewdrop:error("Handler %q not available", v.validate) | |
| 1243 end | |
| 1244 editBoxValidateFunc = handler[v.validate] | |
| 1245 editBoxValidateArg1 = handler | |
| 1246 end | |
| 1247 elseif v.validate then | |
| 1248 if tooltipText then | |
| 1249 tooltipText = tooltipText .. "\n\n" .. RESET_KEYBINDING_DESC | |
| 1250 else | |
| 1251 tooltipText = RESET_KEYBINDING_DESC | |
| 1252 end | |
| 1253 end | |
| 1254 | |
| 1255 self:AddLine( | |
| 1256 'text', name, | |
| 1257 'hasArrow', true, | |
| 1258 'icon', v.icon, | |
| 1259 'iconHeight', iconHeight, | |
| 1260 'iconWidth', iconWidth, | |
| 1261 'iconCoordLeft', iconCoordLeft, | |
| 1262 'iconCoordRight', iconCoordRight, | |
| 1263 'iconCoordTop', iconCoordTop, | |
| 1264 'iconCoordBottom', iconCoordBottom, | |
| 1265 'hasEditBox', true, | |
| 1266 'editBoxText', editBoxText, | |
| 1267 'editBoxFunc', editBoxFunc, | |
| 1268 'editBoxArg1', editBoxArg1, | |
| 1269 'editBoxArg2', editBoxArg2, | |
| 1270 'editBoxValidateFunc', editBoxValidateFunc, | |
| 1271 'editBoxValidateArg1', editBoxValidateArg1, | |
| 1272 'editBoxIsKeybinding', v.validate == "keybinding", | |
| 1273 'disabled', disabled, | |
| 1274 'tooltipTitle', tooltipTitle, | |
| 1275 'tooltipText', tooltipText | |
| 1276 ) | |
| 1277 end | |
| 1278 elseif v.type == "group" then | |
| 1279 self:AddLine( | |
| 1280 'text', name, | |
| 1281 'hasArrow', true, | |
| 1282 'value', k, | |
| 1283 'disabled', disabled, | |
| 1284 'tooltipTitle', tooltipTitle, | |
| 1285 'tooltipText', tooltipText, | |
| 1286 'icon', v.icon, | |
| 1287 'iconHeight', iconHeight, | |
| 1288 'iconWidth', iconWidth, | |
| 1289 'iconCoordLeft', iconCoordLeft, | |
| 1290 'iconCoordRight', iconCoordRight, | |
| 1291 'iconCoordTop', iconCoordTop, | |
| 1292 'iconCoordBottom', iconCoordBottom | |
| 1293 ) | |
| 1294 elseif v.type == "header" then | |
| 1295 if name == "" or not name then | |
| 1296 self:AddLine( | |
| 1297 'isTitle', true, | |
| 1298 'icon', v.icon, | |
| 1299 'iconHeight', iconHeight, | |
| 1300 'iconWidth', iconWidth, | |
| 1301 'iconCoordLeft', iconCoordLeft, | |
| 1302 'iconCoordRight', iconCoordRight, | |
| 1303 'iconCoordTop', iconCoordTop, | |
| 1304 'iconCoordBottom', iconCoordBottom | |
| 1305 ) | |
| 1306 else | |
| 1307 self:AddLine( | |
| 1308 'text', name, | |
| 1309 'isTitle', true, | |
| 1310 'icon', v.icon, | |
| 1311 'iconHeight', iconHeight, | |
| 1312 'iconWidth', iconWidth, | |
| 1313 'iconCoordLeft', iconCoordLeft, | |
| 1314 'iconCoordRight', iconCoordRight, | |
| 1315 'iconCoordTop', iconCoordTop, | |
| 1316 'iconCoordBottom', iconCoordBottom | |
| 1317 ) | |
| 1318 end | |
| 1319 end | |
| 1320 end | |
| 1321 last_order = v.order or 100 | |
| 1322 end | |
| 1323 elseif options.type == "text" and type(options.validate) == "table" then | |
| 1324 local current | |
| 1325 if type(options.get) == "function" then | |
| 1326 current = options.get(passValue) | |
| 1327 elseif options.get ~= false then | |
| 1328 if not handler[options.get] then | |
| 1329 Dewdrop:error("Handler %q not available", options.get) | |
| 1330 end | |
| 1331 current = handler[options.get](handler, passValue) | |
| 1332 end | |
| 1333 local indexed = true | |
| 1334 for k,v in pairs(options.validate) do | |
| 1335 if type(k) ~= "number" then | |
| 1336 indexed = false | |
| 1337 end | |
| 1338 table.insert(values, k) | |
| 1339 end | |
| 1340 if not indexed then | |
| 1341 if not othersort then | |
| 1342 othersort = function(alpha, bravo) | |
| 1343 return othersort_validate[alpha] < othersort_validate[bravo] | |
| 1344 end | |
| 1345 end | |
| 1346 othersort_validate = options.validate | |
| 1347 table.sort(values, othersort) | |
| 1348 othersort_validate = nil | |
| 1349 end | |
| 1350 for _,k in ipairs(values) do | |
| 1351 local v = options.validate[k] | |
| 1352 if type(k) == "number" then | |
| 1353 k = v | |
| 1354 end | |
| 1355 local func, arg1, arg2 | |
| 1356 if type(options.set) == "function" then | |
| 1357 func = options.set | |
| 1358 if passValue ~= nil then | |
| 1359 arg1 = passValue | |
| 1360 arg2 = k | |
| 1361 else | |
| 1362 arg1 = k | |
| 1363 end | |
| 1364 else | |
| 1365 if not handler[options.set] then | |
| 1366 Dewdrop:error("Handler %q not available", options.set) | |
| 1367 end | |
| 1368 func = handler[options.set] | |
| 1369 arg1 = handler | |
| 1370 if passValue ~= nil then | |
| 1371 arg2 = passValue | |
| 1372 arg3 = k | |
| 1373 else | |
| 1374 arg2 = k | |
| 1375 end | |
| 1376 end | |
| 1377 local checked = (k == current or (type(k) == "string" and type(current) == "string" and k:lower() == current:lower())) | |
| 1378 self:AddLine( | |
| 1379 'text', v, | |
| 1380 'func', not checked and func or nil, | |
| 1381 'arg1', not checked and arg1 or nil, | |
| 1382 'arg2', not checked and arg2 or nil, | |
| 1383 'arg3', not checked and arg3 or nil, | |
| 1384 'isRadio', true, | |
| 1385 'checked', checked, | |
| 1386 'tooltipTitle', options.guiName or options.name, | |
| 1387 'tooltipText', v | |
| 1388 ) | |
| 1389 end | |
| 1390 for k in pairs(values) do | |
| 1391 values[k] = nil | |
| 1392 end | |
| 1393 else | |
| 1394 return false | |
| 1395 end | |
| 1396 return true | |
| 1397 end | |
| 1398 | |
| 1399 function Refresh(self, level) | |
| 1400 if type(level) == "number" then | |
| 1401 level = levels[level] | |
| 1402 end | |
| 1403 if not level then | |
| 1404 return | |
| 1405 end | |
| 1406 if baseFunc then | |
| 1407 Clear(self, level) | |
| 1408 currentLevel = level.num | |
| 1409 if type(baseFunc) == "table" then | |
| 1410 if currentLevel == 1 then | |
| 1411 local handler = baseFunc.handler | |
| 1412 if handler then | |
| 1413 local name = tostring(handler) | |
| 1414 if not name:find('^table:') then | |
| 1415 name = name:gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1") | |
| 1416 self:AddLine( | |
| 1417 'text', name, | |
| 1418 'isTitle', true | |
| 1419 ) | |
| 1420 end | |
| 1421 end | |
| 1422 -- elseif level.parentText then | |
| 1423 -- self:AddLine( | |
| 1424 -- 'text', level.parentText, | |
| 1425 -- 'tooltipTitle', level.parentTooltipTitle, | |
| 1426 -- 'tooltipText', level.parentTooltipText, | |
| 1427 -- 'tooltipFunc', level.parentTooltipFunc, | |
| 1428 -- 'isTitle', true | |
| 1429 -- ) | |
| 1430 end | |
| 1431 self:FeedAceOptionsTable(baseFunc) | |
| 1432 if currentLevel == 1 then | |
| 1433 self:AddLine( | |
| 1434 'text', CLOSE, | |
| 1435 'tooltipTitle', CLOSE, | |
| 1436 'tooltipText', CLOSE_DESC, | |
| 1437 'closeWhenClicked', true | |
| 1438 ) | |
| 1439 end | |
| 1440 else | |
| 1441 -- if level.parentText then | |
| 1442 -- self:AddLine( | |
| 1443 -- 'text', level.parentText, | |
| 1444 -- 'tooltipTitle', level.parentTooltipTitle, | |
| 1445 -- 'tooltipText', level.parentTooltipText, | |
| 1446 -- 'tooltipFunc', level.parentTooltipFunc, | |
| 1447 -- 'isTitle', true | |
| 1448 -- ) | |
| 1449 -- end | |
| 1450 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) | |
| 1451 end | |
| 1452 currentLevel = nil | |
| 1453 CheckSize(self, level) | |
| 1454 end | |
| 1455 end | |
| 1456 | |
| 1457 function Dewdrop:Refresh(level) | |
| 1458 self:argCheck(level, 2, "number") | |
| 1459 Refresh(self, levels[level]) | |
| 1460 end | |
| 1461 | |
| 1462 function OpenSlider(self, parent) | |
| 1463 if not sliderFrame then | |
| 1464 sliderFrame = CreateFrame("Frame", nil, nil) | |
| 1465 sliderFrame:SetWidth(80) | |
| 1466 sliderFrame:SetHeight(170) | |
| 1467 sliderFrame:SetScale(UIParent:GetScale()) | |
| 1468 sliderFrame:SetBackdrop(tmp( | |
| 1469 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background", | |
| 1470 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border", | |
| 1471 'tile', true, | |
| 1472 'insets', tmp2( | |
| 1473 'left', 5, | |
| 1474 'right', 5, | |
| 1475 'top', 5, | |
| 1476 'bottom', 5 | |
| 1477 ), | |
| 1478 'tileSize', 16, | |
| 1479 'edgeSize', 16 | |
| 1480 )) | |
| 1481 sliderFrame:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 1482 if sliderFrame.SetTopLevel then | |
| 1483 sliderFrame:SetTopLevel(true) | |
| 1484 end | |
| 1485 sliderFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b) | |
| 1486 sliderFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) | |
| 1487 sliderFrame:EnableMouse(true) | |
| 1488 sliderFrame:Hide() | |
| 1489 sliderFrame:SetPoint("CENTER", UIParent, "CENTER") | |
| 1490 local slider = CreateFrame("Slider", nil, sliderFrame) | |
| 1491 sliderFrame.slider = slider | |
| 1492 slider:SetOrientation("VERTICAL") | |
| 1493 slider:SetMinMaxValues(0, 1) | |
| 1494 slider:SetValueStep(0.01) | |
| 1495 slider:SetValue(0.5) | |
| 1496 slider:SetWidth(16) | |
| 1497 slider:SetHeight(128) | |
| 1498 slider:SetPoint("LEFT", sliderFrame, "LEFT", 15, 0) | |
| 1499 slider:SetBackdrop(tmp( | |
| 1500 'bgFile', "Interface\\Buttons\\UI-SliderBar-Background", | |
| 1501 'edgeFile', "Interface\\Buttons\\UI-SliderBar-Border", | |
| 1502 'tile', true, | |
| 1503 'edgeSize', 8, | |
| 1504 'tileSize', 8, | |
| 1505 'insets', tmp2( | |
| 1506 'left', 3, | |
| 1507 'right', 3, | |
| 1508 'top', 3, | |
| 1509 'bottom', 3 | |
| 1510 ) | |
| 1511 )) | |
| 1512 local texture = slider:CreateTexture() | |
| 1513 slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical") | |
| 1514 local text = slider:CreateFontString(nil, "ARTWORK") | |
| 1515 sliderFrame.topText = text | |
| 1516 text:SetFontObject(GameFontGreenSmall) | |
| 1517 text:SetText("100%") | |
| 1518 text:SetPoint("BOTTOM", slider, "TOP") | |
| 1519 local text = slider:CreateFontString(nil, "ARTWORK") | |
| 1520 sliderFrame.bottomText = text | |
| 1521 text:SetFontObject(GameFontGreenSmall) | |
| 1522 text:SetText("0%") | |
| 1523 text:SetPoint("TOP", slider, "BOTTOM") | |
| 1524 local text = slider:CreateFontString(nil, "ARTWORK") | |
| 1525 sliderFrame.currentText = text | |
| 1526 text:SetFontObject(GameFontHighlightSmall) | |
| 1527 text:SetText("50%") | |
| 1528 text:SetPoint("LEFT", slider, "RIGHT") | |
| 1529 text:SetPoint("RIGHT", sliderFrame, "RIGHT", -6, 0) | |
| 1530 text:SetJustifyH("CENTER") | |
| 1531 local changed = false | |
| 1532 local inside = false | |
| 1533 slider:SetScript("OnValueChanged", function() | |
| 1534 if sliderFrame.changing then | |
| 1535 return | |
| 1536 end | |
| 1537 changed = true | |
| 1538 local done = false | |
| 1539 if sliderFrame.parent and sliderFrame.parent.sliderFunc then | |
| 1540 local min = sliderFrame.parent.sliderMin or 0 | |
| 1541 local max = sliderFrame.parent.sliderMax or 1 | |
| 1542 local step = sliderFrame.parent.sliderStep or (max - min) / 100 | |
| 1543 local a1,a2,a3,a4 = sliderFrame.parent.sliderArg1, sliderFrame.parent.sliderArg2, sliderFrame.parent.sliderArg3, sliderFrame.parent.sliderArg4 | |
| 1544 local value = (1 - slider:GetValue()) * (max - min) + min | |
| 1545 if step > 0 then | |
| 1546 value = math.floor((value - min) / step + 0.5) * step + min | |
| 1547 if value > max then | |
| 1548 value = max | |
| 1549 elseif value < min then | |
| 1550 value = min | |
| 1551 end | |
| 1552 end | |
| 1553 if value == sliderFrame.lastValue then | |
| 1554 return | |
| 1555 end | |
| 1556 sliderFrame.lastValue = value | |
| 1557 local text | |
| 1558 if a1 == nil then | |
| 1559 text = sliderFrame.parent.sliderFunc(value) | |
| 1560 elseif a2 == nil then | |
| 1561 text = sliderFrame.parent.sliderFunc(a1, value) | |
| 1562 elseif a3 == nil then | |
| 1563 text = sliderFrame.parent.sliderFunc(a1, a2, value) | |
| 1564 elseif a4 == nil then | |
| 1565 text = sliderFrame.parent.sliderFunc(a1, a2, a3, value) | |
| 1566 else | |
| 1567 text = sliderFrame.parent.sliderFunc(a1, a2, a3, a4, value) | |
| 1568 end | |
| 1569 if text then | |
| 1570 sliderFrame.currentText:SetText(text) | |
| 1571 done = true | |
| 1572 end | |
| 1573 end | |
| 1574 if not done then | |
| 1575 local min = sliderFrame.parent.sliderMin or 0 | |
| 1576 local max = sliderFrame.parent.sliderMax or 1 | |
| 1577 local step = sliderFrame.parent.sliderStep or (max - min) / 100 | |
| 1578 local value = (1 - slider:GetValue()) * (max - min) + min | |
| 1579 if step > 0 then | |
| 1580 value = math.floor((value - min) / step + 0.5) * step + min | |
| 1581 if value > max then | |
| 1582 value = max | |
| 1583 elseif value < min then | |
| 1584 value = min | |
| 1585 end | |
| 1586 end | |
| 1587 if sliderFrame.parent.sliderIsPercent then | |
| 1588 sliderFrame.currentText:SetText(string.format("%.0f%%", value * 100)) | |
| 1589 else | |
| 1590 if step < 0.1 then | |
| 1591 sliderFrame.currentText:SetText(string.format("%.2f", value)) | |
| 1592 elseif step < 1 then | |
| 1593 sliderFrame.currentText:SetText(string.format("%.1f", value)) | |
| 1594 else | |
| 1595 sliderFrame.currentText:SetText(string.format("%.0f", value)) | |
| 1596 end | |
| 1597 end | |
| 1598 end | |
| 1599 end) | |
| 1600 sliderFrame:SetScript("OnEnter", function() | |
| 1601 StopCounting(self, sliderFrame.level) | |
| 1602 showGameTooltip(sliderFrame.parent) | |
| 1603 end) | |
| 1604 sliderFrame:SetScript("OnLeave", function() | |
| 1605 StartCounting(self, sliderFrame.level) | |
| 1606 GameTooltip:Hide() | |
| 1607 end) | |
| 1608 slider:SetScript("OnMouseDown", function() | |
| 1609 sliderFrame.mouseDown = true | |
| 1610 GameTooltip:Hide() | |
| 1611 end) | |
| 1612 slider:SetScript("OnMouseUp", function() | |
| 1613 sliderFrame.mouseDown = false | |
| 1614 if changed--[[ and not inside]] then | |
| 1615 local parent = sliderFrame.parent | |
| 1616 local sliderFunc = parent.sliderFunc | |
| 1617 for i = 1, sliderFrame.level - 1 do | |
| 1618 Refresh(self, levels[i]) | |
| 1619 end | |
| 1620 local newParent | |
| 1621 for _,button in ipairs(levels[sliderFrame.level-1].buttons) do | |
| 1622 if button.sliderFunc == sliderFunc then | |
| 1623 newParent = button | |
| 1624 break | |
| 1625 end | |
| 1626 end | |
| 1627 if newParent then | |
| 1628 OpenSlider(self, newParent) | |
| 1629 else | |
| 1630 sliderFrame:Hide() | |
| 1631 end | |
| 1632 end | |
| 1633 if inside then | |
| 1634 showGameTooltip(sliderFrame.parent) | |
| 1635 end | |
| 1636 end) | |
| 1637 slider:SetScript("OnEnter", function() | |
| 1638 inside = true | |
| 1639 StopCounting(self, sliderFrame.level) | |
| 1640 showGameTooltip(sliderFrame.parent) | |
| 1641 end) | |
| 1642 slider:SetScript("OnLeave", function() | |
| 1643 inside = false | |
| 1644 StartCounting(self, sliderFrame.level) | |
| 1645 GameTooltip:Hide() | |
| 1646 if changed and not sliderFrame.mouseDown then | |
| 1647 local parent = sliderFrame.parent | |
| 1648 local sliderFunc = parent.sliderFunc | |
| 1649 for i = 1, sliderFrame.level - 1 do | |
| 1650 Refresh(self, levels[i]) | |
| 1651 end | |
| 1652 local newParent | |
| 1653 for _,button in ipairs(levels[sliderFrame.level-1].buttons) do | |
| 1654 if button.sliderFunc == sliderFunc then | |
| 1655 newParent = button | |
| 1656 break | |
| 1657 end | |
| 1658 end | |
| 1659 if newParent then | |
| 1660 OpenSlider(self, newParent) | |
| 1661 else | |
| 1662 sliderFrame:Hide() | |
| 1663 end | |
| 1664 end | |
| 1665 end) | |
| 1666 end | |
| 1667 sliderFrame.parent = parent | |
| 1668 sliderFrame.level = parent.level.num + 1 | |
| 1669 sliderFrame.parentValue = parent.level.value | |
| 1670 sliderFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3) | |
| 1671 sliderFrame.slider:SetFrameLevel(sliderFrame:GetFrameLevel() + 1) | |
| 1672 sliderFrame.changing = true | |
| 1673 if not parent.sliderMin or not parent.sliderMax then | |
| 1674 return | |
| 1675 end | |
| 1676 | |
| 1677 if parent.arrow then | |
| 1678 -- parent.arrow:SetVertexColor(0.2, 0.6, 0) | |
| 1679 -- parent.arrow:SetHeight(24) | |
| 1680 -- parent.arrow:SetWidth(24) | |
| 1681 parent.selected = true | |
| 1682 parent.highlight:Show() | |
| 1683 end | |
| 1684 | |
| 1685 sliderFrame:SetClampedToScreen(false) | |
| 1686 if not parent.sliderValue then | |
| 1687 parent.sliderValue = (parent.sliderMin + parent.sliderMax) / 2 | |
| 1688 end | |
| 1689 sliderFrame.slider:SetValue(1 - (parent.sliderValue - parent.sliderMin) / (parent.sliderMax - parent.sliderMin)) | |
| 1690 sliderFrame.changing = false | |
| 1691 sliderFrame.bottomText:SetText(parent.sliderMinText or "0") | |
| 1692 sliderFrame.topText:SetText(parent.sliderMaxText or "1") | |
| 1693 local text | |
| 1694 if parent.sliderFunc then | |
| 1695 local a1,a2,a3,a4 = parent.sliderArg1, parent.sliderArg2, parent.sliderArg3, parent.sliderArg4 | |
| 1696 if a1 == nil then | |
| 1697 text = parent.sliderFunc(parent.sliderValue) | |
| 1698 elseif a2 == nil then | |
| 1699 text = parent.sliderFunc(a1, parent.sliderValue) | |
| 1700 elseif a3 == nil then | |
| 1701 text = parent.sliderFunc(a1, a2, parent.sliderValue) | |
| 1702 elseif a4 == nil then | |
| 1703 text = parent.sliderFunc(a1, a2, a3, parent.sliderValue) | |
| 1704 else | |
| 1705 text = parent.sliderFunc(a1, a2, a3, a4, parent.sliderValue) | |
| 1706 end | |
| 1707 end | |
| 1708 if text then | |
| 1709 sliderFrame.currentText:SetText(text) | |
| 1710 elseif parent.sliderIsPercent then | |
| 1711 sliderFrame.currentText:SetText(string.format("%.0f%%", parent.sliderValue * 100)) | |
| 1712 else | |
| 1713 sliderFrame.currentText:SetText(parent.sliderValue) | |
| 1714 end | |
| 1715 | |
| 1716 sliderFrame.lastValue = parent.sliderValue | |
| 1717 | |
| 1718 local level = parent.level | |
| 1719 sliderFrame:Show() | |
| 1720 sliderFrame:ClearAllPoints() | |
| 1721 if level.lastDirection == "RIGHT" then | |
| 1722 if level.lastVDirection == "DOWN" then | |
| 1723 sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10) | |
| 1724 else | |
| 1725 sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10) | |
| 1726 end | |
| 1727 else | |
| 1728 if level.lastVDirection == "DOWN" then | |
| 1729 sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10) | |
| 1730 else | |
| 1731 sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10) | |
| 1732 end | |
| 1733 end | |
| 1734 local dirty | |
| 1735 if level.lastDirection == "RIGHT" then | |
| 1736 if sliderFrame:GetRight() > GetScreenWidth() then | |
| 1737 level.lastDirection = "LEFT" | |
| 1738 dirty = true | |
| 1739 end | |
| 1740 elseif sliderFrame:GetLeft() < 0 then | |
| 1741 level.lastDirection = "RIGHT" | |
| 1742 dirty = true | |
| 1743 end | |
| 1744 if level.lastVDirection == "DOWN" then | |
| 1745 if sliderFrame:GetBottom() < 0 then | |
| 1746 level.lastVDirection = "UP" | |
| 1747 dirty = true | |
| 1748 end | |
| 1749 elseif sliderFrame:GetTop() > GetScreenWidth() then | |
| 1750 level.lastVDirection = "DOWN" | |
| 1751 dirty = true | |
| 1752 end | |
| 1753 if dirty then | |
| 1754 sliderFrame:ClearAllPoints() | |
| 1755 if level.lastDirection == "RIGHT" then | |
| 1756 if level.lastVDirection == "DOWN" then | |
| 1757 sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10) | |
| 1758 else | |
| 1759 sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10) | |
| 1760 end | |
| 1761 else | |
| 1762 if level.lastVDirection == "DOWN" then | |
| 1763 sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10) | |
| 1764 else | |
| 1765 sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10) | |
| 1766 end | |
| 1767 end | |
| 1768 end | |
| 1769 local left, bottom = sliderFrame:GetLeft(), sliderFrame:GetBottom() | |
| 1770 sliderFrame:ClearAllPoints() | |
| 1771 sliderFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom) | |
| 1772 if mod(level.num, 5) == 0 then | |
| 1773 local left, bottom = level:GetLeft(), level:GetBottom() | |
| 1774 level:ClearAllPoints() | |
| 1775 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom) | |
| 1776 end | |
| 1777 sliderFrame:SetClampedToScreen(true) | |
| 1778 end | |
| 1779 | |
| 1780 function OpenEditBox(self, parent) | |
| 1781 if not editBoxFrame then | |
| 1782 editBoxFrame = CreateFrame("Frame", nil, nil) | |
| 1783 editBoxFrame:SetWidth(200) | |
| 1784 editBoxFrame:SetHeight(40) | |
| 1785 editBoxFrame:SetScale(UIParent:GetScale()) | |
| 1786 editBoxFrame:SetBackdrop(tmp( | |
| 1787 'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background", | |
| 1788 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border", | |
| 1789 'tile', true, | |
| 1790 'insets', tmp2( | |
| 1791 'left', 5, | |
| 1792 'right', 5, | |
| 1793 'top', 5, | |
| 1794 'bottom', 5 | |
| 1795 ), | |
| 1796 'tileSize', 16, | |
| 1797 'edgeSize', 16 | |
| 1798 )) | |
| 1799 editBoxFrame:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 1800 if editBoxFrame.SetTopLevel then | |
| 1801 editBoxFrame:SetTopLevel(true) | |
| 1802 end | |
| 1803 editBoxFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b) | |
| 1804 editBoxFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) | |
| 1805 editBoxFrame:EnableMouse(true) | |
| 1806 editBoxFrame:Hide() | |
| 1807 editBoxFrame:SetPoint("CENTER", UIParent, "CENTER") | |
| 1808 | |
| 1809 local editBox = CreateFrame("EditBox", nil, editBoxFrame) | |
| 1810 editBoxFrame.editBox = editBox | |
| 1811 editBox:SetFontObject(ChatFontNormal) | |
| 1812 editBox:SetWidth(160) | |
| 1813 editBox:SetHeight(13) | |
| 1814 editBox:SetPoint("CENTER", editBoxFrame, "CENTER", 0, 0) | |
| 1815 | |
| 1816 local left = editBox:CreateTexture(nil, "BACKGROUND") | |
| 1817 left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left") | |
| 1818 left:SetTexCoord(0, 100 / 256, 0, 1) | |
| 1819 left:SetWidth(100) | |
| 1820 left:SetHeight(32) | |
| 1821 left:SetPoint("LEFT", editBox, "LEFT", -10, 0) | |
| 1822 local right = editBox:CreateTexture(nil, "BACKGROUND") | |
| 1823 right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right") | |
| 1824 right:SetTexCoord(156/256, 1, 0, 1) | |
| 1825 right:SetWidth(100) | |
| 1826 right:SetHeight(32) | |
| 1827 right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0) | |
| 1828 | |
| 1829 editBox:SetScript("OnEnterPressed", function() | |
| 1830 if editBoxFrame.parent and editBoxFrame.parent.editBoxValidateFunc then | |
| 1831 local a1,a2,a3,a4 = editBoxFrame.parent.editBoxValidateArg1, editBoxFrame.parent.editBoxValidateArg2, editBoxFrame.parent.editBoxValidateArg3, editBoxFrame.parent.editBoxValidateArg4 | |
| 1832 | |
| 1833 local t = editBox.realText or editBox:GetText() or "" | |
| 1834 local result | |
| 1835 if a1 == nil then | |
| 1836 result = editBoxFrame.parent.editBoxValidateFunc(t) | |
| 1837 elseif a2 == nil then | |
| 1838 result = editBoxFrame.parent.editBoxValidateFunc(a1, t) | |
| 1839 elseif a3 == nil then | |
| 1840 result = editBoxFrame.parent.editBoxValidateFunc(a1, a2, t) | |
| 1841 elseif a4 == nil then | |
| 1842 result = editBoxFrame.parent.editBoxValidateFunc(a1, a2, a3, t) | |
| 1843 else | |
| 1844 result = editBoxFrame.parent.editBoxValidateFunc(a1, a2, a3, a4, t) | |
| 1845 end | |
| 1846 if not result then | |
| 1847 UIErrorsFrame:AddMessage(VALIDATION_ERROR, 1, 0, 0) | |
| 1848 return | |
| 1849 end | |
| 1850 end | |
| 1851 if editBoxFrame.parent and editBoxFrame.parent.editBoxFunc then | |
| 1852 local a1,a2,a3,a4 = editBoxFrame.parent.editBoxArg1, editBoxFrame.parent.editBoxArg2, editBoxFrame.parent.editBoxArg3, editBoxFrame.parent.editBoxArg4 | |
| 1853 local t | |
| 1854 if editBox.realText ~= "NONE" then | |
| 1855 t = editBox.realText or editBox:GetText() or "" | |
| 1856 end | |
| 1857 if a1 == nil then | |
| 1858 editBoxFrame.parent.editBoxFunc(t) | |
| 1859 elseif a2 == nil then | |
| 1860 editBoxFrame.parent.editBoxFunc(a1, t) | |
| 1861 elseif a3 == nil then | |
| 1862 editBoxFrame.parent.editBoxFunc(a1, a2, t) | |
| 1863 elseif a4 == nil then | |
| 1864 editBoxFrame.parent.editBoxFunc(a1, a2, a3, t) | |
| 1865 else | |
| 1866 editBoxFrame.parent.editBoxFunc(a1, a2, a3, a4, t) | |
| 1867 end | |
| 1868 end | |
| 1869 self:Close(editBoxFrame.level) | |
| 1870 for i = 1, editBoxFrame.level - 1 do | |
| 1871 Refresh(self, levels[i]) | |
| 1872 end | |
| 1873 end) | |
| 1874 editBox:SetScript("OnEscapePressed", function() | |
| 1875 self:Close(editBoxFrame.level) | |
| 1876 end) | |
| 1877 local changing = false | |
| 1878 local skipNext = false | |
| 1879 | |
| 1880 function editBox:SpecialSetText(text) | |
| 1881 local oldText = editBox:GetText() or "" | |
| 1882 if not text then | |
| 1883 text = "" | |
| 1884 end | |
| 1885 if text ~= oldText then | |
| 1886 changing = true | |
| 1887 self:SetText(text) | |
| 1888 changing = false | |
| 1889 skipNext = true | |
| 1890 end | |
| 1891 end | |
| 1892 | |
| 1893 editBox:SetScript("OnTextChanged", function() | |
| 1894 if skipNext then | |
| 1895 skipNext = false | |
| 1896 elseif not changing and editBoxFrame.parent and editBoxFrame.parent.editBoxChangeFunc then | |
| 1897 local a1,a2,a3,a4 = editBoxFrame.parent.editBoxChangeArg1, editBoxFrame.parent.editBoxChangeArg2, editBoxFrame.parent.editBoxChangeArg3, editBoxFrame.parent.editBoxChangeArg4 | |
| 1898 local t | |
| 1899 if editBox.realText ~= "NONE" then | |
| 1900 t = editBox.realText or editBox:GetText() or "" | |
| 1901 end | |
| 1902 local text | |
| 1903 if a1 == nil then | |
| 1904 text = editBoxFrame.parent.editBoxChangeFunc(t) | |
| 1905 elseif a2 == nil then | |
| 1906 text = editBoxFrame.parent.editBoxChangeFunc(a1, t) | |
| 1907 elseif a3 == nil then | |
| 1908 text = editBoxFrame.parent.editBoxChangeFunc(a1, a2, t) | |
| 1909 elseif a4 == nil then | |
| 1910 text = editBoxFrame.parent.editBoxChangeFunc(a1, a2, a3, t) | |
| 1911 else | |
| 1912 text = editBoxFrame.parent.editBoxChangeFunc(a1, a2, a3, a4, t) | |
| 1913 end | |
| 1914 if text then | |
| 1915 editBox:SpecialSetText(text) | |
| 1916 end | |
| 1917 end | |
| 1918 end) | |
| 1919 editBoxFrame:SetScript("OnEnter", function() | |
| 1920 StopCounting(self, editBoxFrame.level) | |
| 1921 showGameTooltip(editBoxFrame.parent) | |
| 1922 end) | |
| 1923 editBoxFrame:SetScript("OnLeave", function() | |
| 1924 StartCounting(self, editBoxFrame.level) | |
| 1925 GameTooltip:Hide() | |
| 1926 end) | |
| 1927 editBox:SetScript("OnEnter", function() | |
| 1928 StopCounting(self, editBoxFrame.level) | |
| 1929 showGameTooltip(editBoxFrame.parent) | |
| 1930 end) | |
| 1931 editBox:SetScript("OnLeave", function() | |
| 1932 StartCounting(self, editBoxFrame.level) | |
| 1933 GameTooltip:Hide() | |
| 1934 end) | |
| 1935 editBoxFrame:SetScript("OnKeyDown", function() | |
| 1936 if not editBox.keybinding then | |
| 1937 return | |
| 1938 end | |
| 1939 local arg1 = arg1 | |
| 1940 local screenshotKey = GetBindingKey("SCREENSHOT") | |
| 1941 if screenshotKey and arg1 == screenshotKey then | |
| 1942 Screenshot() | |
| 1943 return | |
| 1944 end | |
| 1945 | |
| 1946 if arg1 == "LeftButton" then | |
| 1947 arg1 = "BUTTON1" | |
| 1948 elseif arg1 == "RightButton" then | |
| 1949 arg1 = "BUTTON2" | |
| 1950 elseif arg1 == "MiddleButton" then | |
| 1951 arg1 = "BUTTON3" | |
| 1952 elseif arg1 == "Button4" then | |
| 1953 arg1 = "BUTTON4" | |
| 1954 elseif arg1 == "Button5" then | |
| 1955 arg1 = "BUTTON5" | |
| 1956 end | |
| 1957 if arg1 == "BUTTON1" or arg1 == "BUTTON2" or arg1 == "UNKNOWN" then | |
| 1958 return | |
| 1959 elseif arg1 == "SHIFT" or arg1 == "CTRL" or arg1 == "ALT" then | |
| 1960 return | |
| 1961 elseif arg1 == "ENTER" then | |
| 1962 return editBox:GetScript("OnEnterPressed")() | |
| 1963 elseif arg1 == "ESCAPE" then | |
| 1964 if editBox.realText == "NONE" then | |
| 1965 return editBox:GetScript("OnEscapePressed")() | |
| 1966 else | |
| 1967 editBox:SpecialSetText(NONE or "NONE") | |
| 1968 editBox.realText = "NONE" | |
| 1969 return | |
| 1970 end | |
| 1971 end | |
| 1972 local s = GetBindingText(arg1, "KEY_") | |
| 1973 local real = arg1 | |
| 1974 if IsShiftKeyDown() then | |
| 1975 s = "SHIFT-" .. s | |
| 1976 real = "SHIFT-" .. real | |
| 1977 end | |
| 1978 if IsControlKeyDown() then | |
| 1979 s = "CTRL-" .. s | |
| 1980 real = "CTRL-" .. real | |
| 1981 end | |
| 1982 if IsAltKeyDown() then | |
| 1983 s = "ALT-" .. s | |
| 1984 real = "ALT-" .. real | |
| 1985 end | |
| 1986 if editBox:GetText() ~= s then | |
| 1987 editBox:SpecialSetText(s) | |
| 1988 editBox.realText = real | |
| 1989 return editBox:GetScript("OnTextChanged")() | |
| 1990 end | |
| 1991 end) | |
| 1992 editBoxFrame:SetScript("OnMouseDown", editBoxFrame:GetScript("OnKeyDown")) | |
| 1993 editBox:SetScript("OnMouseDown", editBoxFrame:GetScript("OnKeyDown")) | |
| 1994 end | |
| 1995 editBoxFrame.parent = parent | |
| 1996 editBoxFrame.level = parent.level.num + 1 | |
| 1997 editBoxFrame.parentValue = parent.level.value | |
| 1998 editBoxFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3) | |
| 1999 editBoxFrame.editBox:SetFrameLevel(editBoxFrame:GetFrameLevel() + 1) | |
| 2000 editBoxFrame.editBox.realText = nil | |
| 2001 editBoxFrame:SetClampedToScreen(false) | |
| 2002 | |
| 2003 if parent.editBoxIsKeybinding then | |
| 2004 local s = parent.editBoxText | |
| 2005 editBoxFrame.editBox.realText = s | |
| 2006 if s and s ~= "" then | |
| 2007 local alpha,bravo = s:match("^(.+)%-(.+)$") | |
| 2008 if not bravo then | |
| 2009 alpha = nil | |
| 2010 bravo = s | |
| 2011 end | |
| 2012 bravo = GetBindingText(bravo, "KEY_") | |
| 2013 if alpha then | |
| 2014 editBoxFrame.editBox:SpecialSetText(alpha:upper() .. "-" .. bravo) | |
| 2015 else | |
| 2016 editBoxFrame.editBox:SpecialSetText(bravo) | |
| 2017 end | |
| 2018 else | |
| 2019 editBoxFrame.editBox:SpecialSetText(NONE or "NONE") | |
| 2020 end | |
| 2021 else | |
| 2022 editBoxFrame.editBox:SpecialSetText(parent.editBoxText) | |
| 2023 end | |
| 2024 | |
| 2025 editBoxFrame.editBox.keybinding = parent.editBoxIsKeybinding | |
| 2026 editBoxFrame.editBox:EnableKeyboard(not parent.editBoxIsKeybinding) | |
| 2027 editBoxFrame:EnableKeyboard(parent.editBoxIsKeybinding) | |
| 2028 | |
| 2029 if parent.arrow then | |
| 2030 -- parent.arrow:SetVertexColor(0.2, 0.6, 0) | |
| 2031 -- parent.arrow:SetHeight(24) | |
| 2032 -- parent.arrow:SetWidth(24) | |
| 2033 parent.selected = true | |
| 2034 parent.highlight:Show() | |
| 2035 end | |
| 2036 | |
| 2037 local level = parent.level | |
| 2038 editBoxFrame:Show() | |
| 2039 editBoxFrame:ClearAllPoints() | |
| 2040 if level.lastDirection == "RIGHT" then | |
| 2041 if level.lastVDirection == "DOWN" then | |
| 2042 editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10) | |
| 2043 else | |
| 2044 editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10) | |
| 2045 end | |
| 2046 else | |
| 2047 if level.lastVDirection == "DOWN" then | |
| 2048 editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10) | |
| 2049 else | |
| 2050 editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10) | |
| 2051 end | |
| 2052 end | |
| 2053 local dirty | |
| 2054 if level.lastDirection == "RIGHT" then | |
| 2055 if editBoxFrame:GetRight() > GetScreenWidth() then | |
| 2056 level.lastDirection = "LEFT" | |
| 2057 dirty = true | |
| 2058 end | |
| 2059 elseif editBoxFrame:GetLeft() < 0 then | |
| 2060 level.lastDirection = "RIGHT" | |
| 2061 dirty = true | |
| 2062 end | |
| 2063 if level.lastVDirection == "DOWN" then | |
| 2064 if editBoxFrame:GetBottom() < 0 then | |
| 2065 level.lastVDirection = "UP" | |
| 2066 dirty = true | |
| 2067 end | |
| 2068 elseif editBoxFrame:GetTop() > GetScreenWidth() then | |
| 2069 level.lastVDirection = "DOWN" | |
| 2070 dirty = true | |
| 2071 end | |
| 2072 if dirty then | |
| 2073 editBoxFrame:ClearAllPoints() | |
| 2074 if level.lastDirection == "RIGHT" then | |
| 2075 if level.lastVDirection == "DOWN" then | |
| 2076 editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10) | |
| 2077 else | |
| 2078 editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10) | |
| 2079 end | |
| 2080 else | |
| 2081 if level.lastVDirection == "DOWN" then | |
| 2082 editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10) | |
| 2083 else | |
| 2084 editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10) | |
| 2085 end | |
| 2086 end | |
| 2087 end | |
| 2088 local left, bottom = editBoxFrame:GetLeft(), editBoxFrame:GetBottom() | |
| 2089 editBoxFrame:ClearAllPoints() | |
| 2090 editBoxFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom) | |
| 2091 if mod(level.num, 5) == 0 then | |
| 2092 local left, bottom = level:GetLeft(), level:GetBottom() | |
| 2093 level:ClearAllPoints() | |
| 2094 level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom) | |
| 2095 end | |
| 2096 editBoxFrame:SetClampedToScreen(true) | |
| 2097 end | |
| 2098 | |
| 2099 function Dewdrop:IsOpen(parent) | |
| 2100 self:argCheck(parent, 2, "table", "nil") | |
| 2101 return levels[1] and levels[1]:IsShown() and (not parent or parent == levels[1].parent or parent == levels[1]:GetParent()) | |
| 2102 end | |
| 2103 | |
| 2104 function Dewdrop:GetOpenedParent() | |
| 2105 return (levels[1] and levels[1]:IsShown()) and (levels[1].parent or levels[1]:GetParent()) | |
| 2106 end | |
| 2107 | |
| 2108 function Open(self, parent, func, level, value, point, relativePoint, cursorX, cursorY) | |
| 2109 self:Close(level) | |
| 2110 if DewdropLib then | |
| 2111 local d = DewdropLib:GetInstance('1.0') | |
| 2112 local ret, val = pcall(d, IsOpen, d) | |
| 2113 if ret and val then | |
| 2114 DewdropLib:GetInstance('1.0'):Close() | |
| 2115 end | |
| 2116 end | |
| 2117 parent:GetCenter() | |
| 2118 local frame = AcquireLevel(self, level) | |
| 2119 if level == 1 then | |
| 2120 frame.lastDirection = "RIGHT" | |
| 2121 frame.lastVDirection = "DOWN" | |
| 2122 else | |
| 2123 frame.lastDirection = levels[level - 1].lastDirection | |
| 2124 frame.lastVDirection = levels[level - 1].lastVDirection | |
| 2125 end | |
| 2126 frame:SetClampedToScreen(false) | |
| 2127 frame:SetFrameStrata("FULLSCREEN_DIALOG") | |
| 2128 frame:ClearAllPoints() | |
| 2129 frame.parent = parent | |
| 2130 frame:SetPoint("LEFT", UIParent, "RIGHT", 10000, 0) | |
| 2131 frame:Show() | |
| 2132 if level == 1 then | |
| 2133 baseFunc = func | |
| 2134 end | |
| 2135 levels[level].value = value | |
| 2136 -- levels[level].parentText = parent.text and parent.text:GetText() or nil | |
| 2137 -- levels[level].parentTooltipTitle = parent.tooltipTitle | |
| 2138 -- levels[level].parentTooltipText = parent.tooltipText | |
| 2139 -- levels[level].parentTooltipFunc = parent.tooltipFunc | |
| 2140 if parent.arrow then | |
| 2141 -- parent.arrow:SetVertexColor(0.2, 0.6, 0) | |
| 2142 -- parent.arrow:SetHeight(24) | |
| 2143 -- parent.arrow:SetWidth(24) | |
| 2144 parent.selected = true | |
| 2145 parent.highlight:Show() | |
| 2146 end | |
| 2147 relativePoint = relativePoint or point | |
| 2148 Refresh(self, levels[level]) | |
| 2149 if point or (cursorX and cursorY) then | |
| 2150 frame:ClearAllPoints() | |
| 2151 if cursorX and cursorY then | |
| 2152 local curX, curY = GetScaledCursorPosition() | |
| 2153 if curY < GetScreenHeight() / 2 then | |
| 2154 point, relativePoint = "BOTTOM", "BOTTOM" | |
| 2155 else | |
| 2156 point, relativePoint = "TOP", "TOP" | |
| 2157 end | |
| 2158 if curX < GetScreenWidth() / 2 then | |
| 2159 point, relativePoint = point .. "LEFT", relativePoint .. "RIGHT" | |
| 2160 else | |
| 2161 point, relativePoint = point .. "RIGHT", relativePoint .. "LEFT" | |
| 2162 end | |
| 2163 end | |
| 2164 frame:SetPoint(point, parent, relativePoint) | |
| 2165 if cursorX and cursorY then | |
| 2166 local left = frame:GetLeft() | |
| 2167 local width = frame:GetWidth() | |
| 2168 local bottom = frame:GetBottom() | |
| 2169 local height = frame:GetHeight() | |
| 2170 local curX, curY = GetScaledCursorPosition() | |
| 2171 frame:ClearAllPoints() | |
| 2172 relativePoint = relativePoint or point | |
| 2173 if point == "BOTTOM" or point == "TOP" then | |
| 2174 if curX < GetScreenWidth() / 2 then | |
| 2175 point = point .. "LEFT" | |
| 2176 else | |
| 2177 point = point .. "RIGHT" | |
| 2178 end | |
| 2179 elseif point == "CENTER" then | |
| 2180 if curX < GetScreenWidth() / 2 then | |
| 2181 point = "LEFT" | |
| 2182 else | |
| 2183 point = "RIGHT" | |
| 2184 end | |
| 2185 end | |
| 2186 local xOffset, yOffset = 0, 0 | |
| 2187 if curY > GetScreenHeight() / 2 then | |
| 2188 yOffset = -height | |
| 2189 end | |
| 2190 if curX > GetScreenWidth() / 2 then | |
| 2191 xOffset = -width | |
| 2192 end | |
| 2193 frame:SetPoint(point, parent, relativePoint, curX - left + xOffset, curY - bottom + yOffset) | |
| 2194 if level == 1 then | |
| 2195 frame.lastDirection = "RIGHT" | |
| 2196 end | |
| 2197 elseif cursorX then | |
| 2198 local left = frame:GetLeft() | |
| 2199 local width = frame:GetWidth() | |
| 2200 local curX, curY = GetScaledCursorPosition() | |
| 2201 frame:ClearAllPoints() | |
| 2202 relativePoint = relativePoint or point | |
| 2203 if point == "BOTTOM" or point == "TOP" then | |
| 2204 if curX < GetScreenWidth() / 2 then | |
| 2205 point = point .. "LEFT" | |
| 2206 else | |
| 2207 point = point .. "RIGHT" | |
| 2208 end | |
| 2209 elseif point == "CENTER" then | |
| 2210 if curX < GetScreenWidth() / 2 then | |
| 2211 point = "LEFT" | |
| 2212 else | |
| 2213 point = "RIGHT" | |
| 2214 end | |
| 2215 end | |
| 2216 frame:SetPoint(point, parent, relativePoint, curX - left - width / 2, 0) | |
| 2217 if level == 1 then | |
| 2218 frame.lastDirection = "RIGHT" | |
| 2219 end | |
| 2220 elseif cursorY then | |
| 2221 local bottom = frame:GetBottom() | |
| 2222 local height = frame:GetHeight() | |
| 2223 local curX, curY = GetScaledCursorPosition() | |
| 2224 frame:ClearAllPoints() | |
| 2225 relativePoint = relativePoint or point | |
| 2226 if point == "LEFT" or point == "RIGHT" then | |
| 2227 if curX < GetScreenHeight() / 2 then | |
| 2228 point = point .. "BOTTOM" | |
| 2229 else | |
| 2230 point = point .. "TOP" | |
| 2231 end | |
| 2232 elseif point == "CENTER" then | |
| 2233 if curX < GetScreenHeight() / 2 then | |
| 2234 point = "BOTTOM" | |
| 2235 else | |
| 2236 point = "TOP" | |
| 2237 end | |
| 2238 end | |
| 2239 frame:SetPoint(point, parent, relativePoint, 0, curY - bottom - height / 2) | |
| 2240 if level == 1 then | |
| 2241 frame.lastDirection = "DOWN" | |
| 2242 end | |
| 2243 end | |
| 2244 if (strsub(point, 1, 3) ~= strsub(relativePoint, 1, 3)) then | |
| 2245 if frame:GetBottom() < 0 then | |
| 2246 local point, parent, relativePoint, x, y = frame:GetPoint(1) | |
| 2247 local change = GetScreenHeight() - frame:GetTop() | |
| 2248 local otherChange = -frame:GetBottom() | |
| 2249 if otherChange < change then | |
| 2250 change = otherChange | |
| 2251 end | |
| 2252 frame:SetPoint(point, parent, relativePoint, x, y + change) | |
| 2253 elseif frame:GetTop() > GetScreenHeight() then | |
| 2254 local point, parent, relativePoint, x, y = frame:GetPoint(1) | |
| 2255 local change = GetScreenHeight() - frame:GetTop() | |
| 2256 local otherChange = -frame:GetBottom() | |
| 2257 if otherChange < change then | |
| 2258 change = otherChange | |
| 2259 end | |
| 2260 frame:SetPoint(point, parent, relativePoint, x, y + change) | |
| 2261 end | |
| 2262 end | |
| 2263 end | |
| 2264 CheckDualMonitor(self, frame) | |
| 2265 frame:SetClampedToScreen(true) | |
| 2266 StartCounting(self, level) | |
| 2267 end | |
| 2268 | |
| 2269 function Dewdrop:IsRegistered(parent) | |
| 2270 self:argCheck(parent, 2, "table") | |
| 2271 return not not self.registry[parent] | |
| 2272 end | |
| 2273 | |
| 2274 function Dewdrop:Register(parent, ...) | |
| 2275 self:argCheck(parent, 2, "table") | |
| 2276 if self.registry[parent] then | |
| 2277 self:Unregister(parent) | |
| 2278 end | |
| 2279 local info = new(...) | |
| 2280 if type(info.children) == "table" then | |
| 2281 local err, position = validateOptions(info.children) | |
| 2282 | |
| 2283 if err then | |
| 2284 if position then | |
| 2285 Dewdrop:error(position .. ": " .. err) | |
| 2286 else | |
| 2287 Dewdrop:error(err) | |
| 2288 end | |
| 2289 end | |
| 2290 end | |
| 2291 self.registry[parent] = info | |
| 2292 if not info.dontHook and not self.onceRegistered[parent] then | |
| 2293 if parent:HasScript("OnMouseUp") then | |
| 2294 local script = parent:GetScript("OnMouseUp") | |
| 2295 parent:SetScript("OnMouseUp", function() | |
| 2296 if script then | |
| 2297 script() | |
| 2298 end | |
| 2299 if arg1 == "RightButton" and self.registry[parent] then | |
| 2300 if self:IsOpen(parent) then | |
| 2301 self:Close() | |
| 2302 else | |
| 2303 self:Open(parent) | |
| 2304 end | |
| 2305 end | |
| 2306 end) | |
| 2307 end | |
| 2308 if parent:HasScript("OnMouseDown") then | |
| 2309 local script = parent:GetScript("OnMouseDown") | |
| 2310 parent:SetScript("OnMouseDown", function() | |
| 2311 if script then | |
| 2312 script() | |
| 2313 end | |
| 2314 if self.registry[parent] then | |
| 2315 self:Close() | |
| 2316 end | |
| 2317 end) | |
| 2318 end | |
| 2319 end | |
| 2320 self.onceRegistered[parent] = true | |
| 2321 end | |
| 2322 | |
| 2323 function Dewdrop:Unregister(parent) | |
| 2324 self:argCheck(parent, 2, "table") | |
| 2325 self.registry[parent] = nil | |
| 2326 end | |
| 2327 | |
| 2328 function Dewdrop:Open(parent, ...) | |
| 2329 self:argCheck(parent, 2, "table") | |
| 2330 local info | |
| 2331 local k1 = ... | |
| 2332 if type(k1) == "table" and k1[0] and k1.IsFrameType and self.registry[k1] then | |
| 2333 info = tmp() | |
| 2334 for k,v in pairs(self.registry[k1]) do | |
| 2335 info[k] = v | |
| 2336 end | |
| 2337 else | |
| 2338 info = tmp(...) | |
| 2339 if self.registry[parent] then | |
| 2340 for k,v in pairs(self.registry[parent]) do | |
| 2341 if info[k] == nil then | |
| 2342 info[k] = v | |
| 2343 end | |
| 2344 end | |
| 2345 end | |
| 2346 end | |
| 2347 local point = info.point | |
| 2348 local relativePoint = info.relativePoint | |
| 2349 local cursorX = info.cursorX | |
| 2350 local cursorY = info.cursorY | |
| 2351 if type(point) == "function" then | |
| 2352 local b | |
| 2353 point, b = point(parent) | |
| 2354 if b then | |
| 2355 relativePoint = b | |
| 2356 end | |
| 2357 end | |
| 2358 if type(relativePoint) == "function" then | |
| 2359 relativePoint = relativePoint(parent) | |
| 2360 end | |
| 2361 Open(self, parent, info.children, 1, nil, point, relativePoint, cursorX, cursorY) | |
| 2362 end | |
| 2363 | |
| 2364 function Clear(self, level) | |
| 2365 if level then | |
| 2366 if level.buttons then | |
| 2367 for i = #level.buttons, 1, -1 do | |
| 2368 ReleaseButton(self, level, i) | |
| 2369 end | |
| 2370 end | |
| 2371 end | |
| 2372 end | |
| 2373 | |
| 2374 function Dewdrop:Close(level) | |
| 2375 if DropDownList1:IsShown() then | |
| 2376 DropDownList1:Hide() | |
| 2377 end | |
| 2378 if DewdropLib then | |
| 2379 local d = DewdropLib:GetInstance('1.0') | |
| 2380 local ret, val = pcall(d, IsOpen, d) | |
| 2381 if ret and val then | |
| 2382 DewdropLib:GetInstance('1.0'):Close() | |
| 2383 end | |
| 2384 end | |
| 2385 self:argCheck(level, 2, "number", "nil") | |
| 2386 if not level then | |
| 2387 level = 1 | |
| 2388 end | |
| 2389 if level == 1 and levels[level] then | |
| 2390 levels[level].parented = false | |
| 2391 end | |
| 2392 if level > 1 and levels[level-1].buttons then | |
| 2393 local buttons = levels[level-1].buttons | |
| 2394 for _,button in ipairs(buttons) do | |
| 2395 -- button.arrow:SetWidth(16) | |
| 2396 -- button.arrow:SetHeight(16) | |
| 2397 button.selected = nil | |
| 2398 button.highlight:Hide() | |
| 2399 -- button.arrow:SetVertexColor(1, 1, 1) | |
| 2400 end | |
| 2401 end | |
| 2402 if sliderFrame and sliderFrame.level >= level then | |
| 2403 sliderFrame:Hide() | |
| 2404 end | |
| 2405 if editBoxFrame and editBoxFrame.level >= level then | |
| 2406 editBoxFrame:Hide() | |
| 2407 end | |
| 2408 for i = level, #levels do | |
| 2409 Clear(self, levels[level]) | |
| 2410 levels[i]:Hide() | |
| 2411 levels[i]:ClearAllPoints() | |
| 2412 levels[i]:SetPoint("CENTER", UIParent, "CENTER") | |
| 2413 levels[i].value = nil | |
| 2414 end | |
| 2415 end | |
| 2416 | |
| 2417 function Dewdrop:AddLine(...) | |
| 2418 local info = tmp(...) | |
| 2419 local level = info.level or currentLevel | |
| 2420 info.level = nil | |
| 2421 local button = AcquireButton(self, level) | |
| 2422 if not next(info) then | |
| 2423 info.disabled = true | |
| 2424 end | |
| 2425 button.disabled = info.isTitle or info.notClickable or info.disabled | |
| 2426 button.isTitle = info.isTitle | |
| 2427 button.notClickable = info.notClickable | |
| 2428 if button.isTitle then | |
| 2429 button.text:SetFontObject(GameFontNormalSmall) | |
| 2430 elseif button.notClickable then | |
| 2431 button.text:SetFontObject(GameFontHighlightSmall) | |
| 2432 elseif button.disabled then | |
| 2433 button.text:SetFontObject(GameFontDisableSmall) | |
| 2434 else | |
| 2435 button.text:SetFontObject(GameFontHighlightSmall) | |
| 2436 end | |
| 2437 if info.disabled then | |
| 2438 button.arrow:SetDesaturated(true) | |
| 2439 button.check:SetDesaturated(true) | |
| 2440 else | |
| 2441 button.arrow:SetDesaturated(false) | |
| 2442 button.check:SetDesaturated(false) | |
| 2443 end | |
| 2444 if info.textR and info.textG and info.textB then | |
| 2445 button.textR = info.textR | |
| 2446 button.textG = info.textG | |
| 2447 button.textB = info.textB | |
| 2448 button.text:SetTextColor(button.textR, button.textG, button.textB) | |
| 2449 else | |
| 2450 button.text:SetTextColor(button.text:GetFontObject():GetTextColor()) | |
| 2451 end | |
| 2452 button.notCheckable = info.notCheckable | |
| 2453 button.text:SetPoint("LEFT", button, "LEFT", button.notCheckable and 0 or 24, 0) | |
| 2454 button.checked = not info.notCheckable and info.checked | |
| 2455 button.isRadio = not info.notCheckable and info.isRadio | |
| 2456 if info.isRadio then | |
| 2457 button.check:Show() | |
| 2458 button.check:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton") | |
| 2459 if button.checked then | |
| 2460 button.check:SetTexCoord(0.25, 0.5, 0, 1) | |
| 2461 button.check:SetVertexColor(1, 1, 1, 1) | |
| 2462 else | |
| 2463 button.check:SetTexCoord(0, 0.25, 0, 1) | |
| 2464 button.check:SetVertexColor(1, 1, 1, 0.5) | |
| 2465 end | |
| 2466 button.radioHighlight:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton") | |
| 2467 button.check:SetWidth(16) | |
| 2468 button.check:SetHeight(16) | |
| 2469 elseif info.icon then | |
| 2470 button.check:Show() | |
| 2471 button.check:SetTexture(info.icon) | |
| 2472 if info.iconWidth and info.iconHeight then | |
| 2473 button.check:SetWidth(info.iconWidth) | |
| 2474 button.check:SetHeight(info.iconHeight) | |
| 2475 else | |
| 2476 button.check:SetWidth(16) | |
| 2477 button.check:SetHeight(16) | |
| 2478 end | |
| 2479 if info.iconCoordLeft and info.iconCoordRight and info.iconCoordTop and info.iconCoordBottom then | |
| 2480 button.check:SetTexCoord(info.iconCoordLeft, info.iconCoordRight, info.iconCoordTop, info.iconCoordBottom) | |
| 2481 elseif info.icon:find("^Interface\\Icons\\") then | |
| 2482 button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95) | |
| 2483 else | |
| 2484 button.check:SetTexCoord(0, 1, 0, 1) | |
| 2485 end | |
| 2486 button.check:SetVertexColor(1, 1, 1, 1) | |
| 2487 else | |
| 2488 if button.checked then | |
| 2489 if info.checkIcon then | |
| 2490 button.check:SetWidth(16) | |
| 2491 button.check:SetHeight(16) | |
| 2492 button.check:SetTexture(info.checkIcon) | |
| 2493 if info.checkIcon:find("^Interface\\Icons\\") then | |
| 2494 button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95) | |
| 2495 else | |
| 2496 button.check:SetTexCoord(0, 1, 0, 1) | |
| 2497 end | |
| 2498 else | |
| 2499 button.check:SetWidth(24) | |
| 2500 button.check:SetHeight(24) | |
| 2501 button.check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") | |
| 2502 button.check:SetTexCoord(0, 1, 0, 1) | |
| 2503 end | |
| 2504 button.check:SetVertexColor(1, 1, 1, 1) | |
| 2505 else | |
| 2506 button.check:SetVertexColor(1, 1, 1, 0) | |
| 2507 end | |
| 2508 end | |
| 2509 if not button.disabled then | |
| 2510 button.func = info.func | |
| 2511 end | |
| 2512 button.hasColorSwatch = info.hasColorSwatch | |
| 2513 if button.hasColorSwatch then | |
| 2514 button.colorSwatch:Show() | |
| 2515 button.colorSwatch.texture:Show() | |
| 2516 button.r = info.r or 1 | |
| 2517 button.g = info.g or 1 | |
| 2518 button.b = info.b or 1 | |
| 2519 button.colorSwatch.texture:SetTexture(button.r, button.g, button.b) | |
| 2520 button.checked = false | |
| 2521 button.func = nil | |
| 2522 button.colorFunc = info.colorFunc | |
| 2523 button.colorArg1 = info.colorArg1 | |
| 2524 button.colorArg2 = info.colorArg2 | |
| 2525 button.colorArg3 = info.colorArg3 | |
| 2526 button.colorArg4 = info.colorArg4 | |
| 2527 button.hasOpacity = info.hasOpacity | |
| 2528 button.opacity = info.opacity or 1 | |
| 2529 else | |
| 2530 button.colorSwatch:Hide() | |
| 2531 button.colorSwatch.texture:Hide() | |
| 2532 end | |
| 2533 button.hasArrow = not button.hasColorSwatch and (info.value or info.hasSlider or info.hasEditBox) and info.hasArrow | |
| 2534 if button.hasArrow then | |
| 2535 button.arrow:SetAlpha(1) | |
| 2536 if info.hasSlider then | |
| 2537 button.hasSlider = true | |
| 2538 button.sliderMin = info.sliderMin or 0 | |
| 2539 button.sliderMax = info.sliderMax or 1 | |
| 2540 button.sliderStep = info.sliderStep or 0 | |
| 2541 button.sliderIsPercent = info.sliderIsPercent and true or false | |
| 2542 button.sliderMinText = info.sliderMinText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMin * 100) or button.sliderMin | |
| 2543 button.sliderMaxText = info.sliderMaxText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMax * 100) or button.sliderMax | |
| 2544 button.sliderFunc = info.sliderFunc | |
| 2545 button.sliderValue = info.sliderValue | |
| 2546 button.sliderArg1 = info.sliderArg1 | |
| 2547 button.sliderArg2 = info.sliderArg2 | |
| 2548 button.sliderArg3 = info.sliderArg3 | |
| 2549 button.sliderArg4 = info.sliderArg4 | |
| 2550 elseif info.hasEditBox then | |
| 2551 button.hasEditBox = true | |
| 2552 button.editBoxText = info.editBoxText or "" | |
| 2553 button.editBoxFunc = info.editBoxFunc | |
| 2554 button.editBoxArg1 = info.editBoxArg1 | |
| 2555 button.editBoxArg2 = info.editBoxArg2 | |
| 2556 button.editBoxArg3 = info.editBoxArg3 | |
| 2557 button.editBoxArg4 = info.editBoxArg4 | |
| 2558 button.editBoxChangeFunc = info.editBoxChangeFunc | |
| 2559 button.editBoxChangeArg1 = info.editBoxChangeArg1 | |
| 2560 button.editBoxChangeArg2 = info.editBoxChangeArg2 | |
| 2561 button.editBoxChangeArg3 = info.editBoxChangeArg3 | |
| 2562 button.editBoxChangeArg4 = info.editBoxChangeArg4 | |
| 2563 button.editBoxValidateFunc = info.editBoxValidateFunc | |
| 2564 button.editBoxValidateArg1 = info.editBoxValidateArg1 | |
| 2565 button.editBoxValidateArg2 = info.editBoxValidateArg2 | |
| 2566 button.editBoxValidateArg3 = info.editBoxValidateArg3 | |
| 2567 button.editBoxValidateArg4 = info.editBoxValidateArg4 | |
| 2568 button.editBoxIsKeybinding = info.editBoxIsKeybinding | |
| 2569 else | |
| 2570 button.value = info.value | |
| 2571 local l = levels[level+1] | |
| 2572 if l and info.value == l.value then | |
| 2573 -- button.arrow:SetWidth(24) | |
| 2574 -- button.arrow:SetHeight(24) | |
| 2575 button.selected = true | |
| 2576 button.highlight:Show() | |
| 2577 end | |
| 2578 end | |
| 2579 else | |
| 2580 button.arrow:SetAlpha(0) | |
| 2581 end | |
| 2582 button.arg1 = info.arg1 | |
| 2583 button.arg2 = info.arg2 | |
| 2584 button.arg3 = info.arg3 | |
| 2585 button.arg4 = info.arg4 | |
| 2586 button.closeWhenClicked = info.closeWhenClicked | |
| 2587 button.textHeight = info.textHeight or UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT or 10 | |
| 2588 local font,_ = button.text:GetFont() | |
| 2589 button.text:SetFont(STANDARD_TEXT_FONT or "Fonts\\FRIZQT__.TTF", button.textHeight) | |
| 2590 button:SetHeight(button.textHeight + 6) | |
| 2591 button.text:SetPoint("RIGHT", button.arrow, (button.hasColorSwatch or button.hasArrow) and "LEFT" or "RIGHT") | |
| 2592 button.text:SetJustifyH(info.justifyH or "LEFT") | |
| 2593 button.text:SetText(info.text) | |
| 2594 button.tooltipTitle = info.tooltipTitle | |
| 2595 button.tooltipText = info.tooltipText | |
| 2596 button.tooltipFunc = info.tooltipFunc | |
| 2597 button.tooltipArg1 = info.tooltipArg1 | |
| 2598 button.tooltipArg2 = info.tooltipArg2 | |
| 2599 button.tooltipArg3 = info.tooltipArg3 | |
| 2600 button.tooltipArg4 = info.tooltipArg4 | |
| 2601 if not button.tooltipTitle and not button.tooltipText and not button.tooltipFunc and not info.isTitle then | |
| 2602 button.tooltipTitle = info.text | |
| 2603 end | |
| 2604 if type(button.func) == "string" then | |
| 2605 self:assert(type(button.arg1) == "table", "Cannot call method " .. button.func .. " on a non-table") | |
| 2606 self:assert(type(button.arg1[button.func]) == "function", "Method " .. button.func .. " nonexistant.") | |
| 2607 end | |
| 2608 end | |
| 2609 | |
| 2610 function Dewdrop:InjectAceOptionsTable(handler, options) | |
| 2611 self:argCheck(handler, 2, "table") | |
| 2612 self:argCheck(options, 3, "table") | |
| 2613 if tostring(options.type):lower() ~= "group" then | |
| 2614 self:error('Cannot inject into options table argument #3 if its type is not "group"') | |
| 2615 end | |
| 2616 if options.handler ~= nil and options.handler ~= handler then | |
| 2617 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2") | |
| 2618 end | |
| 2619 options.handler = handler | |
| 2620 local class = handler.class | |
| 2621 if not AceLibrary:HasInstance("AceOO-2.0") or not class then | |
| 2622 self:error("Cannot retrieve AceOptions tables from a non-object argument #2") | |
| 2623 end | |
| 2624 while class and class ~= AceLibrary("AceOO-2.0").Class do | |
| 2625 if type(class.GetAceOptionsDataTable) == "function" then | |
| 2626 local t = class:GetAceOptionsDataTable(handler) | |
| 2627 for k,v in pairs(t) do | |
| 2628 if type(options.args) ~= "table" then | |
| 2629 options.args = {} | |
| 2630 end | |
| 2631 if options.args[k] == nil then | |
| 2632 options.args[k] = v | |
| 2633 end | |
| 2634 end | |
| 2635 end | |
| 2636 local mixins = class.mixins | |
| 2637 if mixins then | |
| 2638 for mixin in pairs(mixins) do | |
| 2639 if type(mixin.GetAceOptionsDataTable) == "function" then | |
| 2640 local t = mixin:GetAceOptionsDataTable(handler) | |
| 2641 for k,v in pairs(t) do | |
| 2642 if type(options.args) ~= "table" then | |
| 2643 options.args = {} | |
| 2644 end | |
| 2645 if options.args[k] == nil then | |
| 2646 options.args[k] = v | |
| 2647 end | |
| 2648 end | |
| 2649 end | |
| 2650 end | |
| 2651 end | |
| 2652 class = class.super | |
| 2653 end | |
| 2654 return options | |
| 2655 end | |
| 2656 | |
| 2657 local function activate(self, oldLib, oldDeactivate) | |
| 2658 Dewdrop = self | |
| 2659 if oldLib and oldLib.registry then | |
| 2660 self.registry = oldLib.registry | |
| 2661 self.onceRegistered = oldLib.onceRegistered | |
| 2662 else | |
| 2663 self.registry = {} | |
| 2664 self.onceRegistered = {} | |
| 2665 | |
| 2666 local WorldFrame_OnMouseDown = WorldFrame:GetScript("OnMouseDown") | |
| 2667 local WorldFrame_OnMouseUp = WorldFrame:GetScript("OnMouseUp") | |
| 2668 local oldX, oldY, clickTime | |
| 2669 WorldFrame:SetScript("OnMouseDown", function() | |
| 2670 oldX,oldY = GetCursorPosition() | |
| 2671 clickTime = GetTime() | |
| 2672 if WorldFrame_OnMouseDown then | |
| 2673 WorldFrame_OnMouseDown() | |
| 2674 end | |
| 2675 end) | |
| 2676 | |
| 2677 WorldFrame:SetScript("OnMouseUp", function() | |
| 2678 local x,y = GetCursorPosition() | |
| 2679 if not oldX or not oldY or not x or not y or not clickTime then | |
| 2680 self:Close() | |
| 2681 if WorldFrame_OnMouseUp then | |
| 2682 WorldFrame_OnMouseUp() | |
| 2683 end | |
| 2684 return | |
| 2685 end | |
| 2686 local d = math.abs(x - oldX) + math.abs(y - oldY) | |
| 2687 if d <= 5 and GetTime() - clickTime < 0.5 then | |
| 2688 self:Close() | |
| 2689 end | |
| 2690 if WorldFrame_OnMouseUp then | |
| 2691 WorldFrame_OnMouseUp() | |
| 2692 end | |
| 2693 end) | |
| 2694 | |
| 2695 if hooksecurefunc then | |
| 2696 hooksecurefunc(DropDownList1, "Show", function() | |
| 2697 if levels[1] and levels[1]:IsVisible() then | |
| 2698 self:Close() | |
| 2699 end | |
| 2700 end) | |
| 2701 else | |
| 2702 local DropDownList1_Show = DropDownList1.Show | |
| 2703 function DropDownList1.Show(DropDownList1) | |
| 2704 if levels[1] and levels[1]:IsVisible() then | |
| 2705 self:Close() | |
| 2706 end | |
| 2707 DropDownList1_Show(DropDownList1) | |
| 2708 end | |
| 2709 end | |
| 2710 | |
| 2711 if hooksecurefunc then | |
| 2712 hooksecurefunc("HideDropDownMenu", function() | |
| 2713 if levels[1] and levels[1]:IsVisible() then | |
| 2714 self:Close() | |
| 2715 end | |
| 2716 end) | |
| 2717 else | |
| 2718 local old_HideDropDownMenu = HideDropDownMenu | |
| 2719 function HideDropDownMenu(num) | |
| 2720 if levels[1] and levels[1]:IsVisible() then | |
| 2721 self:Close() | |
| 2722 end | |
| 2723 old_HideDropDownMenu(num) | |
| 2724 end | |
| 2725 end | |
| 2726 | |
| 2727 if hooksecurefunc then | |
| 2728 hooksecurefunc("CloseDropDownMenus", function() | |
| 2729 if levels[1] and levels[1]:IsVisible() then | |
| 2730 self:Close() | |
| 2731 end | |
| 2732 end) | |
| 2733 else | |
| 2734 local old_CloseDropDownMenus = CloseDropDownMenus | |
| 2735 function CloseDropDownMenus(num) | |
| 2736 if levels[1] and levels[1]:IsVisible() then | |
| 2737 self:Close() | |
| 2738 end | |
| 2739 old_CloseDropDownMenus(num) | |
| 2740 end | |
| 2741 end | |
| 2742 end | |
| 2743 levels = {} | |
| 2744 buttons = {} | |
| 2745 | |
| 2746 if oldDeactivate then | |
| 2747 oldDeactivate(oldLib) | |
| 2748 end | |
| 2749 end | |
| 2750 | |
| 2751 AceLibrary:Register(Dewdrop, MAJOR_VERSION, MINOR_VERSION, activate) |
