Merge pull request #38 from AssemblerManiac/master

manavortex [04-01-18 - 14:52]
Merge pull request #38 from AssemblerManiac/master

libaddon menu v25; iifa popup location colors; out of bounds sortbar
Filename
IIfA/IIfA.lua
IIfA/IIfA.xml
IIfA/IIfABackpack.lua
IIfA/IIfAMenu.lua
IIfA/IIfATooltip.lua
IIfA/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
IIfA/libs/LibAddonMenu-2.0/controls/button.lua
IIfA/libs/LibAddonMenu-2.0/controls/dropdown.lua
IIfA/libs/LibAddonMenu-2.0/controls/slider.lua
diff --git a/IIfA/IIfA.lua b/IIfA/IIfA.lua
index a9ffce4..63d4b27 100644
--- a/IIfA/IIfA.lua
+++ b/IIfA/IIfA.lua
@@ -34,7 +34,7 @@ local BANK = ZO_PlayerBankBackpack
 local ITEMTOOLTIP = ZO_ItemToolTip
 local POPUPTOOLTIP = ZO_PopupToolTip

-local IIFA_COLORDEF_DEFAULT = ZO_ColorDef:New("3399FF")
+local IIFA_COLOR_DEFAULT = ZO_ColorDef:New("3399FF")

 local task 			= IIfA.task or LibStub("LibAsync"):Create("IIfA_DataCollection")
 IIfA.task			= task
@@ -159,6 +159,45 @@ function IIfA:StatusAlert(message)
 	end
 end

+function IIfA:TextColorFixup(settings)
+	d("settings.TextColorsCraftBag = " .. settings.TextColorsCraftBag)
+	if settings.TextColorsToon == nil then
+		if settings.in2TextColors then
+			d("old = " .. settings.in2TextColors)
+			self.colorHandlerToon = ZO_ColorDef:New(settings.in2TextColors)
+			self.colorHandlerBank = ZO_ColorDef:New(settings.in2TextColors)
+			self.colorHandlerGBank = ZO_ColorDef:New(settings.in2TextColors)
+			self.colorHandlerHouse = ZO_ColorDef:New(settings.in2TextColors)
+			self.colorHandlerHouseChest = ZO_ColorDef:New(settings.in2TextColors)
+			self.colorHandlerCraftBag = ZO_ColorDef:New(settings.in2TextColors)
+		else
+			d("Using default textcolors")
+			self.colorHandlerToon = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+			self.colorHandlerBank = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+			self.colorHandlerGBank = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+			self.colorHandlerHouse = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+			self.colorHandlerHouseChest = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+			self.colorHandlerCraftBag = ZO_ColorDef:New(IIFA_COLOR_DEFAULT:ToHex())
+		end
+		settings.TextColorsToon = self.colorHandlerToon:ToHex()
+		settings.TextColorsBank = self.colorHandlerBank:ToHex()
+		settings.TextColorsGBank = self.colorHandlerGBank:ToHex()
+		settings.TextColorsHouse = self.colorHandlerHouse:ToHex()
+		settings.TextColorsHouseChest = self.colorHandlerHouse:ToHex()
+		settings.TextColorsCraftBag = self.colorHandlerCraftBag:ToHex()
+		settings.in2TextColors = nil
+	else
+		d("using saved textcolors")
+		self.colorHandlerToon = ZO_ColorDef:New(settings.TextColorsToon)
+		self.colorHandlerBank = ZO_ColorDef:New(settings.TextColorsBank)
+		self.colorHandlerGBank = ZO_ColorDef:New(settings.TextColorsGBank)
+		self.colorHandlerHouse = ZO_ColorDef:New(settings.TextColorsHouse)
+		self.colorHandlerHouseChest = ZO_ColorDef:New(settings.TextColorsHouseChest)
+		self.colorHandlerCraftBag = ZO_ColorDef:New(settings.TextColorsCraftBag)
+	end
+end
+
+
 function IIfA_onLoad(eventCode, addOnName)
 	if (addOnName ~= "IIfA") then
 		return
