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