V3.1.7

His Dad [12-12-14 - 20:34]
V3.1.7
Update LAM to 2.0r16
Filename
AIResearchGrid.lua
AIResearchGrid.txt
AIresearchGridConfig.lua
Libs/LAM2/LibAddonMenu-2.0.lua
Libs/LAM2/controls/button.lua
Libs/LAM2/controls/checkbox.lua
Libs/LAM2/controls/colorpicker.lua
Libs/LAM2/controls/custom.lua
Libs/LAM2/controls/description.lua
Libs/LAM2/controls/dropdown.lua
Libs/LAM2/controls/editbox.lua
Libs/LAM2/controls/header.lua
Libs/LAM2/controls/panel.lua
Libs/LAM2/controls/slider.lua
Libs/LAM2/controls/submenu.lua
Libs/LAM2/controls/texture.lua
doc/changelog.txt
diff --git a/AIResearchGrid.lua b/AIResearchGrid.lua
index d1d0a04..18fc55e 100644
--- a/AIResearchGrid.lua
+++ b/AIResearchGrid.lua
@@ -7,7 +7,7 @@ local _
 AIRG = {}

 AIRG.name = "AIResearchGrid"
-AIRG.version = "3.1.5"
+AIRG.version = "3.1.7"
 AIRG.initialised = false
 AIRG.processing = false
 AIRG.all = " #ALL"  -- Default displayname for Virtual character, overrwritten by Localised version
@@ -161,8 +161,11 @@ function AIRG.initUI()
                      end
                      AIRG.OnCraftSelected() --redisplay
          end)
-    AIRG.UI.btnUpdateOther:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-    AIRG.UI.btnUpdateOther:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+  --  The following have caused bugs to be reported, that I can't duplicate. As there is no tooltip text, disable it entirely.
+  --  AIRG.UI.btnUpdateOther:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+  --  AIRG.UI.btnUpdateOther:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+
     AIRG.UI.btnUpdateOther:SetMouseEnabled(true)
   --
     -- PEOPLE ICON NEXT TO THE DROPDOWN BOX.