@@ -176,7 +215,6 @@ function IIfA_onLoad(eventCode, addOnName)
 	local defaultGlobal = {
 		saveSettingsGlobally 	= true,
 		bDebug 					= false,
-		in2TextColors 			= IIFA_COLORDEF_DEFAULT:ToHex(),
 		showItemCountOnRight 	= true,
 		showItemStats			= false,
 		b_collectHouses			= false,
@@ -209,7 +247,6 @@ function IIfA_onLoad(eventCode, addOnName)

 	-- initializing default values
 	local default = {
-		in2TextColors = IIFA_COLORDEF_DEFAULT:ToHex(),
 		showItemCountOnRight	= true,
 		showItemStats			= false,

@@ -391,7 +428,8 @@ function IIfA_onLoad(eventCode, addOnName)
 	_, point, relTo, relPoint, offsX, offsY = IIFA_GUI_ListHolder:GetAnchor(1)
 	IIFA_GUI_ListHolder.savedAnchor2 = {point, relTo, relPoint, offsX, offsY}

-	IIfA.colorHandler = ZO_ColorDef:New(ObjSettings.in2TextColors)
+	IIfA:TextColorFixup(IIfA:GetSettings())
+
 	SLASH_COMMANDS["/ii"] = IIfA_SlashCommands
 	IIfA:CreateSettingsWindow(IIfA.settings, default)

diff --git a/IIfA/IIfA.xml b/IIfA/IIfA.xml
index efe9728..9a06aff 100644
--- a/IIfA/IIfA.xml
+++ b/IIfA/IIfA.xml
@@ -152,7 +152,7 @@
 						<Control name="$(parent)_Filter" mouseEnabled="true">
 							<Dimensions x="300" y="30" />
 							<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="30" offsetY="80"/>
-							<Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="TOPRIGHT" offsetX="50" offsetY="110"/>
+							<Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="TOPRIGHT" offsetX="-10" offsetY="110"/>
 							<Controls>
 								<Button name="$(parent)_Button0">
 									<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
diff --git a/IIfA/IIfABackpack.lua b/IIfA/IIfABackpack.lua
index 1d9dbce..f1fa1e7 100644
--- a/IIfA/IIfABackpack.lua
+++ b/IIfA/IIfABackpack.lua
@@ -664,11 +664,21 @@ function IIfA:QueryAccountInventory(itemLink)
 						newLocation = {}
 						newLocation.name = locationName

-						if location.bagID >= BAG_HOUSE_BANK_ONE and location.bagID <= BAG_HOUSE_BANK_TEN then -- location is a housing chest
+						if location.bagID == BAG_WORN or location.bagID == BAG_BACKPACK then
+							newLocation.bagLoc = BAG_BACKPACK
+						elseif location.bagID == BAG_BANK or location.bagID == BAG_SUBSCRIBER_BANK then
+							newLocation.bagLoc = BAG_BANK
+						elseif location.bagID == BAG_VIRTUAL then
+							newLocation.bagLoc = BAG_VIRTUAL
+						elseif location.bagID == BAG_GUILDBANK then
+							newLocation.bagLoc = BAG_GUILDBANK
+						elseif location.bagID >= BAG_HOUSE_BANK_ONE and location.bagID <= BAG_HOUSE_BANK_TEN then -- location is a housing chest
 							newLocation.name = GetCollectibleNickname(locationName)
 							if newLocation.name == IIfA.EMPTY_STRING then newLocation.name = GetCollectibleName(locationName) end
+							newLocation.bagLoc = BAG_HOUSE_BANK_ONE
 						elseif location.bagID == locationName then	-- location is a house
 							newLocation.name = GetCollectibleName(locationName)
+							newLocation.bagLoc = 99
 						end

 						newLocation.itemsFound = itemCount
diff --git a/IIfA/IIfAMenu.lua b/IIfA/IIfAMenu.lua
index 13f188f..f4decfa 100644
--- a/IIfA/IIfAMenu.lua
+++ b/IIfA/IIfAMenu.lua
@@ -353,21 +353,76 @@ function IIfA:CreateOptionsMenu()
 					setFunc = function(value) 	IIfA:GetSettings().showStyleInfo = value end,
 				}, -- checkbox end

-				 {
+				{
+					type = "colorpicker",
+					name = 'Tooltip Owner Text Color - Characters',
+					tooltip = 'Sets the color of the text for the chacter owner information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerToon:UnpackRGBA() end,
+					setFunc = function(...)
+						IIfA.colorHandlerToon:SetRGBA(...)
+						IIfA:GetSettings().TextColorsToon = IIfA.colorHandlerToon:ToHex()
+					end
+				},
+
+				{
+					type = "colorpicker",
+					name = 'Tooltip Owner Text Color - Banks',
+					tooltip = 'Sets the color of the text for the bank owner information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerBank:UnpackRGBA() end,
+					setFunc = function(...)
+						IIfA.colorHandlerBank:SetRGBA(...)
+						IIfA:GetSettings().TextColorsBank = IIfA.colorHandlerBank:ToHex()
+					end
+				},
+
+				{
+					type = "colorpicker",
+					name = 'Tooltip Owner Text Color - Guild Banks',
+					tooltip = 'Sets the color of the text for guild bank owner information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerGBank:UnpackRGBA() end,
+					setFunc = function(...)
+						IIfA.colorHandlerGBank:SetRGBA(...)
+						IIfA:GetSettings().TextColorsGBank = IIfA.colorHandlerGBank:ToHex()
+					end
+				},
+
+				{
+					type = "colorpicker",
+					name = 'Tooltip Owner Text Color - House Chests',
+					tooltip = 'Sets the color of the text for housing container information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerHouseChest:UnpackRGBA() end,
+					setFunc = function(...)
+						IIfA.colorHandlerHouseChest:SetRGBA(...)
+						IIfA:GetSettings().TextColorsHouseChest = IIfA.colorHandlerHouseChest:ToHex()
+					end
+				},
+
+				{
+					type = "colorpicker",
+					name = 'Tooltip Owner Text Color - House Contents',
+					tooltip = 'Sets the color of the text for house location information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerHouse:UnpackRGBA() end,
+					setFunc = function(...)
+						IIfA.colorHandlerHouse:SetRGBA(...)
+						IIfA:GetSettings().TextColorsHouse = IIfA.colorHandlerHouse:ToHex()
+					end
+				},
+
+				{
 					type = "colorpicker",
-					name = 'Tooltip Inventory Information Text Color',
-					tooltip = 'Sets the color of the text for the inventory information that gets added to Tooltips.',
-					getFunc = function() return IIfA.colorHandler:UnpackRGBA() end,
+					name = 'Tooltip Owner Text Color - Craft Bag',
+					tooltip = 'Sets the color of the text for craft bag location information that gets added to Tooltips.',
+					getFunc = function() return IIfA.colorHandlerCraftBag:UnpackRGBA() end,
 					setFunc = function(...)
-						IIfA.colorHandler:SetRGBA(...)
-						IIfA:GetSettings().in2TextColors = IIfA.colorHandler:ToHex()
+						IIfA.colorHandlerCraftBag:SetRGBA(...)
+						IIfA:GetSettings().TextColorsCraftBag = IIfA.colorHandlerCraftBag:ToHex()
 					end
 				},

 				{
 					type = "dropdown",
 					name = "Tooltips Font",
-					tooltip = "The font used for location information added to both default and custom IN2 tooltips",
+					tooltip = "The font used for location information added to both default and custom tooltips",
 					choices = LMP:List('font'),
 					getFunc = function() return (IIfA:GetSettings().in2TooltipsFont or "ZoFontGame") end,
 					setFunc = function( choice )
@@ -379,7 +434,7 @@ function IIfA:CreateOptionsMenu()
 				{
 					type = "slider",
 					name = "Tooltip Font Size",
-					tooltip = "The font size used for location information added to both default and custom IIfA tooltips",
+					tooltip = "The font size used for location information added to both default and custom tooltips",
 					min = 5,
 					max = 40,
 					step = 1,
diff --git a/IIfA/IIfATooltip.lua b/IIfA/IIfATooltip.lua
index 95ff550..9c198b4 100644
--- a/IIfA/IIfATooltip.lua
+++ b/IIfA/IIfATooltip.lua
@@ -485,8 +485,20 @@ function IIfA:UpdateTooltip(tooltip)
   					if location.worn then
 						textOut = string.format("%s *", textOut)
 					end
-					-- p("IIfA:UpdateTooltip -> <<1>>", textOut)
-					tooltip:AddLine(IIfA.colorHandler:Colorize(textOut))
+					if location.bagLoc == BAG_BACKPACK then		-- all of the bagLocs are distilled down to single locations (bag_worn or bag_backpack are all bag_backpack for this table element)
+						textOut = IIfA.colorHandlerToon:Colorize(textOut)
+					elseif location.bagLoc == BAG_BANK then
+						textOut = IIfA.colorHandlerBank:Colorize(textOut)
+					elseif location.bagLoc == BAG_GUILDBANK then
+						textOut = IIfA.colorHandlerGBank:Colorize(textOut)
+					elseif location.bagLoc == BAG_HOUSE_BANK_ONE then
+						textOut = IIfA.colorHandlerHouse:Colorize(textOut)
+					elseif location.bagLoc == 99 then
+						textOut = IIfA.colorHandlerHouseChest:Colorize(textOut)
+					elseif location.bagLoc == BAG_VIRTUAL then
+						textOut = IIfA.colorHandlerCraftBag:Colorize(textOut)
+					end
+					tooltip:AddLine(textOut)
 				end
 			end
 		end
@@ -547,7 +559,20 @@ function IIfA:UpdateTooltip(tooltip)
 					if location.worn then
 						textOut = string.format("%s *", textOut)
 					end
-					tooltip:AddLine(IIfA.colorHandler:Colorize(textOut))
+					if location.bagLoc == BAG_BACKPACK then		-- all of the bagLocs are distilled down to single locations (bag_worn or bag_backpack are all bag_backpack for this table element)
+						textOut = IIfA.colorHandlerToon:Colorize(textOut)
+					elseif location.bagLoc == BAG_BANK then
+						textOut = IIfA.colorHandlerBank:Colorize(textOut)
+					elseif location.bagLoc == BAG_GUILDBANK then
+						textOut = IIfA.colorHandlerGBank:Colorize(textOut)
+					elseif location.bagLoc == BAG_HOUSE_BANK_ONE then
+						textOut = IIfA.colorHandlerHouse:Colorize(textOut)
+					elseif location.bagLoc == 99 then
+						textOut = IIfA.colorHandlerHouseChest:Colorize(textOut)
+					elseif location.bagLoc == BAG_VIRTUAL then
+						textOut = IIfA.colorHandlerCraftBag:Colorize(textOut)
+					end
+					tooltip:AddLine(textOut)
 				end
 			end
 		end
diff --git a/IIfA/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua b/IIfA/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
index cb97a2e..3c4ab31 100644
--- a/IIfA/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
+++ b/IIfA/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
@@ -4,7 +4,7 @@


 --Register LAM with LibStub
-local MAJOR, MINOR = "LibAddonMenu-2.0", 23
+local MAJOR, MINOR = "LibAddonMenu-2.0", 25
 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

@@ -340,6 +340,16 @@ local localization = {
         RELOAD_DIALOG_RELOAD_BUTTON = "Reload",
         RELOAD_DIALOG_DISCARD_BUTTON = "Discard",
     },
+    it = { -- provided by JohnnyKing
+        PANEL_NAME = "Addon",
+        VERSION = "Versione: <<X:1>>",
+        WEBSITE = "Visita il Sitoweb",
+        RELOAD_UI_WARNING = "Cambiare questa impostazione richiede un Ricarica UI al fine che faccia effetto.",
+        RELOAD_DIALOG_TITLE = "Ricarica UI richiesto",
+        RELOAD_DIALOG_TEXT = "Alcune modifiche richiedono un Ricarica UI al fine che facciano effetto. Sei sicuro di voler ricaricare ora o di voler annullare le modifiche?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Ricarica",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Annulla",
+    },
     fr = { -- provided by Ayantir
         PANEL_NAME = "Extensions",
         WEBSITE = "Visiter le site Web",
@@ -363,9 +373,21 @@ local localization = {
         VERSION = "Версия: <<X:1>>",
         WEBSITE = "Посетить сайт",
         PANEL_INFO_FONT = "RuESO/fonts/Univers57.otf|14|soft-shadow-thin",
+        RELOAD_UI_WARNING = "Для применения этой настройки необходима перезагрузка интерфейса.",
+        RELOAD_DIALOG_TITLE = "Необходима перезагрузка интерфейса",
+        RELOAD_DIALOG_TEXT = "Для применения некоторых изменений необходима перезагрузка интерфейса. Перезагрузить интерфейс сейчас или отменить изменения?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Перезагрузить",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Отменить изменения",
     },
-    es = { -- provided by silvereyes333
-        WEBSITE = "Vaya al sitio web",
+    es = { -- provided by Morganlefai, checked by Kwisatz
+        PANEL_NAME = "Configuración",
+        VERSION = "Versión: <<X:1>>",
+        WEBSITE = "Visita la página web",
+        RELOAD_UI_WARNING = "Cambiar este ajuste recargará la interfaz del usuario.",
+        RELOAD_DIALOG_TITLE = "Requiere recargar la interfaz",
+        RELOAD_DIALOG_TEXT = "Algunos cambios requieren recargar la interfaz para poder aplicarse. Quieres aplicar los cambios y recargar la interfaz?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Recargar",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Cancelar",
     },
     jp = { -- provided by k0ta0uchi
         PANEL_NAME = "アドオン設定",
@@ -377,6 +399,16 @@ local localization = {
         WEBSITE = "访问网站",
         PANEL_INFO_FONT = "EsoZh/fonts/univers57.otf|14|soft-shadow-thin",
     },
+    pl = { -- provided by EmiruTegryfon
+        PANEL_NAME = "Dodatki",
+        VERSION = "Wersja: <<X:1>>",
+        WEBSITE = "Odwiedź stronę",
+        RELOAD_UI_WARNING = "Zmiany będą widoczne po ponownym załadowaniu UI.",
+        RELOAD_DIALOG_TITLE = "Wymagane przeładowanie UI",
+        RELOAD_DIALOG_TEXT = "Niektóre zmiany wymagają ponownego załadowania UI. Czy chcesz teraz ponownie załadować, czy porzucić zmiany?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Przeładuj",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Porzuć",
+    },
 }

 util.L = ZO_ShallowTableCopy(localization[GetCVar("Language.2")], localization["en"])
@@ -409,7 +441,7 @@ local function ScrollDataIntoView(list, data)

     local scrollMin, scrollMax = list.scrollbar:GetMinMax()
     local scrollTop = list.scrollbar:GetValue()
-    local controlHeight = list.controlHeight
+    local controlHeight = list.uniformControlHeight or list.controlHeight
     local targetMin = controlHeight * (targetIndex - 1) - 64
     -- subtracting 64 ain't arbitrary, it's the maximum fading height
     -- (libraries/zo_templates/scrolltemplates.lua/UpdateScrollFade)
@@ -462,6 +494,7 @@ local function PopulateAddonList(addonList, filter)
     local entryList = ZO_ScrollList_GetDataList(addonList)
     local numEntries = 0
     local selectedData = nil
+    local selectionIsFinal = false

     ZO_ScrollList_Clear(addonList)

@@ -473,8 +506,14 @@ local function PopulateAddonList(addonList, filter)
             entryList[numEntries] = dataEntry
             -- select the first panel passing the filter, or the currently
             -- shown panel, but only if it passes the filter as well
-            if selectedData == nil or data.panel == lam.currentAddonPanel then
-                selectedData = data
+            if selectedData == nil or data.panel == lam.pendingAddonPanel or data.panel == lam.currentAddonPanel then
+                if not selectionIsFinal then
+                    selectedData = data
+                end
+                if data.panel == lam.pendingAddonPanel then
+                    lam.pendingAddonPanel = nil
+                    selectionIsFinal = true
+                end
             end
         else
             data.sortIndex = nil
@@ -568,6 +607,7 @@ function lam:OpenToPanel(panel)
         if addonData.panel == panel then
             selectedData = addonData
             ScrollDataIntoView(addonList, selectedData)
+            lam.pendingAddonPanel = addonData.panel
             break
         end
     end
@@ -713,12 +753,12 @@ local function CreateOptionsControls(panel)

                     err, anchorOffset, lastAddedControl, wasHalf = CreateAndAnchorWidget(parent, widgetData, offsetX, anchorOffset, lastAddedControl, wasHalf)
                     if err then
-                        PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, widgetData.name or "unnamed", addonID))
+                        PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, GetStringFromValue(widgetData.name or "unnamed"), addonID))
                     end

                     if isSubmenu then
                         if SetupCreationCalls(lastAddedControl, widgetData.controls) then
-                            PrintLater(("The sub menu '%s' of %s is missing some entries."):format(widgetData.name or "unnamed", addonID))
+                            PrintLater(("The sub menu '%s' of %s is missing some entries."):format(GetStringFromValue(widgetData.name or "unnamed"), addonID))
                         end
                     end
                 end
diff --git a/IIfA/libs/LibAddonMenu-2.0/controls/button.lua b/IIfA/libs/LibAddonMenu-2.0/controls/button.lua
index 89d5b08..82b5032 100644
--- a/IIfA/libs/LibAddonMenu-2.0/controls/button.lua
+++ b/IIfA/libs/LibAddonMenu-2.0/controls/button.lua
@@ -5,7 +5,7 @@
     tooltip = "Button's tooltip text.", -- string id or function returning a string (optional)
     width = "full", --or "half" (optional)
     disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    icon = "icon/path.dds", --(optional)
+    icon = "icon\\path.dds", --(optional)
     isDangerous = false, -- boolean, if set to true, the button text will be red and a confirmation dialog with the button label and warning text will show on click before the callback is executed (optional)
     warning = "Will need to reload the UI.", --(optional)
     reference = "MyAddonButton", -- unique global reference to control (optional)
diff --git a/IIfA/libs/LibAddonMenu-2.0/controls/dropdown.lua b/IIfA/libs/LibAddonMenu-2.0/controls/dropdown.lua
index 2349ba6..70e23bb 100644
--- a/IIfA/libs/LibAddonMenu-2.0/controls/dropdown.lua
+++ b/IIfA/libs/LibAddonMenu-2.0/controls/dropdown.lua
@@ -9,6 +9,7 @@
     choicesTooltips = {"tooltip 1", "tooltip 2", "tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
     sort = "name-up", --or "name-down", "numeric-up", "numeric-down", "value-up", "value-down", "numericvalue-up", "numericvalue-down" (optional) - if not provided, list will not be sorted
     width = "full", --or "half" (optional)
+    scrollable = true, -- boolean or number, if set the dropdown will feature a scroll bar if there are a large amount of choices and limit the visible lines to the specified number or 10 if true is used (optional)
     disabled = function() return db.someBooleanSetting end, --or boolean (optional)
     warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
     requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
@@ -17,7 +18,7 @@
 } ]]