diff --git a/AIResearchGrid.txt b/AIResearchGrid.txt
index 24bcbc7..462c4c8 100644
--- a/AIResearchGrid.txt
+++ b/AIResearchGrid.txt
@@ -1,24 +1,24 @@
-## Title: |cFFFFB0Research Grid|r v3.1 by |c00C000CrazyDutchGuy|r and His Dad
-## APIVersion: 100010
-## Version: @project-version@
-## Author: Stormknight, CrazyDutchGuy &  His Dad
-## OptionalDependsOn: LibAddonMenu-2.0
-## SavedVariables: AIRG_SavedVariables
-## Description: Allows you to quickly and easily see which traits your characters have researched for Blacksmithing, Clothing & Woodworking, wherever you are in the world.
-
-Libs/LibStub/LibStub.lua
-Libs/LAM2/LibAddonMenu-2.0.lua
-Libs/LAM2/controls/panel.lua
-Libs\LAM2/controls/header.lua
-Libs\LAM2/controls/checkbox.lua
-Libs\LAM2/controls/dropdown.lua
-Libs\LAM2/controls/button.lua
-Libs\LAM2/controls/description.lua
-
-AIResearchGrid.lua
-AIResearchGridConfig.lua
-AIResearchGrid.xml
-Bindings.xml
-
-Language/en.lua
-Language/$(language).lua
+## Title: |cFFFFB0Research Grid|r v3.1.7
+## APIVersion: 100010
+## Version: @project-version@
+## Author: Stormknight and Team
+## OptionalDependsOn: LibAddonMenu-2.0
+## SavedVariables: AIRG_SavedVariables
+## Description: Allows you to quickly and easily see which traits your characters have researched for Blacksmithing, Clothing & Woodworking, wherever you are in the world.
+
+Libs/LibStub/LibStub.lua
+Libs/LAM2/LibAddonMenu-2.0.lua
+Libs/LAM2/controls/panel.lua
+Libs\LAM2/controls/header.lua
+Libs\LAM2/controls/checkbox.lua
+Libs\LAM2/controls/dropdown.lua
+Libs\LAM2/controls/button.lua
+Libs\LAM2/controls/description.lua
+
+AIResearchGrid.lua
+AIResearchGridConfig.lua
+AIResearchGrid.xml
+Bindings.xml
+
+Language/en.lua
+Language/$(language).lua
diff --git a/AIresearchGridConfig.lua b/AIresearchGridConfig.lua
index 549fadc..8c3f864 100644
--- a/AIresearchGridConfig.lua
+++ b/AIresearchGridConfig.lua
@@ -1,67 +1,67 @@
-function AIRG.CreateConfigMenu()
-    local charList = {}
-    table.insert(charList,"")
-    for charName, _ in pairs(AIRG.vars.data) do
-        table.insert(charList, charName)
-    end
-
-    local panelData = {
-        type = "panel",
-        name = "AI Research Grid",
-        displayName = "|c8080FFAI Research Grid|r",
-        author = "Stormknight & CrazyDutchGuy",
-        version = tostring(AIRG.version),
-    }
-
-    local optionsData = {
-    -- GENERAL SECTION
-        {
-            type = "header",
-            name = AIRG.L["General Options"],
-        },
-        {
-            type = "checkbox",
-            name = AIRG.L["Show Motifs"],
-            tooltip = AIRG.L["Show Motifs Long"],
-            getFunc = function() return AIRG.vars.showMotifs end,
-            setFunc = function(newValue)
-                    AIRG.vars.showMotifs = newValue
-                    AIRG.UI.motifSection:SetHidden(not newValue)
-                    AIRG.UI.BottomDivider:SetHidden(not newValue)
-                    AIResearchGrid:SetHeight(newValue and 706 or 636)
-                end,
-        },
-        -- CHARACTER DELETION SECTION
-        {
-            type = "header",
-            name = AIRG.L["Characters"],
-        },
-        {
-            type = "dropdown",
-            name = AIRG.L["CharacterSelect"],
-            choices = charList,
-            getFunc = function() return "" end,
-            setFunc = function(newValue) AIRG.charToDelete = newValue	end,
-        },
-        {
-            type = "button",
-            name = AIRG.L["Delete"],
-            tooltip = AIRG.L["DeleteDesc"],
-            func = function() AIRG.DeleteCharacter(AIRG.charToDelete) end,
-        },
-        -- KEYBINDS SECTION
-        {
-            type = "header",
-            name = AIRG.L["Keybinds"],
-        },
-        {
-            type = "description",
-            text = AIRG.L["Keybind Text"],
-        },
-    }
-
-    local LAM2 = LibStub("LibAddonMenu-2.0")
-    LAM2:RegisterAddonPanel(AIRG.name.."Config", panelData)
-    LAM2:RegisterOptionControls(AIRG.name.."Config", optionsData)
-
-end -- AIRG.CreateConfigMenu
+function AIRG.CreateConfigMenu()
+    local charList = {}
+    table.insert(charList,"")
+    for charName, _ in pairs(AIRG.vars.data) do
+        table.insert(charList, charName)
+    end
+
+    local panelData = {
+        type = "panel",
+        name = "AI Research Grid",
+        displayName = "|c8080FFAI Research Grid|r",
+        author = "Stormknight, CrazyDutchGuy and His Dad",
+        version = tostring(AIRG.version),
+    }
+
+    local optionsData = {
+    -- GENERAL SECTION
+        {
+            type = "header",
+            name = AIRG.L["General Options"],
+        },
+        {
+            type = "checkbox",
+            name = AIRG.L["Show Motifs"],
+            tooltip = AIRG.L["Show Motifs Long"],
+            getFunc = function() return AIRG.vars.showMotifs end,
+            setFunc = function(newValue)
+                    AIRG.vars.showMotifs = newValue
+                    AIRG.UI.motifSection:SetHidden(not newValue)
+                    AIRG.UI.BottomDivider:SetHidden(not newValue)
+                    AIResearchGrid:SetHeight(newValue and 706 or 636)
+                end,
+        },
+        -- CHARACTER DELETION SECTION
+        {
+            type = "header",
+            name = AIRG.L["Characters"],
+        },
+        {
+            type = "dropdown",
+            name = AIRG.L["CharacterSelect"],
+            choices = charList,
+            getFunc = function() return "" end,
+            setFunc = function(newValue) AIRG.charToDelete = newValue	end,
+        },
+        {
+            type = "button",
+            name = AIRG.L["Delete"],
+            tooltip = AIRG.L["DeleteDesc"],
+            func = function() AIRG.DeleteCharacter(AIRG.charToDelete) end,
+        },
+        -- KEYBINDS SECTION
+        {
+            type = "header",
+            name = AIRG.L["Keybinds"],
+        },
+        {
+            type = "description",
+            text = AIRG.L["Keybind Text"],
+        },
+    }
+
+    local LAM2 = LibStub("LibAddonMenu-2.0")
+    LAM2:RegisterAddonPanel(AIRG.name.."Config", panelData)
+    LAM2:RegisterOptionControls(AIRG.name.."Config", optionsData)
+
+end -- AIRG.CreateConfigMenu
diff --git a/Libs/LAM2/LibAddonMenu-2.0.lua b/Libs/LAM2/LibAddonMenu-2.0.lua
index a58bf03..05f0670 100644
--- a/Libs/LAM2/LibAddonMenu-2.0.lua
+++ b/Libs/LAM2/LibAddonMenu-2.0.lua
@@ -1,309 +1,322 @@
---	LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah)	--
---	All Rights Reserved										--
---	Permission is granted to use Seerah's LibAddonMenu-2.0	--
---	in your project. Any modifications to LibAddonMenu-2.0	--
---	may not be redistributed.								--
---------------------------------------------------------------
-
-
---Register LAM with LibStub
-local MAJOR, MINOR = "LibAddonMenu-2.0", 14
-local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
-if not lam then return end	--the same or newer version of this lib is already loaded into memory
-
-
---UPVALUES--
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
-local optionsWindow = ZO_OptionsWindowSettingsScrollChild
-local _
-
-local addonsForList = {}
-local addonToOptionsMap = {}
-local optionsCreated = {}
-lam.widgets = lam.widgets or {}
-local widgets = lam.widgets
-
-
---METHOD: REGISTER WIDGET--
---each widget has its version checked before loading,
---so we only have the most recent one in memory
---Usage:
---	widgetType = "string"; the type of widget being registered
---	widgetVersion = integer; the widget's version number
-LAMCreateControl = LAMCreateControl or {}
-local lamcc = LAMCreateControl
-
-function lam:RegisterWidget(widgetType, widgetVersion)
-	if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
-		return false
-	else
-		widgets[widgetType] = widgetVersion
-		return true
-	end
-end
-
-
---METHOD: OPEN TO ADDON PANEL--
---opens to a specific addon's option panel
---Usage:
---	panel = userdata; the panel returned by the :RegisterOptionsPanel method
---local settings = {en = "Settings", de = "Einstellungen", fr = "Réglages"}
---local locSettings = settings[GetCVar("Language.2")]
-local locSettings = GetString(SI_GAME_MENU_SETTINGS)
-function lam:OpenToPanel(panel)
-	SCENE_MANAGER:Show("gameMenuInGame")
-	zo_callLater(function()
-			ZO_GameMenu_InGame.gameMenu.headerControls[locSettings]:SetOpen(true)
-			SCENE_MANAGER:AddFragment(OPTIONS_WINDOW_FRAGMENT)
-			ZO_OptionsWindow_ChangePanels(lam.panelID)
-			if not lam.panelSubCategoryControl then
-				lam.panelSubCategoryControl = _G["ZO_GameMenu_InGameNavigationContainerScrollChildZO_GameMenu_SubCategory"..(lam.panelID + 1)]
-			end
-			ZO_TreeEntry_OnMouseUp(lam.panelSubCategoryControl, true)
-			panel:SetHidden(false)
-		end, 200)
-end
-
-
---INTERNAL FUNCTION
---creates controls when options panel is first shown
---controls anchoring of these controls in the panel
-local function CreateOptionsControls(panel)
-	local addonID = panel:GetName()
-	local optionsTable = addonToOptionsMap[addonID]
-
-	if optionsTable then
-		local lastAddedControl, lacAtHalfRow
-		for _, widgetData in ipairs(optionsTable) do
-			local widgetType = widgetData.type
-			if widgetType == "submenu" then
-				local submenu = LAMCreateControl[widgetType](panel, widgetData)
-				if lastAddedControl then
-					submenu:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
-				else
-					submenu:SetAnchor(TOPLEFT)
-				end
-				lastAddedControl = submenu
-				lacAtHalfRow = false
-
-				local lastAddedControlSub, lacAtHalfRowSub
-				for _, subWidgetData in ipairs(widgetData.controls) do
-					local subWidgetType = subWidgetData.type
-					local subWidget = LAMCreateControl[subWidgetType](submenu, subWidgetData)
-					local isHalf = subWidgetData.width == "half"
-					if lastAddedControlSub then
-						if lacAtHalfRowSub and isHalf then
-							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, TOPRIGHT, 5, 0)
-							lacAtHalfRowSub = false
-						else
-							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, BOTTOMLEFT, 0, 15)
-							lacAtHalfRowSub = isHalf and true or false
-							lastAddedControlSub = subWidget
-						end
-					else
-						subWidget:SetAnchor(TOPLEFT)
-						lacAtHalfRowSub = isHalf and true or false
-						lastAddedControlSub = subWidget
-					end
-				end
-			else
-				local widget = LAMCreateControl[widgetType](panel, widgetData)
-				local isHalf = widgetData.width == "half"
-				if lastAddedControl then
-					if lacAtHalfRow and isHalf then
-						widget:SetAnchor(TOPLEFT, lastAddedControl, TOPRIGHT, 10, 0)
-						lacAtHalfRow = false
-					else
-						widget:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
-						lacAtHalfRow = isHalf and true or false
-						lastAddedControl = widget
-					end
-				else
-					widget:SetAnchor(TOPLEFT)
-					lacAtHalfRow = isHalf and true or false
-					lastAddedControl = widget
-				end
-			end
-		end
-	end
-
-	optionsCreated[addonID] = true
-	cm:FireCallbacks("LAM-PanelControlsCreated", panel)
-end
-
-
---INTERNAL FUNCTION
---handles switching between panels
-local function ToggleAddonPanels(panel)	--called in OnShow of newly shown panel
-	local currentlySelected = LAMAddonPanelsMenu.currentlySelected
-	if currentlySelected and currentlySelected ~= panel then
-		currentlySelected:SetHidden(true)
-	end
-	LAMAddonPanelsMenu.currentlySelected = panel
-
-	if not optionsCreated[panel:GetName()] then	--if this is the first time opening this panel, create these options
-		CreateOptionsControls(panel)
-	end
-
-	cm:FireCallbacks("LAM-RefreshPanel", panel)
-end
-
-
---METHOD: REGISTER ADDON PANEL
---registers your addon with LibAddonMenu and creates a panel
---Usage:
---	addonID = "string"; unique ID which will be the global name of your panel
---	panelData = table; data object for your panel - see controls\panel.lua
-function lam:RegisterAddonPanel(addonID, panelData)
-	local panel = lamcc.panel(nil, panelData, addonID)	--addonID==global name of panel
-	panel:SetHidden(true)
-	panel:SetAnchor(TOPLEFT, LAMAddonPanelsMenu, TOPRIGHT, 10, 0)
-	panel:SetAnchor(BOTTOMLEFT, LAMAddonPanelsMenu, BOTTOMRIGHT, 10, 0)
-	panel:SetWidth(549)
-	panel:SetDrawLayer(DL_OVERLAY)
-	tinsert(addonsForList, {panel = addonID, name = panelData.name})
-	panel:SetHandler("OnShow", ToggleAddonPanels)
-	if panelData.slashCommand then
-		SLASH_COMMANDS[panelData.slashCommand] = function()
-			lam:OpenToPanel(panel)
-		end
-	end
-
-	return panel	--return for authors creating options manually
-end
-
-
---METHOD: REGISTER OPTION CONTROLS
---registers the options you want shown for your addon
---these are stored in a table where each key-value pair is the order
---of the options in the panel and the data for that control, respectively
---see exampleoptions.lua for an example
---see controls\<widget>.lua for each widget type
---Usage:
---	addonID = "string"; the same string passed to :RegisterAddonPanel
---	optionsTable = table; the table containing all of the options controls and their data
-function lam:RegisterOptionControls(addonID, optionsTable)	--optionsTable = {sliderData, buttonData, etc}
-	addonToOptionsMap[addonID] = optionsTable
-end
-
-
---INTERNAL FUNCTION
---handles switching between LAM's Addon Settings panel and other panels in the Settings menu
-local oldDefaultButton = ZO_OptionsWindowResetToDefaultButton
-local oldCallback = oldDefaultButton.callback
-local dummyFunc = function() end
-local panelWindow = ZO_OptionsWindow
-local bgL = ZO_OptionsWindowBGLeft
-local bgR = ZO_OptionsWindowBGLeftBGRight
-local function HandlePanelSwitching(panel)
-	if panel == lam.panelID then	--our addon settings panel
-		oldDefaultButton:SetCallback(dummyFunc)
-		oldDefaultButton:SetHidden(true)
-		oldDefaultButton:SetAlpha(0)	--just because it still bugs out
-		panelWindow:SetDimensions(999, 960)
-		bgL:SetWidth(666)
-		bgR:SetWidth(333)
-	else
-		local shown = LAMAddonPanelsMenu.currentlySelected
-		if shown then shown:SetHidden(true) end
-		oldDefaultButton:SetCallback(oldCallback)
-		oldDefaultButton:SetHidden(false)
-		oldDefaultButton:SetAlpha(1)
-		panelWindow:SetDimensions(768, 914)
-		bgL:SetWidth(512)
-		bgR:SetWidth(256)
-	end
-end
-
-
---INTERNAL FUNCTION
---creates LAM's Addon Settings panel
-local function CreateAddonSettingsPanel()
-	if not LAMSettingsPanelCreated then
-		local controlPanelID = "LAM_ADDON_SETTINGS_PANEL"
-		--Russian for TERAB1T's RuESO addon, which creates an "ru" locale
-		--game font does not support Cyrillic, so they are using custom fonts + extended latin charset
-		local controlPanelNames = {en = "Addon Settings", fr = "Extensions", de = "Erweiterungen", ru = "Îacòpoéêè äoïoìîeîèé"}
-
-		ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelNames[GetCVar("Language.2")] or controlPanelName["en"])
-
-		lam.panelID = _G[controlPanelID]
-
-		ZO_PreHook("ZO_OptionsWindow_ChangePanels", HandlePanelSwitching)
-
-		LAMSettingsPanelCreated = true
-	end
-end
-
-
---INTERNAL FUNCTION
---adds each registered addon to the menu in LAM's panel
-local function CreateAddonButtons(list, addons)
-	for i = 1, #addons do
-		local button = wm:CreateControlFromVirtual("LAMAddonMenuButton"..i, list.scrollChild, "ZO_DefaultTextButton")
-		button.name = addons[i].name
-		button.panel = _G[addons[i].panel]
-		button:SetText(button.name)
-		button:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
-		button:SetWidth(190)
-		if i == 1 then
-			button:SetAnchor(TOPLEFT, list.scrollChild, TOPLEFT, 5, 5)
-		else
-			button:SetAnchor(TOPLEFT, _G["LAMAddonMenuButton"..i-1], BOTTOMLEFT)
-		end
-		button:SetHandler("OnClicked", function(self) self.panel:SetHidden(false) end)
-	end
-end
-
-
---INTERNAL FUNCTION
---creates the left-hand menu in LAM's panel
-local function CreateAddonList()
-	local list
-	--check if an earlier loaded copy of LAM created it already
-	list = LAMAddonPanelsMenu or wm:CreateControlFromVirtual("LAMAddonPanelsMenu", optionsWindow, "ZO_ScrollContainer")
-	list:ClearAnchors()
-	list:SetAnchor(TOPLEFT)
-	list:SetHeight(675)
-	list:SetWidth(200)
-
-	list.bg = list.bg or wm:CreateControl(nil, list, CT_BACKDROP)
-	local bg = list.bg
-	bg:SetAnchorFill()	--offsets of 8?
-	bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16)
-	bg:SetCenterColor(0, 0, 0, 0)
-
-	list.scrollChild = LAMAddonPanelsMenuScrollChild
-	list.scrollChild:SetResizeToFitPadding(0, 15)
-
-	local generatedButtons
-	list:SetHandler("OnShow", function(self)
-			if not generatedButtons and #addonsForList > 0 then
-				--we're about to show our list for the first time - let's sort the buttons before creating them
-				table.sort(addonsForList, function(a, b)
-						return a.name < b.name
-					end)
-				CreateAddonButtons(list, addonsForList)
-				self.currentlySelected = LAMAddonMenuButton1 and LAMAddonMenuButton1.panel
-				--since our addon panels don't have a parent, let's make sure they hide when we're done with them
-				ZO_PreHookHandler(ZO_OptionsWindow, "OnHide", function() self.currentlySelected:SetHidden(true) end)
-				generatedButtons = true
-			end
-			if self.currentlySelected then self.currentlySelected:SetHidden(false) end
-		end)
-
-	list.controlType = OPTIONS_CUSTOM
-	list.panel = lam.panelID
-
-	ZO_OptionsWindow_InitializeControl(list)
-
-	return list
-end
-
-
---INITIALIZING
-CreateAddonSettingsPanel()
-CreateAddonList()
-
+--	LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah)	--
+--	All Rights Reserved										--
+--	Permission is granted to use Seerah's LibAddonMenu-2.0	--
+--	in your project. Any modifications to LibAddonMenu-2.0	--
+--	may not be redistributed.								--
+--------------------------------------------------------------
+
+
+--Register LAM with LibStub
+local MAJOR, MINOR = "LibAddonMenu-2.0", 16
+local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lam then return end	--the same or newer version of this lib is already loaded into memory
+
+
+--UPVALUES--
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+local optionsWindow = ZO_OptionsWindowSettingsScrollChild
+local _
+
+local addonsForList = {}
+local addonToOptionsMap = {}
+local optionsCreated = {}
+lam.widgets = lam.widgets or {}
+local widgets = lam.widgets
+
+
+--METHOD: REGISTER WIDGET--
+--each widget has its version checked before loading,
+--so we only have the most recent one in memory
+--Usage:
+--	widgetType = "string"; the type of widget being registered
+--	widgetVersion = integer; the widget's version number
+LAMCreateControl = LAMCreateControl or {}
+local lamcc = LAMCreateControl
+
+function lam:RegisterWidget(widgetType, widgetVersion)
+	if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
+		return false
+	else
+		widgets[widgetType] = widgetVersion
+		return true
+	end
+end
+
+
+--METHOD: OPEN TO ADDON PANEL--
+--opens to a specific addon's option panel
+--Usage:
+--	panel = userdata; the panel returned by the :RegisterOptionsPanel method
+--local settings = {en = "Settings", de = "Einstellungen", fr = "Réglages"}
+--local locSettings = settings[GetCVar("Language.2")]
+local locSettings = GetString(SI_GAME_MENU_SETTINGS)
+function lam:OpenToPanel(panel)
+	SCENE_MANAGER:Show("gameMenuInGame")
+	zo_callLater(function()
+			ZO_GameMenu_InGame.gameMenu.headerControls[locSettings]:SetOpen(true)
+			SCENE_MANAGER:AddFragment(OPTIONS_WINDOW_FRAGMENT)
+			--ZO_OptionsWindow_ChangePanels(lam.panelID)
+			KEYBOARD_OPTIONS:ChangePanels(lam.panelID)
+			--if not lam.panelSubCategoryControl then
+			--	lam.panelSubCategoryControl = _G["ZO_GameMenu_InGameNavigationContainerScrollChildZO_GameMenu_SubCategory"..(lam.panelID + 1)]
+			--end
+			--ZO_TreeEntry_OnMouseUp(lam.panelSubCategoryControl, true)
+			panel:SetHidden(false)
+		end, 200)
+end
+
+
+--INTERNAL FUNCTION
+--creates controls when options panel is first shown
+--controls anchoring of these controls in the panel
+local function CreateOptionsControls(panel)
+	local addonID = panel:GetName()
+	local optionsTable = addonToOptionsMap[addonID]
+
+	if optionsTable then
+		local lastAddedControl, lacAtHalfRow
+		for _, widgetData in ipairs(optionsTable) do
+			local widgetType = widgetData.type
+			if widgetType == "submenu" then
+				local submenu = LAMCreateControl[widgetType](panel, widgetData)
+				if lastAddedControl then
+					submenu:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
+				else
+					submenu:SetAnchor(TOPLEFT)
+				end
+				lastAddedControl = submenu
+				lacAtHalfRow = false
+
+				local lastAddedControlSub, lacAtHalfRowSub
+				for _, subWidgetData in ipairs(widgetData.controls) do
+					local subWidgetType = subWidgetData.type
+					local subWidget = LAMCreateControl[subWidgetType](submenu, subWidgetData)
+					local isHalf = subWidgetData.width == "half"
+					if lastAddedControlSub then
+						if lacAtHalfRowSub and isHalf then
+							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, TOPRIGHT, 5, 0)
+							lacAtHalfRowSub = false
+						else
+							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, BOTTOMLEFT, 0, 15)
+							lacAtHalfRowSub = isHalf and true or false
+							lastAddedControlSub = subWidget
+						end
+					else
+						subWidget:SetAnchor(TOPLEFT)
+						lacAtHalfRowSub = isHalf and true or false
+						lastAddedControlSub = subWidget
+					end
+				end
+			else
+				local widget = LAMCreateControl[widgetType](panel, widgetData)
+				local isHalf = widgetData.width == "half"
+				if lastAddedControl then
+					if lacAtHalfRow and isHalf then
+						widget:SetAnchor(TOPLEFT, lastAddedControl, TOPRIGHT, 10, 0)
+						lacAtHalfRow = false
+					else
+						widget:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
+						lacAtHalfRow = isHalf and true or false
+						lastAddedControl = widget
+					end
+				else
+					widget:SetAnchor(TOPLEFT)
+					lacAtHalfRow = isHalf and true or false
+					lastAddedControl = widget
+				end
+			end
+		end
+	end
+
+	optionsCreated[addonID] = true
+	cm:FireCallbacks("LAM-PanelControlsCreated", panel)
+end
+
+
+--INTERNAL FUNCTION
+--handles switching between panels
+local function ToggleAddonPanels(panel)	--called in OnShow of newly shown panel
+	local currentlySelected = LAMAddonPanelsMenu.currentlySelected
+	if currentlySelected and currentlySelected ~= panel then
+		currentlySelected:SetHidden(true)
+	end
+	LAMAddonPanelsMenu.currentlySelected = panel
+
+	if not optionsCreated[panel:GetName()] then	--if this is the first time opening this panel, create these options
+		CreateOptionsControls(panel)
+	end
+
+	cm:FireCallbacks("LAM-RefreshPanel", panel)
+end
+
+
+--METHOD: REGISTER ADDON PANEL
+--registers your addon with LibAddonMenu and creates a panel
+--Usage:
+--	addonID = "string"; unique ID which will be the global name of your panel
+--	panelData = table; data object for your panel - see controls\panel.lua
+function lam:RegisterAddonPanel(addonID, panelData)
+	local panel = lamcc.panel(nil, panelData, addonID)	--addonID==global name of panel
+	panel:SetHidden(true)
+	panel:SetAnchor(TOPLEFT, LAMAddonPanelsMenu, TOPRIGHT, 10, 0)
+	panel:SetAnchor(BOTTOMLEFT, LAMAddonPanelsMenu, BOTTOMRIGHT, 10, 0)
+	panel:SetWidth(549)
+	panel:SetDrawLayer(DL_OVERLAY)
+	tinsert(addonsForList, {panel = addonID, name = panelData.name})
+	panel:SetHandler("OnShow", ToggleAddonPanels)
+	if panelData.slashCommand then
+		SLASH_COMMANDS[panelData.slashCommand] = function()
+			lam:OpenToPanel(panel)
+		end
+	end
+
+	return panel	--return for authors creating options manually
+end
+
+
+--METHOD: REGISTER OPTION CONTROLS
+--registers the options you want shown for your addon
+--these are stored in a table where each key-value pair is the order
+--of the options in the panel and the data for that control, respectively
+--see exampleoptions.lua for an example
+--see controls\<widget>.lua for each widget type
+--Usage:
+--	addonID = "string"; the same string passed to :RegisterAddonPanel
+--	optionsTable = table; the table containing all of the options controls and their data
+function lam:RegisterOptionControls(addonID, optionsTable)	--optionsTable = {sliderData, buttonData, etc}
+	addonToOptionsMap[addonID] = optionsTable
+end
+
+
+--INTERNAL FUNCTION
+--handles switching between LAM's Addon Settings panel and other panels in the Settings menu
+local oldDefaultButton = ZO_OptionsWindowResetToDefaultButton
+local oldCallback = oldDefaultButton.callback
+local dummyFunc = function() end
+local panelWindow = ZO_OptionsWindow
+local bgL = ZO_OptionsWindowBGLeft
+local bgR = ZO_OptionsWindowBGLeftBGRight
+local function HandlePanelSwitching(self, panel)
+	if panel == lam.panelID then	--our addon settings panel
+		oldDefaultButton:SetCallback(dummyFunc)
+		oldDefaultButton:SetHidden(true)
+		oldDefaultButton:SetAlpha(0)	--just because it still bugs out
+		panelWindow:SetDimensions(999, 960)
+		bgL:SetWidth(666)
+		bgR:SetWidth(333)
+	else
+		local shown = LAMAddonPanelsMenu.currentlySelected
+		if shown then shown:SetHidden(true) end
+		oldDefaultButton:SetCallback(oldCallback)
+		oldDefaultButton:SetHidden(false)
+		oldDefaultButton:SetAlpha(1)
+		panelWindow:SetDimensions(768, 914)
+		bgL:SetWidth(512)
+		bgR:SetWidth(256)
+	end
+end
+
+
+--INTERNAL FUNCTION
+--creates LAM's Addon Settings panel
+local function CreateAddonSettingsPanel()
+	if not LAMSettingsPanelCreated then
+		local controlPanelID = "LAM_ADDON_SETTINGS_PANEL"
+		--Russian for TERAB1T's RuESO addon, which creates an "ru" locale
+		--game font does not support Cyrillic, so they are using custom fonts + extended latin charset
+		--Spanish provided by Luisen75 for their translation project
+		local controlPanelNames = {
+			en = "Addon Settings",
+			fr = "Extensions",
+			de = "Erweiterungen",
+			ru = "Îacòpoéêè äoïoìîeîèé",
+			es = "Configura Addons",
+		}
+
+		ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelNames[GetCVar("Language.2")] or controlPanelName["en"])
+
+		lam.panelID = _G[controlPanelID]
+
+		--ZO_PreHook("ZO_OptionsWindow_ChangePanels", HandlePanelSwitching)
+		ZO_PreHook(ZO_SharedOptions, "ChangePanels", HandlePanelSwitching)
+
+		LAMSettingsPanelCreated = true
+	end
+end
+
+
+--INTERNAL FUNCTION
+--adds each registered addon to the menu in LAM's panel
+local function CreateAddonButtons(list, addons)
+	for i = 1, #addons do
+		local button = wm:CreateControlFromVirtual("LAMAddonMenuButton"..i, list.scrollChild, "ZO_DefaultTextButton")
+		button.name = addons[i].name
+		button.panel = _G[addons[i].panel]
+		button:SetText(button.name)
+		button:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
+		button:SetWidth(190)
+		if i == 1 then
+			button:SetAnchor(TOPLEFT, list.scrollChild, TOPLEFT, 5, 5)
+		else
+			button:SetAnchor(TOPLEFT, _G["LAMAddonMenuButton"..i-1], BOTTOMLEFT)
+		end
+		button:SetHandler("OnClicked", function(self) self.panel:SetHidden(false) end)
+	end
+end
+
+
+--INTERNAL FUNCTION
+--creates the left-hand menu in LAM's panel
+local function CreateAddonList()
+	local list
+	--check if an earlier loaded copy of LAM created it already
+	list = LAMAddonPanelsMenu or wm:CreateControlFromVirtual("LAMAddonPanelsMenu", optionsWindow, "ZO_ScrollContainer")
+	list:ClearAnchors()
+	list:SetAnchor(TOPLEFT)
+	list:SetHeight(675)
+	list:SetWidth(200)
+
+	list.bg = list.bg or wm:CreateControl(nil, list, CT_BACKDROP)
+	local bg = list.bg
+	bg:SetAnchorFill()	--offsets of 8?
+	bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16)
+	bg:SetCenterColor(0, 0, 0, 0)
+
+	list.scrollChild = LAMAddonPanelsMenuScrollChild
+	list.scrollChild:SetResizeToFitPadding(0, 15)
+
+	local generatedButtons
+	list:SetHandler("OnShow", function(self)
+			if not generatedButtons and #addonsForList > 0 then
+				--we're about to show our list for the first time - let's sort the buttons before creating them
+				table.sort(addonsForList, function(a, b)
+						return a.name < b.name
+					end)
+				CreateAddonButtons(list, addonsForList)
+				self.currentlySelected = LAMAddonMenuButton1 and LAMAddonMenuButton1.panel
+				--since our addon panels don't have a parent, let's make sure they hide when we're done with them
+				ZO_PreHookHandler(ZO_OptionsWindow, "OnHide", function() self.currentlySelected:SetHidden(true) end)
+				generatedButtons = true
+			end
+			if self.currentlySelected then self.currentlySelected:SetHidden(false) end
+		end)
+
+	--list.controlType = OPTIONS_CUSTOM
+	--list.panel = lam.panelID
+	list.data = {
+		controlType = OPTIONS_CUSTOM,
+		panel = lam.panelID,
+	}
+
+	ZO_OptionsWindow_InitializeControl(list)
+
+	return list
+end
+
+
+--INITIALIZING
+CreateAddonSettingsPanel()
+CreateAddonList()
+
diff --git a/Libs/LAM2/controls/button.lua b/Libs/LAM2/controls/button.lua
index 090a812..13387a1 100644
--- a/Libs/LAM2/controls/button.lua
+++ b/Libs/LAM2/controls/button.lua
@@ -1,87 +1,89 @@
---[[buttonData = {
-	type = "button",
-	name = "My Button",
-	tooltip = "Button's tooltip text.",
-	func = function() end,
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	icon = "icon\\path.dds",	--(optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	reference = "MyAddonButton"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 3
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("button", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	control.button:SetEnabled(not disable)
-end
-
-
---controlName is optional
-function LAMCreateControl.button(parent, buttonData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or buttonData.reference)
-	control:SetParent(parent.scroll or parent)
-
-	local isHalfWidth = buttonData.width == "half"
-	control:SetDimensions(isHalfWidth and 250 or 510, isHalfWidth and 55 or 28)
-	control:SetMouseEnabled(true)
-
-	if buttonData.icon then
-		control.button = wm:CreateControl(nil, control, CT_BUTTON)
-		control.button:SetDimensions(26, 26)
-		control.button:SetNormalTexture(buttonData.icon)
-		control.button:SetPressedOffset(2, 2)
-	else
-		--control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton")
-		control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton")
-		control.button:SetWidth(isHalfWidth and 180 or 200)
-		control.button:SetText(buttonData.name)
-	end
-	local button = control.button
-	button:SetAnchor(isHalfWidth and CENTER or RIGHT)
-	button:SetClickSound("Click")
-	button.tooltipText = buttonData.tooltip
-	button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-	button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-	button:SetHandler("OnClicked", function(self, ...)
-			buttonData.func(self, ...)
-			if control.panel.data.registerForRefresh then
-				cm:FireCallbacks("LAM-RefreshPanel", control)
-			end
-		end)
-
-	if buttonData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0)
-		control.warning.tooltipText = buttonData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = buttonData
-
-	if buttonData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-
-		--this is here because buttons don't have an UpdateValue method
-		if control.panel.data.registerForRefresh then	--if our parent window wants to refresh controls, then add this to the list
-			tinsert(control.panel.controlsToRefresh, control)
-		end
-	end
-
-	return control
+--[[buttonData = {
+	type = "button",
+	name = "My Button",
+	tooltip = "Button's tooltip text.",
+	func = function() end,
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	icon = "icon\\path.dds",	--(optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	reference = "MyAddonButton"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 5
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("button", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	control.button:SetEnabled(not disable)
+end
+
+
+--controlName is optional
+function LAMCreateControl.button(parent, buttonData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or buttonData.reference)
+	control:SetParent(parent.scroll or parent)
+
+	local isHalfWidth = buttonData.width == "half"
+	control:SetDimensions(isHalfWidth and 250 or 510, isHalfWidth and 55 or 28)
+	control:SetMouseEnabled(true)
+
+	if buttonData.icon then
+		control.button = wm:CreateControl(nil, control, CT_BUTTON)
+		control.button:SetDimensions(26, 26)
+		control.button:SetNormalTexture(buttonData.icon)
+		control.button:SetPressedOffset(2, 2)
+	else
+		--control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton")
+		control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton")
+		control.button:SetWidth(isHalfWidth and 180 or 200)
+		control.button:SetText(buttonData.name)
+	end
+	local button = control.button
+	button:SetAnchor(isHalfWidth and CENTER or RIGHT)
+	button:SetClickSound("Click")
+	--button.tooltipText = buttonData.tooltip
+	button.data = {tooltipText = buttonData.tooltip}
+	button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+	button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+	button:SetHandler("OnClicked", function(self, ...)
+			buttonData.func(self, ...)
+			if control.panel.data.registerForRefresh then
+				cm:FireCallbacks("LAM-RefreshPanel", control)
+			end
+		end)
+
+	if buttonData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0)
+		--control.warning.tooltipText = buttonData.warning
+		control.warning.data = {tooltipText = buttonData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = buttonData
+
+	if buttonData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+
+		--this is here because buttons don't have an UpdateValue method
+		if control.panel.data.registerForRefresh then	--if our parent window wants to refresh controls, then add this to the list
+			tinsert(control.panel.controlsToRefresh, control)
+		end
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/checkbox.lua b/Libs/LAM2/controls/checkbox.lua
index b178043..14b1638 100644
--- a/Libs/LAM2/controls/checkbox.lua
+++ b/Libs/LAM2/controls/checkbox.lua
@@ -1,170 +1,172 @@
---[[checkboxData = {
-	type = "checkbox",
-	name = "My Checkbox",
-	tooltip = "Checkbox's tooltip text.",
-	getFunc = function() return db.var end,
-	setFunc = function(value) db.var = value doStuff() end,
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	default = defaults.var,	--(optional)
-	reference = "MyAddonCheckbox"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 5
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("checkbox", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
---label
-local enabledColor = ZO_DEFAULT_ENABLED_COLOR
-local enabledHLcolor = ZO_HIGHLIGHT_TEXT
-local disabledColor = ZO_DEFAULT_DISABLED_COLOR
-local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR
---checkbox
-local checkboxColor = ZO_NORMAL_TEXT
-local checkboxHLcolor = ZO_HIGHLIGHT_TEXT
-
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA())
-	control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA())
-	--control:SetMouseEnabled(not disable)
-	--control:SetMouseEnabled(true)
-
-	control.isDisabled = disable
-end
-
-local function ToggleCheckbox(control)
-	if control.value then
-		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-		control.checkbox:SetText(control.checkedText)
-	else
-		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-		control.checkbox:SetText(control.uncheckedText)
-	end
-end
-
-local function UpdateValue(control, forceDefault, value)
-	if forceDefault then	--if we are forcing defaults
-		value = control.data.default
-		control.data.setFunc(value)
-	elseif value ~= nil then	--our value could be false
-		control.data.setFunc(value)
-		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-		if control.panel.data.registerForRefresh then
-			cm:FireCallbacks("LAM-RefreshPanel", control)
-		end
-	else
-		value = control.data.getFunc()
-	end
-	control.value = value
-
-	ToggleCheckbox(control)
-end
-
-local function OnMouseEnter(control)
-	ZO_Options_OnMouseEnter(control)
-
-	if control.isDisabled then return end
-
-	local label = control.label
-	if control.value then
-		label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
-	else
-		label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-	end
-	control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
-end
-
-local function OnMouseExit(control)
-    ZO_Options_OnMouseExit(control)
-
-	if control.isDisabled then return end
-
-	local label = control.label
-	if control.value then
-		label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-	else
-		label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-	end
-	control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
-end
-
-
---controlName is optional
-function LAMCreateControl.checkbox(parent, checkboxData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or checkboxData.reference)
-	control:SetParent(parent.scroll or parent)
-	control:SetMouseEnabled(true)
-	control.tooltipText = checkboxData.tooltip
-	control:SetHandler("OnMouseEnter", OnMouseEnter)
-	control:SetHandler("OnMouseExit", OnMouseExit)
-	control:SetHandler("OnMouseUp", function(control)
-			if control.isDisabled then return end
-			PlaySound(SOUNDS.DEFAULT_CLICK)
-			control.value = not control.value
-			control:UpdateValue(false, control.value)
-		end)
-
-	control.label = wm:CreateControl(nil, control, CT_LABEL)
-	local label = control.label
-	label:SetFont("ZoFontWinH4")
-	label:SetText(checkboxData.name)
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetHeight(26)
-
-	control.checkbox = wm:CreateControl(nil, control, CT_LABEL)
-	local checkbox = control.checkbox
-	checkbox:SetFont("ZoFontGameBold")
-	checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
-	control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper()
-	control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper()
-
-	local isHalfWidth = checkboxData.width == "half"
-	if isHalfWidth then
-		control:SetDimensions(250, 55)
-		checkbox:SetDimensions(100, 26)
-		checkbox:SetAnchor(BOTTOMRIGHT)
-		label:SetAnchor(TOPLEFT)
-		label:SetAnchor(TOPRIGHT)
-	else
-		control:SetDimensions(510, 30)
-		checkbox:SetDimensions(200, 26)
-		checkbox:SetAnchor(RIGHT)
-		label:SetAnchor(LEFT)
-		label:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
-	end
-
-	if checkboxData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
-		control.warning.tooltipText = checkboxData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = checkboxData
-
-	if checkboxData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-	end
-	control.UpdateValue = UpdateValue
-	control:UpdateValue()
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[checkboxData = {
+	type = "checkbox",
+	name = "My Checkbox",
+	tooltip = "Checkbox's tooltip text.",
+	getFunc = function() return db.var end,
+	setFunc = function(value) db.var = value doStuff() end,
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	default = defaults.var,	--(optional)
+	reference = "MyAddonCheckbox"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 7
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("checkbox", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+--label
+local enabledColor = ZO_DEFAULT_ENABLED_COLOR
+local enabledHLcolor = ZO_HIGHLIGHT_TEXT
+local disabledColor = ZO_DEFAULT_DISABLED_COLOR
+local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR
+--checkbox
+local checkboxColor = ZO_NORMAL_TEXT
+local checkboxHLcolor = ZO_HIGHLIGHT_TEXT
+
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA())
+	control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA())
+	--control:SetMouseEnabled(not disable)
+	--control:SetMouseEnabled(true)
+
+	control.isDisabled = disable
+end
+
+local function ToggleCheckbox(control)
+	if control.value then
+		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+		control.checkbox:SetText(control.checkedText)
+	else
+		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+		control.checkbox:SetText(control.uncheckedText)
+	end
+end
+
+local function UpdateValue(control, forceDefault, value)
+	if forceDefault then	--if we are forcing defaults
+		value = control.data.default
+		control.data.setFunc(value)
+	elseif value ~= nil then	--our value could be false
+		control.data.setFunc(value)
+		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+		if control.panel.data.registerForRefresh then
+			cm:FireCallbacks("LAM-RefreshPanel", control)
+		end
+	else
+		value = control.data.getFunc()
+	end
+	control.value = value
+
+	ToggleCheckbox(control)
+end
+
+local function OnMouseEnter(control)
+	ZO_Options_OnMouseEnter(control)
+
+	if control.isDisabled then return end
+
+	local label = control.label
+	if control.value then
+		label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
+	else
+		label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+	end
+	control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
+end
+
+local function OnMouseExit(control)
+    ZO_Options_OnMouseExit(control)
+
+	if control.isDisabled then return end
+
+	local label = control.label
+	if control.value then
+		label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+	else
+		label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+	end
+	control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
+end
+
+
+--controlName is optional
+function LAMCreateControl.checkbox(parent, checkboxData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or checkboxData.reference)
+	control:SetParent(parent.scroll or parent)
+	control:SetMouseEnabled(true)
+	--control.tooltipText = checkboxData.tooltip
+	control:SetHandler("OnMouseEnter", OnMouseEnter)
+	control:SetHandler("OnMouseExit", OnMouseExit)
+	control:SetHandler("OnMouseUp", function(control)
+			if control.isDisabled then return end
+			PlaySound(SOUNDS.DEFAULT_CLICK)
+			control.value = not control.value
+			control:UpdateValue(false, control.value)
+		end)
+
+	control.label = wm:CreateControl(nil, control, CT_LABEL)
+	local label = control.label
+	label:SetFont("ZoFontWinH4")
+	label:SetText(checkboxData.name)
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetHeight(26)
+
+	control.checkbox = wm:CreateControl(nil, control, CT_LABEL)
+	local checkbox = control.checkbox
+	checkbox:SetFont("ZoFontGameBold")
+	checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
+	control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper()
+	control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper()
+
+	local isHalfWidth = checkboxData.width == "half"
+	if isHalfWidth then
+		control:SetDimensions(250, 55)
+		checkbox:SetDimensions(100, 26)
+		checkbox:SetAnchor(BOTTOMRIGHT)
+		label:SetAnchor(TOPLEFT)
+		label:SetAnchor(TOPRIGHT)
+	else
+		control:SetDimensions(510, 30)
+		checkbox:SetDimensions(200, 26)
+		checkbox:SetAnchor(RIGHT)
+		label:SetAnchor(LEFT)
+		label:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
+	end
+
+	if checkboxData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
+		--control.warning.tooltipText = checkboxData.warning
+		control.warning.data = {tooltipText = checkboxData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = checkboxData
+	control.data.tooltipText = checkboxData.tooltip
+
+	if checkboxData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+	end
+	control.UpdateValue = UpdateValue
+	control:UpdateValue()
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/colorpicker.lua b/Libs/LAM2/controls/colorpicker.lua
index 42e8e25..3918030 100644
--- a/Libs/LAM2/controls/colorpicker.lua
+++ b/Libs/LAM2/controls/colorpicker.lua
@@ -1,138 +1,140 @@
---[[colorpickerData = {
-	type = "colorpicker",
-	name = "My Color Picker",
-	tooltip = "Color Picker's tooltip text.",
-	getFunc = function() return db.r, db.g, db.b, db.a end,	--(alpha is optional)
-	setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end,	--(alpha is optional)
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	default = {defaults.r, defaults.g, defaults.b, defaults.a},	--(optional) table of default color values
-	reference = "MyAddonColorpicker"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 3
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
-
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	if disable then
-		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-	else
-		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-	end
-
-	control.isDisabled = disable
-end
-
-local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA)
-	if forceDefault then	--if we are forcing defaults
-		local color = control.data.default
-		valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a
-		control.data.setFunc(valueR, valueG, valueB, valueA)
-	elseif valueR and valueG and valueB then
-		control.data.setFunc(valueR, valueG, valueB, valueA or 1)
-		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-		if control.panel.data.registerForRefresh then
-			cm:FireCallbacks("LAM-RefreshPanel", control)
-		end
-	else
-		valueR, valueG, valueB, valueA = control.data.getFunc()
-	end
-
-	control.thumb:SetColor(valueR, valueG, valueB, valueA or 1)
-end
-
-
-function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or colorpickerData.reference)
-	control:SetParent(parent.scroll or parent)
-	control:SetMouseEnabled(true)
-	control.tooltipText = colorpickerData.tooltip
-	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
-	control.label = wm:CreateControl(nil, control, CT_LABEL)
-	local label = control.label
-	label:SetDimensions(300, 26)
-	label:SetAnchor(TOPLEFT)
-	label:SetFont("ZoFontWinH4")
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetText(colorpickerData.name)
-
-	control.color = wm:CreateControl(nil, control, CT_CONTROL)
-	local color = control.color
-
-	local isHalfWidth = colorpickerData.width == "half"
-	if isHalfWidth then
-		control:SetDimensions(250, 55)
-		label:SetDimensions(250, 26)
-		color:SetDimensions(100, 24)
-		color:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
-	else
-		control:SetDimensions(510, 30)
-		label:SetDimensions(300, 26)
-		color:SetDimensions(200, 24)
-		color:SetAnchor(TOPRIGHT)
-	end
-
-	control.thumb = wm:CreateControl(nil, color, CT_TEXTURE)
-	local thumb = control.thumb
-	thumb:SetDimensions(36, 18)
-	thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
-
-	color.border = wm:CreateControl(nil, color, CT_TEXTURE)
-	local border = color.border
-	border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds")
-	border:SetTextureCoords(0, .625, 0, .8125)
-	border:SetDimensions(40, 22)
-	border:SetAnchor(CENTER, thumb, CENTER, 0, 0)
-
-	local function ColorPickerCallback(r, g, b, a)
-			control:UpdateValue(false, r, g, b, a)
-		end
-
-	control:SetHandler("OnMouseUp", function(self, btn, upInside)
-			if self.isDisabled then return end
-
-			if upInside then
-				local r, g, b, a = colorpickerData.getFunc()
-				COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, colorpickerData.name)
-			end
-		end)
-
-	if colorpickerData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0)
-		control.warning.tooltipText = colorpickerData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = colorpickerData
-
-	if colorpickerData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-	end
-	control.UpdateValue = UpdateValue
-	control:UpdateValue()
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[colorpickerData = {
+	type = "colorpicker",
+	name = "My Color Picker",
+	tooltip = "Color Picker's tooltip text.",
+	getFunc = function() return db.r, db.g, db.b, db.a end,	--(alpha is optional)
+	setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end,	--(alpha is optional)
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a},	--(optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a])
+	reference = "MyAddonColorpicker"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 5
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	if disable then
+		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+	else
+		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+	end
+
+	control.isDisabled = disable
+end
+
+local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA)
+	if forceDefault then	--if we are forcing defaults
+		local color = control.data.default
+		valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a
+		control.data.setFunc(valueR, valueG, valueB, valueA)
+	elseif valueR and valueG and valueB then
+		control.data.setFunc(valueR, valueG, valueB, valueA or 1)
+		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+		if control.panel.data.registerForRefresh then
+			cm:FireCallbacks("LAM-RefreshPanel", control)
+		end
+	else
+		valueR, valueG, valueB, valueA = control.data.getFunc()
+	end
+
+	control.thumb:SetColor(valueR, valueG, valueB, valueA or 1)
+end
+
+
+function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or colorpickerData.reference)
+	control:SetParent(parent.scroll or parent)
+	control:SetMouseEnabled(true)
+	--control.tooltipText = colorpickerData.tooltip
+	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+	control.label = wm:CreateControl(nil, control, CT_LABEL)
+	local label = control.label
+	label:SetDimensions(300, 26)
+	label:SetAnchor(TOPLEFT)
+	label:SetFont("ZoFontWinH4")
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetText(colorpickerData.name)
+
+	control.color = wm:CreateControl(nil, control, CT_CONTROL)
+	local color = control.color
+
+	local isHalfWidth = colorpickerData.width == "half"
+	if isHalfWidth then
+		control:SetDimensions(250, 55)
+		label:SetDimensions(250, 26)
+		color:SetDimensions(100, 24)
+		color:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
+	else
+		control:SetDimensions(510, 30)
+		label:SetDimensions(300, 26)
+		color:SetDimensions(200, 24)
+		color:SetAnchor(TOPRIGHT)
+	end
+
+	control.thumb = wm:CreateControl(nil, color, CT_TEXTURE)
+	local thumb = control.thumb
+	thumb:SetDimensions(36, 18)
+	thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
+
+	color.border = wm:CreateControl(nil, color, CT_TEXTURE)
+	local border = color.border
+	border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds")
+	border:SetTextureCoords(0, .625, 0, .8125)
+	border:SetDimensions(40, 22)
+	border:SetAnchor(CENTER, thumb, CENTER, 0, 0)
+
+	local function ColorPickerCallback(r, g, b, a)
+			control:UpdateValue(false, r, g, b, a)
+		end
+
+	control:SetHandler("OnMouseUp", function(self, btn, upInside)
+			if self.isDisabled then return end
+
+			if upInside then
+				local r, g, b, a = colorpickerData.getFunc()
+				COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, colorpickerData.name)
+			end
+		end)
+
+	if colorpickerData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0)
+		--control.warning.tooltipText = colorpickerData.warning
+		control.warning.data = {tooltipText = colorpickerData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = colorpickerData
+	control.data.tooltipText = colorpickerData.tooltip
+
+	if colorpickerData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+	end
+	control.UpdateValue = UpdateValue
+	control:UpdateValue()
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/custom.lua b/Libs/LAM2/controls/custom.lua
index 54c9775..fcfa618 100644
--- a/Libs/LAM2/controls/custom.lua
+++ b/Libs/LAM2/controls/custom.lua
@@ -1,45 +1,45 @@
---[[customData = {
-	type = "custom",
-	reference = "MyAddonCustomControl",	--(optional) unique name for your control to use as reference
-	refreshFunc = function(customControl) end,	--(optional) function to call when panel/controls refresh
-	width = "full",	--or "half" (optional)
-}	]]
-
-local widgetVersion = 4
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("custom", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local tinsert = table.insert
-
-local function UpdateValue(control)
-	if control.data.refreshFunc then
-		control.data.refreshFunc(control)
-	end
-end
-
-function LAMCreateControl.custom(parent, customData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or customData.reference)
-	control:SetResizeToFitDescendents(true)
-	control:SetParent(parent.scroll or parent)
-
-	local isHalfWidth = customData.width == "half"
-	if isHalfWidth then	--note these restrictions
-		control:SetDimensionConstraints(250, 55, 250, 100)
-		control:SetDimensions(250, 55)
-	else
-		control:SetDimensionConstraints(510, 30, 510, 100)
-		control:SetDimensions(510, 30)
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = customData
-
-	control.UpdateValue = UpdateValue
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[customData = {
+	type = "custom",
+	reference = "MyAddonCustomControl",	--(optional) unique name for your control to use as reference
+	refreshFunc = function(customControl) end,	--(optional) function to call when panel/controls refresh
+	width = "full",	--or "half" (optional)
+}	]]
+
+local widgetVersion = 4
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("custom", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local tinsert = table.insert
+
+local function UpdateValue(control)
+	if control.data.refreshFunc then
+		control.data.refreshFunc(control)
+	end
+end
+
+function LAMCreateControl.custom(parent, customData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or customData.reference)
+	control:SetResizeToFitDescendents(true)
+	control:SetParent(parent.scroll or parent)
+
+	local isHalfWidth = customData.width == "half"
+	if isHalfWidth then	--note these restrictions
+		control:SetDimensionConstraints(250, 55, 250, 100)
+		control:SetDimensions(250, 55)
+	else
+		control:SetDimensionConstraints(510, 30, 510, 100)
+		control:SetDimensions(510, 30)
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = customData
+
+	control.UpdateValue = UpdateValue
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/description.lua b/Libs/LAM2/controls/description.lua
index 5d7219d..aac6d9e 100644
--- a/Libs/LAM2/controls/description.lua
+++ b/Libs/LAM2/controls/description.lua
@@ -1,67 +1,67 @@
---[[descriptionData = {
-	type = "description",
-	title = "My Title",	--(optional)
-	text = "My description text to display.",
-	width = "full",	--or "half" (optional)
-	reference = "MyAddonDescription"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 4
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("description", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local tinsert = table.insert
-
-local function UpdateValue(control)
-	if control.title then
-		control.title:SetText(control.data.title)
-	end
-	control.desc:SetText(control.data.text)
-end
-
-function LAMCreateControl.description(parent, descriptionData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or descriptionData.reference)
-	control:SetResizeToFitDescendents(true)
-	control:SetParent(parent.scroll or parent)
-	local isHalfWidth = descriptionData.width == "half"
-	if isHalfWidth then
-		control:SetDimensionConstraints(250, 55, 250, 100)
-		control:SetDimensions(250, 55)
-	else
-		control:SetDimensionConstraints(510, 40, 510, 100)
-		control:SetDimensions(510, 30)
-	end
-
-	control.desc = wm:CreateControl(nil, control, CT_LABEL)
-	local desc = control.desc
-	desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
-	desc:SetFont("ZoFontGame")
-	desc:SetText(descriptionData.text)
-	desc:SetWidth(isHalfWidth and 250 or 510)
-
-	if descriptionData.title then
-		control.title = wm:CreateControl(nil, control, CT_LABEL)
-		local title = control.title
-		title:SetWidth(isHalfWidth and 250 or 510)
-		title:SetAnchor(TOPLEFT, control, TOPLEFT)
-		title:SetFont("ZoFontWinH4")
-		title:SetText(descriptionData.title)
-		desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT)
-	else
-		desc:SetAnchor(TOPLEFT)
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = descriptionData
-
-	control.UpdateValue = UpdateValue
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
-
+--[[descriptionData = {
+	type = "description",
+	title = "My Title",	--(optional)
+	text = "My description text to display.",
+	width = "full",	--or "half" (optional)
+	reference = "MyAddonDescription"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 4
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("description", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local tinsert = table.insert
+
+local function UpdateValue(control)
+	if control.title then
+		control.title:SetText(control.data.title)
+	end
+	control.desc:SetText(control.data.text)
+end
+
+function LAMCreateControl.description(parent, descriptionData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or descriptionData.reference)
+	control:SetResizeToFitDescendents(true)
+	control:SetParent(parent.scroll or parent)
+	local isHalfWidth = descriptionData.width == "half"
+	if isHalfWidth then
+		control:SetDimensionConstraints(250, 55, 250, 100)
+		control:SetDimensions(250, 55)
+	else
+		control:SetDimensionConstraints(510, 40, 510, 100)
+		control:SetDimensions(510, 30)
+	end
+
+	control.desc = wm:CreateControl(nil, control, CT_LABEL)
+	local desc = control.desc
+	desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
+	desc:SetFont("ZoFontGame")
+	desc:SetText(descriptionData.text)
+	desc:SetWidth(isHalfWidth and 250 or 510)
+
+	if descriptionData.title then
+		control.title = wm:CreateControl(nil, control, CT_LABEL)
+		local title = control.title
+		title:SetWidth(isHalfWidth and 250 or 510)
+		title:SetAnchor(TOPLEFT, control, TOPLEFT)
+		title:SetFont("ZoFontWinH4")
+		title:SetText(descriptionData.title)
+		desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT)
+	else
+		desc:SetAnchor(TOPLEFT)
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = descriptionData
+
+	control.UpdateValue = UpdateValue
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
+
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/dropdown.lua b/Libs/LAM2/controls/dropdown.lua
index 4ced295..10c44eb 100644
--- a/Libs/LAM2/controls/dropdown.lua
+++ b/Libs/LAM2/controls/dropdown.lua
@@ -1,151 +1,153 @@
---[[dropdownData = {
-	type = "dropdown",
-	name = "My Dropdown",
-	tooltip = "Dropdown's tooltip text.",
-	choices = {"table", "of", "choices"},
-	sort = "name-up", --or "name-down", "numeric-up", "numeric-down" (optional) - if not provided, list will not be sorted
-	getFunc = function() return db.var end,
-	setFunc = function(var) db.var = var doStuff() end,
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	default = defaults.var,	--(optional)
-	reference = "MyAddonDropdown"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 5
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
-
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	control.dropdown:SetEnabled(not disable)
-	if disable then
-		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-	else
-		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-	end
-end
-
-local function UpdateValue(control, forceDefault, value)
-	if forceDefault then	--if we are forcing defaults
-		value = control.data.default
-		control.data.setFunc(value)
-		control.dropdown:SetSelectedItem(value)
-	elseif value then
-		control.data.setFunc(value)
-		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-		if control.panel.data.registerForRefresh then
-			cm:FireCallbacks("LAM-RefreshPanel", control)
-		end
-	else
-		value = control.data.getFunc()
-		control.dropdown:SetSelectedItem(value)
-	end
-end
-
-local function DropdownCallback(choice, choiceText, choice)
-	choice.control:UpdateValue(false, choiceText)
-end
-
-local function UpdateChoices(control, choices)
-	control.dropdown:ClearItems()	--remove previous choices	--(need to call :SetSelectedItem()?)
-
-	--build new list of choices
-	local choices = choices or control.data.choices
-	for i = 1, #choices do
-		local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback)
-		entry.control = control
-		control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE)	--if sort type/order isn't specified, then don't sort
-	end
-end
-
-local function GrabSortingInfo(sortInfo)
-	local t, i = {}, 1
-	for info in string.gmatch(sortInfo, "([^%-]+)") do
-		t[i] = info
-		i = i + 1
-	end
-
-	return t
-end
-
-
-local comboboxCount = 1
-function LAMCreateControl.dropdown(parent, dropdownData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or dropdownData.reference)
-	control:SetParent(parent.scroll or parent)
-	control:SetMouseEnabled(true)
-	control.tooltipText = dropdownData.tooltip
-	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
-	control.label = wm:CreateControl(nil, control, CT_LABEL)
-	local label = control.label
-	label:SetAnchor(TOPLEFT)
-	label:SetFont("ZoFontWinH4")
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetText(dropdownData.name)
-
-	control.combobox = wm:CreateControlFromVirtual(parent:GetName().."Combobox"..comboboxCount, control, "ZO_ComboBox")
-	comboboxCount = comboboxCount + 1
-	local combobox = control.combobox
-	combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-	combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-	control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox)
-	local dropdown = control.dropdown
-	if dropdownData.sort then
-		local sortInfo = GrabSortingInfo(dropdownData.sort)
-		local sortType, sortOrder = sortInfo[1], sortInfo[2]
-		dropdown:SetSortOrder(sortOrder == "up" and ZO_SORT_ORDER_UP or ZO_SORT_ORDER_DOWN, sortType == "name" and ZO_SORT_BY_NAME or ZO_SORT_BY_NAME_NUMERIC)
-	end
-
-	local isHalfWidth = dropdownData.width == "half"
-	if isHalfWidth then
-		control:SetDimensions(250, 55)
-		label:SetDimensions(250, 26)
-		combobox:SetDimensions(225, 26)
-		combobox:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
-	else
-		control:SetDimensions(510, 30)
-		label:SetDimensions(300, 26)
-		combobox:SetDimensions(200, 26)
-		combobox:SetAnchor(TOPRIGHT)
-	end
-
-	if dropdownData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0)
-		control.warning.tooltipText = dropdownData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = dropdownData
-
-	if dropdownData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-	end
-	control.UpdateChoices = UpdateChoices
-	control:UpdateChoices(dropdownData.choices)
-	control.UpdateValue = UpdateValue
-	control:UpdateValue()
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[dropdownData = {
+	type = "dropdown",
+	name = "My Dropdown",
+	tooltip = "Dropdown's tooltip text.",
+	choices = {"table", "of", "choices"},
+	sort = "name-up", --or "name-down", "numeric-up", "numeric-down" (optional) - if not provided, list will not be sorted
+	getFunc = function() return db.var end,
+	setFunc = function(var) db.var = var doStuff() end,
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	default = defaults.var,	--(optional)
+	reference = "MyAddonDropdown"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 7
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	control.dropdown:SetEnabled(not disable)
+	if disable then
+		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+	else
+		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+	end
+end
+
+local function UpdateValue(control, forceDefault, value)
+	if forceDefault then	--if we are forcing defaults
+		value = control.data.default
+		control.data.setFunc(value)
+		control.dropdown:SetSelectedItem(value)
+	elseif value then
+		control.data.setFunc(value)
+		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+		if control.panel.data.registerForRefresh then
+			cm:FireCallbacks("LAM-RefreshPanel", control)
+		end
+	else
+		value = control.data.getFunc()
+		control.dropdown:SetSelectedItem(value)
+	end
+end
+
+local function DropdownCallback(choice, choiceText, choice)
+	choice.control:UpdateValue(false, choiceText)
+end
+
+local function UpdateChoices(control, choices)
+	control.dropdown:ClearItems()	--remove previous choices	--(need to call :SetSelectedItem()?)
+
+	--build new list of choices
+	local choices = choices or control.data.choices
+	for i = 1, #choices do
+		local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback)
+		entry.control = control
+		control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE)	--if sort type/order isn't specified, then don't sort
+	end
+end
+
+local function GrabSortingInfo(sortInfo)
+	local t, i = {}, 1
+	for info in string.gmatch(sortInfo, "([^%-]+)") do
+		t[i] = info
+		i = i + 1
+	end
+
+	return t
+end
+
+
+local comboboxCount = 1
+function LAMCreateControl.dropdown(parent, dropdownData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or dropdownData.reference)
+	control:SetParent(parent.scroll or parent)
+	control:SetMouseEnabled(true)
+	--control.tooltipText = dropdownData.tooltip
+	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+	control.label = wm:CreateControl(nil, control, CT_LABEL)
+	local label = control.label
+	label:SetAnchor(TOPLEFT)
+	label:SetFont("ZoFontWinH4")
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetText(dropdownData.name)
+
+	control.combobox = wm:CreateControlFromVirtual(parent:GetName().."Combobox"..comboboxCount, control, "ZO_ComboBox")
+	comboboxCount = comboboxCount + 1
+	local combobox = control.combobox
+	combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+	combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+	control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox)
+	local dropdown = control.dropdown
+	if dropdownData.sort then
+		local sortInfo = GrabSortingInfo(dropdownData.sort)
+		local sortType, sortOrder = sortInfo[1], sortInfo[2]
+		dropdown:SetSortOrder(sortOrder == "up" and ZO_SORT_ORDER_UP or ZO_SORT_ORDER_DOWN, sortType == "name" and ZO_SORT_BY_NAME or ZO_SORT_BY_NAME_NUMERIC)
+	end
+
+	local isHalfWidth = dropdownData.width == "half"
+	if isHalfWidth then
+		control:SetDimensions(250, 55)
+		label:SetDimensions(250, 26)
+		combobox:SetDimensions(225, 26)
+		combobox:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
+	else
+		control:SetDimensions(510, 30)
+		label:SetDimensions(300, 26)
+		combobox:SetDimensions(200, 26)
+		combobox:SetAnchor(TOPRIGHT)
+	end
+
+	if dropdownData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0)
+		--control.warning.tooltipText = dropdownData.warning
+		control.warning.data = {tooltipText = dropdownData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = dropdownData
+	control.data.tooltipText = dropdownData.tooltip
+
+	if dropdownData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+	end
+	control.UpdateChoices = UpdateChoices
+	control:UpdateChoices(dropdownData.choices)
+	control.UpdateValue = UpdateValue
+	control:UpdateValue()
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/editbox.lua b/Libs/LAM2/controls/editbox.lua
index 3b92ea0..25396ff 100644
--- a/Libs/LAM2/controls/editbox.lua
+++ b/Libs/LAM2/controls/editbox.lua
@@ -1,153 +1,155 @@
---[[editboxData = {
-	type = "editbox",
-	name = "My Editbox",
-	tooltip = "Editbox's tooltip text.",
-	getFunc = function() return db.text end,
-	setFunc = function(text) db.text = text doStuff() end,
-	isMultiline = true,	--boolean
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	default = defaults.text,	--(optional)
-	reference = "MyAddonEditbox"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 4
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("editbox", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local tinsert = table.insert
-
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	if disable then
-		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-		control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-	else
-		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-		control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-	end
-	--control.editbox:SetEditEnabled(not disable)
-	control.editbox:SetMouseEnabled(not disable)
-end
-
-local function UpdateValue(control, forceDefault, value)
-	if forceDefault then	--if we are forcing defaults
-		value = control.data.default
-		control.data.setFunc(value)
-		control.editbox:SetText(value)
-	elseif value then
-		control.data.setFunc(value)
-		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-		if control.panel.data.registerForRefresh then
-			cm:FireCallbacks("LAM-RefreshPanel", control)
-		end
-	else
-		value = control.data.getFunc()
-		control.editbox:SetText(value)
-	end
-end
-
-
-function LAMCreateControl.editbox(parent, editboxData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or editboxData.reference)
-	control:SetParent(parent.scroll or parent)
-	control:SetMouseEnabled(true)
-	control:SetResizeToFitDescendents(true)
-	control.tooltipText = editboxData.tooltip
-	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
-	control.label = wm:CreateControl(nil, control, CT_LABEL)
-	local label = control.label
-	label:SetAnchor(TOPLEFT)
-	label:SetFont("ZoFontWinH4")
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetText(editboxData.name)
-
-	control.bg = wm:CreateControlFromVirtual(nil, control, "ZO_EditBackdrop")
-	local bg = control.bg
-
-	if editboxData.isMultiline then
-		control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop")
-		control.editbox:SetHandler("OnMouseWheel", function(self, delta)
-				if self:HasFocus() then	--only set focus to new spots if the editbox is currently in use
-					local cursorPos = self:GetCursorPosition()
-					local text = self:GetText()
-					local textLen = text:len()
-					local newPos
-					if delta > 0 then	--scrolling up
-						local reverseText = text:reverse()
-						local revCursorPos = textLen - cursorPos
-						local revPos = reverseText:find("\n", revCursorPos+1)
-						newPos = revPos and textLen - revPos
-					else	--scrolling down
-						newPos = text:find("\n", cursorPos+1)
-					end
-					if newPos then	--if we found a new line, then scroll, otherwise don't
-						self:SetCursorPosition(newPos)
-					end
-				end
-			end)
-	else
-		control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop")
-	end
-	local editbox = control.editbox
-	editbox:SetText(editboxData.getFunc())
-	editbox:SetMaxInputChars(3000)
-	editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end)
-	editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end)
-	editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-	editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-
-	local isHalfWidth = editboxData.width == "half"
-	if isHalfWidth then
-		control:SetDimensions(250, 55)
-		label:SetDimensions(250, 26)
-		bg:SetDimensions(225, editboxData.isMultiline and 74 or 24)
-		bg:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
-		if editboxData.isMultiline then
-			editbox:SetDimensionConstraints(210, 74, 210, 500)
-		end
-	else
-		control:SetDimensions(510, 30)
-		label:SetDimensions(300, 26)
-		bg:SetDimensions(200, editboxData.isMultiline and 100 or 24)
-		bg:SetAnchor(TOPRIGHT)
-		if editboxData.isMultiline then
-			editbox:SetDimensionConstraints(185, 100, 185, 500)
-		end
-	end
-
-	if editboxData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0)
-		control.warning.tooltipText = editboxData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = editboxData
-
-	if editboxData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-	end
-	control.UpdateValue = UpdateValue
-	control:UpdateValue()
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[editboxData = {
+	type = "editbox",
+	name = "My Editbox",
+	tooltip = "Editbox's tooltip text.",
+	getFunc = function() return db.text end,
+	setFunc = function(text) db.text = text doStuff() end,
+	isMultiline = true,	--boolean
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	default = defaults.text,	--(optional)
+	reference = "MyAddonEditbox"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 6
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("editbox", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	if disable then
+		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+		control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+	else
+		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+		control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+	end
+	--control.editbox:SetEditEnabled(not disable)
+	control.editbox:SetMouseEnabled(not disable)
+end
+
+local function UpdateValue(control, forceDefault, value)
+	if forceDefault then	--if we are forcing defaults
+		value = control.data.default
+		control.data.setFunc(value)
+		control.editbox:SetText(value)
+	elseif value then
+		control.data.setFunc(value)
+		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+		if control.panel.data.registerForRefresh then
+			cm:FireCallbacks("LAM-RefreshPanel", control)
+		end
+	else
+		value = control.data.getFunc()
+		control.editbox:SetText(value)
+	end
+end
+
+
+function LAMCreateControl.editbox(parent, editboxData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or editboxData.reference)
+	control:SetParent(parent.scroll or parent)
+	control:SetMouseEnabled(true)
+	control:SetResizeToFitDescendents(true)
+	--control.tooltipText = editboxData.tooltip
+	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+	control.label = wm:CreateControl(nil, control, CT_LABEL)
+	local label = control.label
+	label:SetAnchor(TOPLEFT)
+	label:SetFont("ZoFontWinH4")
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetText(editboxData.name)
+
+	control.bg = wm:CreateControlFromVirtual(nil, control, "ZO_EditBackdrop")
+	local bg = control.bg
+
+	if editboxData.isMultiline then
+		control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop")
+		control.editbox:SetHandler("OnMouseWheel", function(self, delta)
+				if self:HasFocus() then	--only set focus to new spots if the editbox is currently in use
+					local cursorPos = self:GetCursorPosition()
+					local text = self:GetText()
+					local textLen = text:len()
+					local newPos
+					if delta > 0 then	--scrolling up
+						local reverseText = text:reverse()
+						local revCursorPos = textLen - cursorPos
+						local revPos = reverseText:find("\n", revCursorPos+1)
+						newPos = revPos and textLen - revPos
+					else	--scrolling down
+						newPos = text:find("\n", cursorPos+1)
+					end
+					if newPos then	--if we found a new line, then scroll, otherwise don't
+						self:SetCursorPosition(newPos)
+					end
+				end
+			end)
+	else
+		control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop")
+	end
+	local editbox = control.editbox
+	editbox:SetText(editboxData.getFunc())
+	editbox:SetMaxInputChars(3000)
+	editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end)
+	editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end)
+	editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+	editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+
+	local isHalfWidth = editboxData.width == "half"
+	if isHalfWidth then
+		control:SetDimensions(250, 55)
+		label:SetDimensions(250, 26)
+		bg:SetDimensions(225, editboxData.isMultiline and 74 or 24)
+		bg:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT)
+		if editboxData.isMultiline then
+			editbox:SetDimensionConstraints(210, 74, 210, 500)
+		end
+	else
+		control:SetDimensions(510, 30)
+		label:SetDimensions(300, 26)
+		bg:SetDimensions(200, editboxData.isMultiline and 100 or 24)
+		bg:SetAnchor(TOPRIGHT)
+		if editboxData.isMultiline then
+			editbox:SetDimensionConstraints(185, 100, 185, 500)
+		end
+	end
+
+	if editboxData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0)
+		--control.warning.tooltipText = editboxData.warning
+		control.warning.data = {tooltipText = editboxData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = editboxData
+	control.data.tooltipText = editboxData.tooltip
+
+	if editboxData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+	end
+	control.UpdateValue = UpdateValue
+	control:UpdateValue()
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/header.lua b/Libs/LAM2/controls/header.lua
index bbf2c60..98df539 100644
--- a/Libs/LAM2/controls/header.lua
+++ b/Libs/LAM2/controls/header.lua
@@ -1,47 +1,47 @@
---[[headerData = {
-	type = "header",
-	name = "My Header",
-	width = "full",	--or "half" (optional)
-	reference = "MyAddonHeader"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 4
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("header", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local tinsert = table.insert
-
-local function UpdateValue(control)
-	control.header:SetText(control.data.name)
-end
-
-function LAMCreateControl.header(parent, headerData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or headerData.reference)
-	control:SetParent(parent.scroll or parent)
-	local isHalfWidth = headerData.width == "half"
-	control:SetDimensions(isHalfWidth and 250 or 510, 30)
-
-	control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
-	local divider = control.divider
-	divider:SetWidth(isHalfWidth and 250 or 510)
-	divider:SetAnchor(TOPLEFT)
-
-	control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-	local header = control.header
-	header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT)
-	header:SetAnchor(BOTTOMRIGHT)
-	header:SetText(headerData.name)
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = headerData
-
-	control.UpdateValue = UpdateValue
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[headerData = {
+	type = "header",
+	name = "My Header",
+	width = "full",	--or "half" (optional)
+	reference = "MyAddonHeader"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 4
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("header", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local tinsert = table.insert
+
+local function UpdateValue(control)
+	control.header:SetText(control.data.name)
+end
+
+function LAMCreateControl.header(parent, headerData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or headerData.reference)
+	control:SetParent(parent.scroll or parent)
+	local isHalfWidth = headerData.width == "half"
+	control:SetDimensions(isHalfWidth and 250 or 510, 30)
+
+	control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
+	local divider = control.divider
+	divider:SetWidth(isHalfWidth and 250 or 510)
+	divider:SetAnchor(TOPLEFT)
+
+	control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+	local header = control.header
+	header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT)
+	header:SetAnchor(BOTTOMRIGHT)
+	header:SetText(headerData.name)
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = headerData
+
+	control.UpdateValue = UpdateValue
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/panel.lua b/Libs/LAM2/controls/panel.lua
index 5f9f41b..158fd8d 100644
--- a/Libs/LAM2/controls/panel.lua
+++ b/Libs/LAM2/controls/panel.lua
@@ -1,138 +1,138 @@
---[[panelData = {
-	type = "panel",
-	name = "Window Title",
-	displayName = "My Longer Window Title",	--(optional) (can be useful for long addon names or if you want to colorize it)
-	author = "Seerah",	--(optional)
-	version = "2.0",	--(optional)
-	slashCommand = "/myaddon",	--(optional) will register a keybind to open to this panel (don't forget to include the slash!)
-	registerForRefresh = true,	--boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown)
-	registerForDefaults = true,	--boolean (optional) (will set all options controls back to default values)
-	resetFunc = function() print("defaults reset") end,	--(optional) custom function to run after settings are reset to defaults
-}	]]
-
-
-local widgetVersion = 8
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("panel", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-
-local function RefreshPanel(control)
-	local panel = control.panel or control	--callback can be fired by a single control or by the panel showing
-	local panelControls = panel.controlsToRefresh
-
-	for i = 1, #panelControls do
-		local updateControl = panelControls[i]
-		if  updateControl ~= control then
-			if updateControl.UpdateValue then
-				updateControl:UpdateValue()
-			end
-			if updateControl.UpdateDisabled then
-				updateControl:UpdateDisabled()
-			end
-		end
-	end
-end
-
-local function ForceDefaults(panel)
-	local panelControls = panel.controlsToRefresh
-
-	for i = 1, #panelControls do
-		local updateControl = panelControls[i]
-		if updateControl.UpdateValue and updateControl.data.default ~= nil then
-			updateControl:UpdateValue(true)
-		end
-	end
-
-	if panel.data.resetFunc then
-		panel.data.resetFunc()
-	end
-
-	cm:FireCallbacks("LAM-RefreshPanel", panel)
-end
-ESO_Dialogs["LAM_DEFAULTS"] = {
-	title = {
-		text = SI_OPTIONS_RESET_TITLE,
-	},
-	mainText = {
-		text = SI_OPTIONS_RESET_PROMPT,
-		align = TEXT_ALIGN_CENTER,
-	},
-	buttons = {
-		[1] = {
-			text = SI_OPTIONS_RESET,
-			callback = function(dialog) ForceDefaults(dialog.data[1]) end,
-		},
-		[2] = {
-			text = SI_DIALOG_CANCEL,
-		},
-	},
-}
-
-local callbackRegistered = false
-LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
-function LAMCreateControl.panel(parent, panelData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName)
-	control:SetParent(parent)
-
-	control.bg = wm:CreateControl(nil, control, CT_BACKDROP)
-	local bg = control.bg
-	bg:SetAnchorFill()
-	bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16)
-	bg:SetCenterColor(0, 0, 0, 0)
-
-	control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-	local label = control.label
-	label:SetAnchor(TOPLEFT, control, TOPLEFT, 10, 10)
-	label:SetText(panelData.displayName and panelData.displayName or panelData.name)
-
-	if panelData.author or panelData.version then
-		control.info = wm:CreateControl(nil, control, CT_LABEL)
-		local info = control.info
-		info:SetFont("$(CHAT_FONT)|14|soft-shadow-thin")
-		info:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
-		info:SetHeight(13)
-		info:SetAnchor(TOPRIGHT, control, BOTTOMRIGHT, -5, 2)
-		if panelData.author and panelData.version then
-			--info:SetText("Version: "..panelData.version.."  -  "..GetString(SI_ADDON_MANAGER_AUTHOR)..": "..panelData.author)
-			info:SetText(string.format("Version: %s  -  %s: %s", panelData.version, GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author))
-		elseif panelData.author then
-			info:SetText(string.format("%s: %s", GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author))
-		else
-			info:SetText("Version: "..panelData.version)
-		end
-	end
-
-	control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
-	LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1
-	local container = control.container
-	container:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 20)
-	container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3)
-	control.scroll = GetControl(control.container, "ScrollChild")
-	control.scroll:SetResizeToFitPadding(0, 20)
-
-	if panelData.registerForDefaults then
-		control.defaultButton = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultTextButton")
-		local defaultButton = control.defaultButton
-		defaultButton:SetFont("ZoFontDialogKeybindDescription")
-		defaultButton:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
-		--defaultButton:SetText("Reset To Defaults")
-		defaultButton:SetText(GetString(SI_OPTIONS_RESET_TITLE))
-		defaultButton:SetDimensions(200, 30)
-		defaultButton:SetAnchor(TOPLEFT, control, BOTTOMLEFT, 0, 2)
-		defaultButton:SetHandler("OnClicked", function()
-				ZO_Dialogs_ShowDialog("LAM_DEFAULTS", {control})
-			end)
-	end
-
-	if panelData.registerForRefresh and not callbackRegistered then	--don't want to register our callback more than once
-		cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel)
-		callbackRegistered = true
-	end
-
-	control.data = panelData
-	control.controlsToRefresh = {}
-
-	return control
+--[[panelData = {
+	type = "panel",
+	name = "Window Title",
+	displayName = "My Longer Window Title",	--(optional) (can be useful for long addon names or if you want to colorize it)
+	author = "Seerah",	--(optional)
+	version = "2.0",	--(optional)
+	slashCommand = "/myaddon",	--(optional) will register a keybind to open to this panel (don't forget to include the slash!)
+	registerForRefresh = true,	--boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown)
+	registerForDefaults = true,	--boolean (optional) (will set all options controls back to default values)
+	resetFunc = function() print("defaults reset") end,	--(optional) custom function to run after settings are reset to defaults
+}	]]
+
+
+local widgetVersion = 8
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("panel", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+
+local function RefreshPanel(control)
+	local panel = control.panel or control	--callback can be fired by a single control or by the panel showing
+	local panelControls = panel.controlsToRefresh
+
+	for i = 1, #panelControls do
+		local updateControl = panelControls[i]
+		if  updateControl ~= control then
+			if updateControl.UpdateValue then
+				updateControl:UpdateValue()
+			end
+			if updateControl.UpdateDisabled then
+				updateControl:UpdateDisabled()
+			end
+		end
+	end
+end
+
+local function ForceDefaults(panel)
+	local panelControls = panel.controlsToRefresh
+
+	for i = 1, #panelControls do
+		local updateControl = panelControls[i]
+		if updateControl.UpdateValue and updateControl.data.default ~= nil then
+			updateControl:UpdateValue(true)
+		end
+	end
+
+	if panel.data.resetFunc then
+		panel.data.resetFunc()
+	end
+
+	cm:FireCallbacks("LAM-RefreshPanel", panel)
+end
+ESO_Dialogs["LAM_DEFAULTS"] = {
+	title = {
+		text = SI_OPTIONS_RESET_TITLE,
+	},
+	mainText = {
+		text = SI_OPTIONS_RESET_PROMPT,
+		align = TEXT_ALIGN_CENTER,
+	},
+	buttons = {
+		[1] = {
+			text = SI_OPTIONS_RESET,
+			callback = function(dialog) ForceDefaults(dialog.data[1]) end,
+		},
+		[2] = {
+			text = SI_DIALOG_CANCEL,
+		},
+	},
+}
+
+local callbackRegistered = false
+LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
+function LAMCreateControl.panel(parent, panelData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName)
+	control:SetParent(parent)
+
+	control.bg = wm:CreateControl(nil, control, CT_BACKDROP)
+	local bg = control.bg
+	bg:SetAnchorFill()
+	bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16)
+	bg:SetCenterColor(0, 0, 0, 0)
+
+	control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+	local label = control.label
+	label:SetAnchor(TOPLEFT, control, TOPLEFT, 10, 10)
+	label:SetText(panelData.displayName and panelData.displayName or panelData.name)
+
+	if panelData.author or panelData.version then
+		control.info = wm:CreateControl(nil, control, CT_LABEL)
+		local info = control.info
+		info:SetFont("$(CHAT_FONT)|14|soft-shadow-thin")
+		info:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
+		info:SetHeight(13)
+		info:SetAnchor(TOPRIGHT, control, BOTTOMRIGHT, -5, 2)
+		if panelData.author and panelData.version then
+			--info:SetText("Version: "..panelData.version.."  -  "..GetString(SI_ADDON_MANAGER_AUTHOR)..": "..panelData.author)
+			info:SetText(string.format("Version: %s  -  %s: %s", panelData.version, GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author))
+		elseif panelData.author then
+			info:SetText(string.format("%s: %s", GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author))
+		else
+			info:SetText("Version: "..panelData.version)
+		end
+	end
+
+	control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
+	LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1
+	local container = control.container
+	container:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 20)
+	container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3)
+	control.scroll = GetControl(control.container, "ScrollChild")
+	control.scroll:SetResizeToFitPadding(0, 20)
+
+	if panelData.registerForDefaults then
+		control.defaultButton = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultTextButton")
+		local defaultButton = control.defaultButton
+		defaultButton:SetFont("ZoFontDialogKeybindDescription")
+		defaultButton:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
+		--defaultButton:SetText("Reset To Defaults")
+		defaultButton:SetText(GetString(SI_OPTIONS_RESET_TITLE))
+		defaultButton:SetDimensions(200, 30)
+		defaultButton:SetAnchor(TOPLEFT, control, BOTTOMLEFT, 0, 2)
+		defaultButton:SetHandler("OnClicked", function()
+				ZO_Dialogs_ShowDialog("LAM_DEFAULTS", {control})
+			end)
+	end
+
+	if panelData.registerForRefresh and not callbackRegistered then	--don't want to register our callback more than once
+		cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel)
+		callbackRegistered = true
+	end
+
+	control.data = panelData
+	control.controlsToRefresh = {}
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/slider.lua b/Libs/LAM2/controls/slider.lua
index d26f314..e7bc01c 100644
--- a/Libs/LAM2/controls/slider.lua
+++ b/Libs/LAM2/controls/slider.lua
@@ -1,182 +1,184 @@
---[[sliderData = {
-	type = "slider",
-	name = "My Slider",
-	tooltip = "Slider's tooltip text.",
-	min = 0,
-	max = 20,
-	step = 1,	--(optional)
-	getFunc = function() return db.var end,
-	setFunc = function(value) db.var = value doStuff() end,
-	width = "full",	--or "half" (optional)
-	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
-	warning = "Will need to reload the UI.",	--(optional)
-	default = defaults.var,	--(optional)
-	reference = "MyAddonSlider"	--(optional) unique global reference to control
-}	]]
-
-
-local widgetVersion = 3
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("slider", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-local round = zo_round
-local strformat = string.format
-local tinsert = table.insert
-
-local function UpdateDisabled(control)
-	local disable
-	if type(control.data.disabled) == "function" then
-		disable = control.data.disabled()
-	else
-		disable = control.data.disabled
-	end
-
-	control.slider:SetEnabled(not disable)
-	control.slidervalue:SetEditEnabled(not disable)
-	if disable then
-		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-		control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-		control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-		control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-	else
-		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-		control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-		control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-		control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-	end
-end
-
-local function UpdateValue(control, forceDefault, value)
-	if forceDefault then	--if we are forcing defaults
-		value = control.data.default
-		control.data.setFunc(value)
-	elseif value and value >= control.data.min and value <= control.data.max then
-		control.data.setFunc(value)
-		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-		if control.panel.data.registerForRefresh then
-			cm:FireCallbacks("LAM-RefreshPanel", control)
-		end
-	else
-		value = control.data.getFunc()
-	end
-
-	control.slider:SetValue(value)
-	control.slidervalue:SetText(value)
-end
-
-
-function LAMCreateControl.slider(parent, sliderData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or sliderData.reference)
-	control:SetParent(parent.scroll or parent)
-	local isHalfWidth = sliderData.width == "half"
-	if isHalfWidth then
-		control:SetDimensions(250, 55)
-	else
-		control:SetDimensions(510, 40)
-	end
-	control:SetMouseEnabled(true)
-	control.tooltipText = sliderData.tooltip
-	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
-	control.label = wm:CreateControl(nil, control, CT_LABEL)
-	local label = control.label
-	label:SetFont("ZoFontWinH4")
-	label:SetDimensions(isHalfWidth and 250 or 300, 26)
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetAnchor(isHalfWidth and TOPLEFT or LEFT)
-	label:SetText(sliderData.name)
-
-	--skipping creating the backdrop...  Is this the actual slider texture?
-	control.slider = wm:CreateControl(nil, control, CT_SLIDER)
-	local slider = control.slider
-	slider:SetDimensions(190, 14)
-	if isHalfWidth then
-		slider:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT, -5, 2)
-	else
-		slider:SetAnchor(RIGHT, control, RIGHT, -5, -5)
-	end
-	slider:SetMouseEnabled(true)
-	slider:SetOrientation(ORIENTATION_HORIZONTAL)
-	--put nil for highlighted texture file path, and what look to be texture coords
-	slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16)
-	local minValue = sliderData.min
-	local maxValue = sliderData.max
-	slider:SetMinMax(minValue, maxValue)
-	slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-	slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseExit(control) end)
-
-	slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP)
-	local bg = slider.bg
-	bg:SetCenterColor(0, 0, 0)
-	bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4)
-	bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4)
-	bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)
-
-	control.minText = wm:CreateControl(nil, slider, CT_LABEL)
-	local minText = control.minText
-	minText:SetFont("ZoFontGameSmall")
-	minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT)
-	minText:SetText(sliderData.min)
-
-	control.maxText = wm:CreateControl(nil, slider, CT_LABEL)
-	local maxText = control.maxText
-	maxText:SetFont("ZoFontGameSmall")
-	maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT)
-	maxText:SetText(sliderData.max)
-
-	control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop")
-	control.slidervalueBG:SetDimensions(50, 16)
-	control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
-	control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")
-	local slidervalue = control.slidervalue
-	slidervalue:ClearAnchors()
-	slidervalue:SetAnchor(TOPLEFT, slidervaluebg, TOPLEFT, 3, 1)
-	slidervalue:SetAnchor(BOTTOMRIGHT, slidervaluebg, BOTTOMRIGHT, -3, -1)
-	slidervalue:SetTextType(TEXT_TYPE_NUMERIC)
-	slidervalue:SetFont("ZoFontGameSmall")
-	slidervalue:SetHandler("OnEscape", function(self)
-			self:LoseFocus()
-			control:UpdateValue()
-		end)
-	slidervalue:SetHandler("OnEnter", function(self)
-			self:LoseFocus()
-			control:UpdateValue(false, tonumber(self:GetText()))
-		end)
-
-	local range = maxValue - minValue
-	slider:SetValueStep(sliderData.step or 1)
-	slider:SetHandler("OnValueChanged", function(self, value, eventReason)
-			if eventReason == EVENT_REASON_SOFTWARE then return end
-			self:SetValue(value)	--do we actually need this line?
-			slidervalue:SetText(value)
-		end)
-	slider:SetHandler("OnSliderReleased", function(self, value)
-			--sliderData.setFunc(value)
-			control:UpdateValue(false, value)	--does this work here instead?
-		end)
-
-	if sliderData.warning then
-		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-		control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0)
-		control.warning.tooltipText = sliderData.warning
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is the submenu's parent
-	control.data = sliderData
-
-	if sliderData.disabled then
-		control.UpdateDisabled = UpdateDisabled
-		control:UpdateDisabled()
-	end
-	control.UpdateValue = UpdateValue
-	control:UpdateValue()
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
+--[[sliderData = {
+	type = "slider",
+	name = "My Slider",
+	tooltip = "Slider's tooltip text.",
+	min = 0,
+	max = 20,
+	step = 1,	--(optional)
+	getFunc = function() return db.var end,
+	setFunc = function(value) db.var = value doStuff() end,
+	width = "full",	--or "half" (optional)
+	disabled = function() return db.someBooleanSetting end,	--or boolean (optional)
+	warning = "Will need to reload the UI.",	--(optional)
+	default = defaults.var,	--(optional)
+	reference = "MyAddonSlider"	--(optional) unique global reference to control
+}	]]
+
+
+local widgetVersion = 5
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("slider", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+local round = zo_round
+local strformat = string.format
+local tinsert = table.insert
+
+local function UpdateDisabled(control)
+	local disable
+	if type(control.data.disabled) == "function" then
+		disable = control.data.disabled()
+	else
+		disable = control.data.disabled
+	end
+
+	control.slider:SetEnabled(not disable)
+	control.slidervalue:SetEditEnabled(not disable)
+	if disable then
+		control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+		control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+		control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+		control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+	else
+		control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+		control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+		control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+		control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+	end
+end
+
+local function UpdateValue(control, forceDefault, value)
+	if forceDefault then	--if we are forcing defaults
+		value = control.data.default
+		control.data.setFunc(value)
+	elseif value and value >= control.data.min and value <= control.data.max then
+		control.data.setFunc(value)
+		--after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+		if control.panel.data.registerForRefresh then
+			cm:FireCallbacks("LAM-RefreshPanel", control)
+		end
+	else
+		value = control.data.getFunc()
+	end
+
+	control.slider:SetValue(value)
+	control.slidervalue:SetText(value)
+end
+
+
+function LAMCreateControl.slider(parent, sliderData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or sliderData.reference)
+	control:SetParent(parent.scroll or parent)
+	local isHalfWidth = sliderData.width == "half"
+	if isHalfWidth then
+		control:SetDimensions(250, 55)
+	else
+		control:SetDimensions(510, 40)
+	end
+	control:SetMouseEnabled(true)
+	--control.tooltipText = sliderData.tooltip
+	control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+	control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+	control.label = wm:CreateControl(nil, control, CT_LABEL)
+	local label = control.label
+	label:SetFont("ZoFontWinH4")
+	label:SetDimensions(isHalfWidth and 250 or 300, 26)
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetAnchor(isHalfWidth and TOPLEFT or LEFT)
+	label:SetText(sliderData.name)
+
+	--skipping creating the backdrop...  Is this the actual slider texture?
+	control.slider = wm:CreateControl(nil, control, CT_SLIDER)
+	local slider = control.slider
+	slider:SetDimensions(190, 14)
+	if isHalfWidth then
+		slider:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT, -5, 2)
+	else
+		slider:SetAnchor(RIGHT, control, RIGHT, -5, -5)
+	end
+	slider:SetMouseEnabled(true)
+	slider:SetOrientation(ORIENTATION_HORIZONTAL)
+	--put nil for highlighted texture file path, and what look to be texture coords
+	slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16)
+	local minValue = sliderData.min
+	local maxValue = sliderData.max
+	slider:SetMinMax(minValue, maxValue)
+	slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+	slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseExit(control) end)
+
+	slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP)
+	local bg = slider.bg
+	bg:SetCenterColor(0, 0, 0)
+	bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4)
+	bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4)
+	bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)
+
+	control.minText = wm:CreateControl(nil, slider, CT_LABEL)
+	local minText = control.minText
+	minText:SetFont("ZoFontGameSmall")
+	minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT)
+	minText:SetText(sliderData.min)
+
+	control.maxText = wm:CreateControl(nil, slider, CT_LABEL)
+	local maxText = control.maxText
+	maxText:SetFont("ZoFontGameSmall")
+	maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT)
+	maxText:SetText(sliderData.max)
+
+	control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop")
+	control.slidervalueBG:SetDimensions(50, 16)
+	control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
+	control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")
+	local slidervalue = control.slidervalue
+	slidervalue:ClearAnchors()
+	slidervalue:SetAnchor(TOPLEFT, slidervaluebg, TOPLEFT, 3, 1)
+	slidervalue:SetAnchor(BOTTOMRIGHT, slidervaluebg, BOTTOMRIGHT, -3, -1)
+	slidervalue:SetTextType(TEXT_TYPE_NUMERIC)
+	slidervalue:SetFont("ZoFontGameSmall")
+	slidervalue:SetHandler("OnEscape", function(self)
+			self:LoseFocus()
+			control:UpdateValue()
+		end)
+	slidervalue:SetHandler("OnEnter", function(self)
+			self:LoseFocus()
+			control:UpdateValue(false, tonumber(self:GetText()))
+		end)
+
+	local range = maxValue - minValue
+	slider:SetValueStep(sliderData.step or 1)
+	slider:SetHandler("OnValueChanged", function(self, value, eventReason)
+			if eventReason == EVENT_REASON_SOFTWARE then return end
+			self:SetValue(value)	--do we actually need this line?
+			slidervalue:SetText(value)
+		end)
+	slider:SetHandler("OnSliderReleased", function(self, value)
+			--sliderData.setFunc(value)
+			control:UpdateValue(false, value)	--does this work here instead?
+		end)
+
+	if sliderData.warning then
+		control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+		control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0)
+		--control.warning.tooltipText = sliderData.warning
+		control.warning.data = {tooltipText = sliderData.warning}
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is the submenu's parent
+	control.data = sliderData
+	control.data.tooltipText = sliderData.tooltip
+
+	if sliderData.disabled then
+		control.UpdateDisabled = UpdateDisabled
+		control:UpdateDisabled()
+	end
+	control.UpdateValue = UpdateValue
+	control:UpdateValue()
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
 end