-local widgetVersion = 16
+local widgetVersion = 18
 local LAM = LibStub("LibAddonMenu-2.0")
 if not LAM:RegisterWidget("dropdown", widgetVersion) then return end

@@ -125,7 +126,9 @@ local function UpdateChoices(control, choices, choicesValues, choicesTooltips)

     if choicesTooltips then
         assert(#choices == #choicesTooltips, "choices and choicesTooltips need to have the same size")
-        SetupTooltips(control.dropdown, choicesTooltips)
+        if not control.scrollHelper then -- only do this for non-scrollable
+            SetupTooltips(control.dropdown, choicesTooltips)
+        end
     end

     for i = 1, #choices do
@@ -134,6 +137,9 @@ local function UpdateChoices(control, choices, choicesValues, choicesTooltips)
         if choicesValues then
             entry.value = choicesValues[i]
         end
+        if choicesTooltips and control.scrollHelper then
+            entry.tooltip = choicesTooltips[i]
+        end
         control.choices[entry.value or entry.name] = entry.name
         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
@@ -149,6 +155,171 @@ local function GrabSortingInfo(sortInfo)
     return t
 end

+local DEFAULT_VISIBLE_ROWS = 10
+local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = 25 -- same as in zo_combobox.lua
+local CONTENT_PADDING = 24
+local SCROLLBAR_PADDING = 16
+local PADDING = GetMenuPadding() / 2 -- half the amount looks closer to the regular dropdown
+local ROUNDING_MARGIN = 0.01 -- needed to avoid rare issue with too many anchors processed
+local ScrollableDropdownHelper = ZO_Object:Subclass()
+
+function ScrollableDropdownHelper:New(...)
+    local object = ZO_Object.New(self)
+    object:Initialize(...)
+    return object
+end
+
+function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
+    local combobox = control.combobox
+    local dropdown = control.dropdown
+    self.parent = parent
+    self.control = control
+    self.combobox = combobox
+    self.dropdown = dropdown
+    self.visibleRows = visibleRows
+
+    -- clear anchors so we can adjust the width dynamically
+    dropdown.m_dropdown:ClearAnchors()
+    dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT)
+
+    -- handle dropdown or settingsmenu opening/closing
+    local function onShow() self:OnShow() end
+    local function onHide() self:OnHide() end
+    local function doHide() self:DoHide() end
+
+    ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow)
+    ZO_PreHook(dropdown, "HideDropdownInternal", onHide)
+    combobox:SetHandler("OnEffectivelyHidden", onHide)
+    parent:SetHandler("OnEffectivelyHidden", doHide)
+
+    -- dont fade entries near the edges
+    local scrollList = dropdown.m_scroll
+    scrollList.selectionTemplate = nil
+    scrollList.highlightTemplate = nil
+    ZO_ScrollList_EnableSelection(scrollList, "ZO_SelectionHighlight")
+    ZO_ScrollList_EnableHighlight(scrollList, "ZO_SelectionHighlight")
+    ZO_Scroll_SetUseFadeGradient(scrollList, false)
+
+    -- adjust scroll content anchor to mimic menu padding
+    local scroll = dropdown.m_dropdown:GetNamedChild("Scroll")
+    local anchor1 = {scroll:GetAnchor(0)}
+    local anchor2 = {scroll:GetAnchor(1)}
+    scroll:ClearAnchors()
+    scroll:SetAnchor(anchor1[2], anchor1[3], anchor1[4], anchor1[5] + PADDING, anchor1[6] + PADDING)
+    scroll:SetAnchor(anchor2[2], anchor2[3], anchor2[4], anchor2[5] - PADDING, anchor2[6] - PADDING)
+    ZO_ScrollList_Commit(scrollList)
+
+    -- hook mouse enter/exit
+    local function onMouseEnter(control) self:OnMouseEnter(control) end
+    local function onMouseExit(control) self:OnMouseExit(control) end
+
+    -- adjust row setup to mimic the highlight padding
+    local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
+    local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 2)
+    local oSetup = dataType1.setupCallback -- both types have the same setup function
+    local function SetupEntry(control, data, list)
+        oSetup(control, data, list)
+        control.m_label:SetAnchor(LEFT, nil, nil, 2)
+        -- no need to store old ones since we have full ownership of our dropdown controls
+        if not control.hookedMouseHandlers then --only do it once per control
+            control.hookedMouseHandlers = true
+            ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter)
+            ZO_PreHookHandler(control, "OnMouseExit", onMouseExit)
+            -- we could also just replace the handlers
+            --control:SetHandler("OnMouseEnter", onMouseEnter)
+            --control:SetHandler("OnMouseExit", onMouseExit)
+        end
+    end
+    dataType1.setupCallback = SetupEntry
+    dataType2.setupCallback = SetupEntry
+
+    -- adjust dimensions based on entries
+    local scrollContent = scroll:GetNamedChild("Contents")
+    ZO_PreHook(dropdown, "AddMenuItems", function()
+        local width = PADDING * 2 + zo_max(self:GetMaxWidth(), combobox:GetWidth())
+        local numItems = #dropdown.m_sortedItems
+        local anchorOffset = 0
+        if(numItems > self.visibleRows) then
+            width = width + CONTENT_PADDING + SCROLLBAR_PADDING
+            anchorOffset = -SCROLLBAR_PADDING
+            numItems = self.visibleRows
+        end
+        scrollContent:SetAnchor(BOTTOMRIGHT, nil, nil, anchorOffset)
+        local height = PADDING * 2 + numItems * (SCROLLABLE_ENTRY_TEMPLATE_HEIGHT + dropdown.m_spacing) - dropdown.m_spacing + ROUNDING_MARGIN
+        dropdown.m_dropdown:SetWidth(width)
+        dropdown.m_dropdown:SetHeight(height)
+    end)
+end
+
+function ScrollableDropdownHelper:OnShow()
+    local dropdown = self.dropdown
+    if dropdown.m_lastParent ~= ZO_Menus then
+        dropdown.m_lastParent = dropdown.m_dropdown:GetParent()
+        dropdown.m_dropdown:SetParent(ZO_Menus)
+        ZO_Menus:BringWindowToTop()
+    end
+end
+
+function ScrollableDropdownHelper:OnHide()
+    local dropdown = self.dropdown
+    if dropdown.m_lastParent then
+        dropdown.m_dropdown:SetParent(dropdown.m_lastParent)
+        dropdown.m_lastParent = nil
+    end
+end
+
+function ScrollableDropdownHelper:DoHide()
+    local dropdown = self.dropdown
+    if dropdown:IsDropdownVisible() then
+        dropdown:HideDropdown()
+    end
+end
+
+function ScrollableDropdownHelper:GetMaxWidth()
+    local dropdown = self.dropdown
+    local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
+
+    local dummy = dataType.pool:AcquireObject()
+    dataType.setupCallback(dummy, {
+        m_owner = dropdown,
+        name = "Dummy"
+    }, dropdown)
+
+    local maxWidth = 0
+    local label = dummy.m_label
+    local entries = dropdown.m_sortedItems
+    local numItems = #entries
+    for index = 1, numItems do
+        label:SetText(entries[index].name)
+        local width = label:GetTextWidth()
+        if (width > maxWidth) then
+            maxWidth = width
+        end
+    end
+
+    dataType.pool:ReleaseObject(dummy.key)
+    return maxWidth
+end
+
+function ScrollableDropdownHelper:OnMouseEnter(control)
+    -- call original code if we replace instead of hook the handler
+        --ZO_ScrollableComboBox_Entry_OnMouseEnter(control)
+    -- show tooltip
+    if control.m_data.tooltip then
+        InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
+        SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.m_data.tooltip))
+        InformationTooltipTopLevel:BringWindowToTop()
+    end
+end
+function ScrollableDropdownHelper:OnMouseExit(control)
+    -- call original code if we replace instead of hook the handler
+        --ZO_ScrollableComboBox_Entry_OnMouseExit(control)
+    -- hide tooltip
+    if control.m_data.tooltip then
+        ClearTooltip(InformationTooltip)
+    end
+end
+
 function LAMCreateControl.dropdown(parent, dropdownData, controlName)
     local control = LAM.util.CreateLabelAndContainerControl(parent, dropdownData, controlName)
     control.choices = {}
@@ -161,7 +332,7 @@ function LAMCreateControl.dropdown(parent, dropdownData, controlName)
     end
     local comboboxCount = (countControl.comboboxCount or 0) + 1
     countControl.comboboxCount = comboboxCount
-    control.combobox = wm:CreateControlFromVirtual(zo_strjoin(nil, name, "Combobox", comboboxCount), control.container, "ZO_ComboBox")
+    control.combobox = wm:CreateControlFromVirtual(zo_strjoin(nil, name, "Combobox", comboboxCount), control.container, dropdownData.scrollable and "ZO_ScrollableComboBox" or "ZO_ComboBox")

     local combobox = control.combobox
     combobox:SetAnchor(TOPLEFT)
@@ -172,6 +343,11 @@ function LAMCreateControl.dropdown(parent, dropdownData, controlName)
     local dropdown = control.dropdown
     dropdown:SetSortsItems(false) -- need to sort ourselves in order to be able to sort by value

+    if dropdownData.scrollable then
+        local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS
+        control.scrollHelper = ScrollableDropdownHelper:New(parent, control, visibleRows)
+    end
+
     ZO_PreHook(dropdown, "UpdateItems", function(self)
         assert(not self.m_sortsItems, "built-in dropdown sorting was reactivated, sorting is handled by LAM")
         if control.m_sortOrder ~= nil and control.m_sortType then
diff --git a/IIfA/libs/LibAddonMenu-2.0/controls/slider.lua b/IIfA/libs/LibAddonMenu-2.0/controls/slider.lua
index 209a7e7..bd721c5 100644
--- a/IIfA/libs/LibAddonMenu-2.0/controls/slider.lua
+++ b/IIfA/libs/LibAddonMenu-2.0/controls/slider.lua
@@ -9,7 +9,7 @@
     clampInput = true, -- boolean, if set to false the input won't clamp to min and max and allow any number instead (optional)
     decimals = 0, -- when specified the input value is rounded to the specified number of decimals (optional)
     autoSelect = false, -- boolean, automatically select everything in the text input field when it gains focus (optional)
-    inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional)
+    inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional)
     tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional)
     width = "full", --or "half" (optional)
     disabled = function() return db.someBooleanSetting end, --or boolean (optional)
@@ -77,7 +77,7 @@ end

 function LAMCreateControl.slider(parent, sliderData, controlName)
     local control = LAM.util.CreateLabelAndContainerControl(parent, sliderData, controlName)
-    local isInputOnRight = sliderData.inputLocation == "right"
+    local isInputOnRight = sliderData.inputLocation == "right"

     --skipping creating the backdrop...  Is this the actual slider texture?
     control.slider = wm:CreateControl(nil, control.container, CT_SLIDER)
@@ -104,7 +104,7 @@ function LAMCreateControl.slider(parent, sliderData, controlName)
     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)
+    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)

     control.minText = wm:CreateControl(nil, slider, CT_LABEL)
     local minText = control.minText
@@ -123,7 +123,7 @@ function LAMCreateControl.slider(parent, sliderData, controlName)
         control.slidervalueBG:SetDimensions(60, 26)
         control.slidervalueBG:SetAnchor(LEFT, slider, RIGHT, 5, 0)
     else
-        control.slidervalueBG:SetDimensions(50, 18)
+        control.slidervalueBG:SetDimensions(50, 16)
         control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
     end
     control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")