\ No newline at end of file
diff --git a/Libs/LAM2/controls/submenu.lua b/Libs/LAM2/controls/submenu.lua
index 41e8402..ee2b777 100644
--- a/Libs/LAM2/controls/submenu.lua
+++ b/Libs/LAM2/controls/submenu.lua
@@ -1,121 +1,123 @@
---[[submenuData = {
-	type = "submenu",
-	name = "Submenu Title",
-	tooltip = "My submenu tooltip",	--(optional)
-	controls = {sliderData, buttonData}	--(optional) used by LAM
-	reference = "MyAddonSubmenu"	--(optional) unique global reference to control
-}	]]
-
-local widgetVersion = 5
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("submenu", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local am = ANIMATION_MANAGER
-local tinsert = table.insert
-
-
-local function UpdateValue(control)
-	control.label:SetText(control.data.name)
-	if control.data.tooltip then
-		control.label.tooltipText = control.data.tooltip
-	end
-end
-
-local function AnimateSubmenu(clicked)
-	local control = clicked:GetParent()
-	control.open = not control.open
-
-	if control.open then
-		control.animation:PlayFromStart()
-	else
-		control.animation:PlayFromEnd()
-	end
-end
-
-
-function LAMCreateControl.submenu(parent, submenuData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or submenuData.reference)
-	control:SetParent(parent.scroll or parent)
-	control.panel = parent
-	control:SetDimensions(523, 40)
-
-	control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-	local label = control.label
-	label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
-	label:SetDimensions(520, 30)
-	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-	label:SetText(submenuData.name)
-	label:SetMouseEnabled(true)
-	if submenuData.tooltip then
-		label.tooltipText = submenuData.tooltip
-		label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-		label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-	end
-
-	control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
-	local scroll = control.scroll
-	scroll:SetParent(control)
-	scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10)
-	scroll:SetDimensionConstraints(525, 0, 525, 2500)
-
-	control.bg = wm:CreateControl(nil, label, CT_BACKDROP)
-	local bg = control.bg
-	bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5)
-	bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
-	bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
-	bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
-	bg:SetInsets(16, 16, -16, -16)
-
-	control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
-	local arrow = control.arrow
-	arrow:SetDimensions(28, 28)
-	arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")	--list_sortup for the other way
-	arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5)
-
-	--figure out the cool animation later...
-	control.animation = am:CreateTimeline()
-	local animation = control.animation
-	animation:SetPlaybackType(ANIMATION_SIZE, 0)	--2nd arg = loop count
-	--animation:SetDuration(1)
-	--animation:SetEasingFunction(ZO_LinearEase)	--is this needed?
-	--animation:SetHeightStartAndEnd(40, 80)	--SetStartAndEndHeight
-	--animation:SetStartAndEndHeight(40, 80)	--SetStartAndEndHeight
-	--animation:SetAnimatedControl(control)
-
-	control:SetResizeToFitDescendents(true)
-	control.open = false
-	label:SetHandler("OnMouseUp", AnimateSubmenu)
-	animation:SetHandler("OnStop", function(self, completedPlaying)
-			scroll:SetResizeToFitDescendents(control.open)
-			if control.open then
-				control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds")
-				scroll:SetResizeToFitPadding(5, 20)
-			else
-				control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")
-				scroll:SetResizeToFitPadding(5, 0)
-				scroll:SetHeight(0)
-			end
-		end)
-
-	--small strip at the bottom of the submenu that you can click to close it
-	control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE)
-	local btmToggle = control.btmToggle
-	btmToggle:SetMouseEnabled(true)
-	btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT)
-	btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT)
-	btmToggle:SetHeight(15)
-	btmToggle:SetAlpha(0)
-	btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
-
-	control.data = submenuData
-
-	control.UpdateValue = UpdateValue
-
-	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
-		tinsert(control.panel.controlsToRefresh, control)
-	end
-
-	return control
-end
-
+--[[submenuData = {
+	type = "submenu",
+	name = "Submenu Title",
+	tooltip = "My submenu tooltip",	--(optional)
+	controls = {sliderData, buttonData}	--(optional) used by LAM
+	reference = "MyAddonSubmenu"	--(optional) unique global reference to control
+}	]]
+
+local widgetVersion = 7
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("submenu", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local am = ANIMATION_MANAGER
+local tinsert = table.insert
+
+
+local function UpdateValue(control)
+	control.label:SetText(control.data.name)
+	if control.data.tooltip then
+		--control.label.tooltipText = control.data.tooltip
+		control.label.data = {tooltipText = control.data.tooltip}
+	end
+end
+
+local function AnimateSubmenu(clicked)
+	local control = clicked:GetParent()
+	control.open = not control.open
+
+	if control.open then
+		control.animation:PlayFromStart()
+	else
+		control.animation:PlayFromEnd()
+	end
+end
+
+
+function LAMCreateControl.submenu(parent, submenuData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or submenuData.reference)
+	control:SetParent(parent.scroll or parent)
+	control.panel = parent
+	control:SetDimensions(523, 40)
+
+	control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+	local label = control.label
+	label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
+	label:SetDimensions(520, 30)
+	label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+	label:SetText(submenuData.name)
+	label:SetMouseEnabled(true)
+	if submenuData.tooltip then
+		--label.tooltipText = submenuData.tooltip
+		label.data = {tooltipText = submenuData.tooltip}
+		label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+		label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+	end
+
+	control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
+	local scroll = control.scroll
+	scroll:SetParent(control)
+	scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10)
+	scroll:SetDimensionConstraints(525, 0, 525, 2500)
+
+	control.bg = wm:CreateControl(nil, label, CT_BACKDROP)
+	local bg = control.bg
+	bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5)
+	bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
+	bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
+	bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
+	bg:SetInsets(16, 16, -16, -16)
+
+	control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
+	local arrow = control.arrow
+	arrow:SetDimensions(28, 28)
+	arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")	--list_sortup for the other way
+	arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5)
+
+	--figure out the cool animation later...
+	control.animation = am:CreateTimeline()
+	local animation = control.animation
+	animation:SetPlaybackType(ANIMATION_SIZE, 0)	--2nd arg = loop count
+	--animation:SetDuration(1)
+	--animation:SetEasingFunction(ZO_LinearEase)	--is this needed?
+	--animation:SetHeightStartAndEnd(40, 80)	--SetStartAndEndHeight
+	--animation:SetStartAndEndHeight(40, 80)	--SetStartAndEndHeight
+	--animation:SetAnimatedControl(control)
+
+	control:SetResizeToFitDescendents(true)
+	control.open = false
+	label:SetHandler("OnMouseUp", AnimateSubmenu)
+	animation:SetHandler("OnStop", function(self, completedPlaying)
+			scroll:SetResizeToFitDescendents(control.open)
+			if control.open then
+				control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds")
+				scroll:SetResizeToFitPadding(5, 20)
+			else
+				control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")
+				scroll:SetResizeToFitPadding(5, 0)
+				scroll:SetHeight(0)
+			end
+		end)
+
+	--small strip at the bottom of the submenu that you can click to close it
+	control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE)
+	local btmToggle = control.btmToggle
+	btmToggle:SetMouseEnabled(true)
+	btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT)
+	btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT)
+	btmToggle:SetHeight(15)
+	btmToggle:SetAlpha(0)
+	btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
+
+	control.data = submenuData
+
+	control.UpdateValue = UpdateValue
+
+	if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then	--if our parent window wants to refresh controls, then add this to the list
+		tinsert(control.panel.controlsToRefresh, control)
+	end
+
+	return control
+end
+
diff --git a/Libs/LAM2/controls/texture.lua b/Libs/LAM2/controls/texture.lua
index 8ce85de..efb29ec 100644
--- a/Libs/LAM2/controls/texture.lua
+++ b/Libs/LAM2/controls/texture.lua
@@ -1,50 +1,51 @@
---[[textureData = {
-	type = "texture",
-	image = "file/path.dds",
-	imageWidth = 64,	--max of 250 for half width, 510 for full
-	imageHeight = 32,	--max of 100
-	tooltip = "Image's tooltip text.",	--(optional)
-	width = "full",	--or "half" (optional)
-	reference = "MyAddonTexture"	--(optional) unique global reference to control
-}	]]
-
---add texture coords support?
-
-local widgetVersion = 3
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("texture", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-function LAMCreateControl.texture(parent, textureData, controlName)
-	local control = wm:CreateTopLevelWindow(controlName or textureData.reference)
-	control:SetResizeToFitDescendents(true)
-	control:SetParent(parent.scroll or parent)
-
-	local isHalfWidth = textureData.width == "half"
-	if isHalfWidth then
-		control:SetDimensionConstraints(250, 55, 250, 100)
-		control:SetDimensions(250, 55)
-	else
-		control:SetDimensionConstraints(510, 30, 510, 100)
-		control:SetDimensions(510, 30)
-	end
-
-	control.texture = wm:CreateControl(nil, control, CT_TEXTURE)
-	local texture = control.texture
-	texture:SetAnchor(CENTER)
-	texture:SetDimensions(textureData.imageWidth, textureData.imageHeight)
-	texture:SetTexture(textureData.image)
-
-	if textureData.tooltip then
-		texture:SetMouseEnabled(true)
-		texture.tooltipText = textureData.tooltip
-		texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-		texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseExit)
-	end
-
-	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
-	control.data = textureData
-
-	return control
+--[[textureData = {
+	type = "texture",
+	image = "file/path.dds",
+	imageWidth = 64,	--max of 250 for half width, 510 for full
+	imageHeight = 32,	--max of 100
+	tooltip = "Image's tooltip text.",	--(optional)
+	width = "full",	--or "half" (optional)
+	reference = "MyAddonTexture"	--(optional) unique global reference to control
+}	]]
+
+--add texture coords support?
+
+local widgetVersion = 5
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("texture", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+function LAMCreateControl.texture(parent, textureData, controlName)
+	local control = wm:CreateTopLevelWindow(controlName or textureData.reference)
+	control:SetResizeToFitDescendents(true)
+	control:SetParent(parent.scroll or parent)
+
+	local isHalfWidth = textureData.width == "half"
+	if isHalfWidth then
+		control:SetDimensionConstraints(250, 55, 250, 100)
+		control:SetDimensions(250, 55)
+	else
+		control:SetDimensionConstraints(510, 30, 510, 100)
+		control:SetDimensions(510, 30)
+	end
+
+	control.texture = wm:CreateControl(nil, control, CT_TEXTURE)
+	local texture = control.texture
+	texture:SetAnchor(CENTER)
+	texture:SetDimensions(textureData.imageWidth, textureData.imageHeight)
+	texture:SetTexture(textureData.image)
+
+	if textureData.tooltip then
+		texture:SetMouseEnabled(true)
+		--texture.tooltipText = textureData.tooltip
+		texture.data = {tooltipText = textureData.tooltip}
+		texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+		texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseExit)
+	end
+
+	control.panel = parent.panel or parent	--if this is in a submenu, panel is its parent
+	control.data = textureData
+
+	return control
 end
\ No newline at end of file
diff --git a/doc/changelog.txt b/doc/changelog.txt
index 5e12c21..e2e00ea 100644
--- a/doc/changelog.txt
+++ b/doc/changelog.txt
@@ -2,7 +2,7 @@
 	New Feature
 	None
 	Bugs Fixed
-	Styles not showing highlighted on first load
+	Styles not showing highlighted on first load. Disabled tooltips causing error. Updated LibAddonMenu to 2.0.r16

 2014-12-12 V3.1.6
 	New Feature