diff --git a/.gitignore b/.gitignore
index 9f11b75..aba02a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-.idea/
+.idea/
diff --git a/Roomba.lua b/Roomba.lua
index 8e63872..6f3af5b 100644
--- a/Roomba.lua
+++ b/Roomba.lua
@@ -1,390 +1,390 @@
---[[
--- Roomba
- - (Thanks to BalkiTheWise for the name)
- -
- ]]
-
-Roomba = ZO_Object:Subclass()
-
-function Roomba:New(...)
- local roomba = ZO_Object.New(self)
- roomba:Initialise(...)
- return roomba
-end
-
-local LAM = LibStub:GetLibrary("LibAddonMenu-1.0")
-local BACKPACK = ZO_PlayerInventoryBackpack.data
-local GUILDBANK = ZO_GuildBankBackpack.data
-local WM = WINDOW_MANAGER
-local DELAY = 100
-local settings = {}
-local format = " %3d"
-local containerHooks = { INVENTORY_BACKPACK, INVENTORY_BANK, INVENTORY_GUILD_BANK }
-local currentRun = {}
-
-local function GetItemID(link)
- return tonumber(string.match(string.match(link, "%d+:"), "%d+"))
-end
-
-local function GetInstanceId(target, slotId)
- for i,v in ipairs(target) do
- if v.data.slotIndex == slotId then return v.data.itemInstanceId end
- end
- return nil
-end
-
-local function FindSlot(target, slotId)
- for i,v in ipairs(target) do
- if v.data.slotIndex == slotId then return i,v.data end
- end
- return nil
-end
-
-local function ClearGuildDetails(guildId)
- return { name = GetGuildName(guildId),
- lookUp = {},
- duplicates = {},
- index = {}
- }
-end
-
-local function TableEntryCount(t)
- local i = next(t)
- local c = 0
- while i do
- c = c + 1
- i = next(t, i)
- end
- return c
-end
-
--- Who is your Guild and what do they do
-local function GetGuildDetails(self)
- for guildIndex = 1, GetNumGuilds() do
- local guildId = GetGuildId(guildIndex)
- if DoesGuildHavePrivilege(guildId, GUILD_PRIVILEGE_BANK_DEPOSIT) then
- self.guildInfo[guildId] = true
- end
- end
-end
-
--- Okay, let's see.
--- First we'll take current bag inventory.
-function Roomba:CheckWeHaveEnoughRoom()
- return CheckInventorySpaceAndWarn(5)
-end
-
-function Roomba:HaveStuffToStack()
- local bank = self.guildInfo[GetSelectedGuildBankId()]
- if type(bank) == "table" and next(bank.duplicates) then return true end
- return false
-end
-
-local checkingBank = false
-
--- Bank is ready! Find those duplicates!
-function Roomba:RoombaReady()
- if ZO_GuildBankBackpack:IsHidden() then return end
- -- Are we in the process of checking the bank?
- if not checkingBank then checkingBank = true else return end
-
- local selectedBankId = GetSelectedGuildBankId()
-
- if not self.guildInfo[selectedBankId] then return end
-
- self.guildInfo[selectedBankId] = ClearGuildDetails(selectedBankId)
- local bank = self.guildInfo[selectedBankId]
-
- -- We only need to store A) slots with items
- for index, slot in ipairs(GUILDBANK) do
- if slot.data.equipType == 0 then -- Equipped gear cannot be stacked
- local id = slot.data.itemInstanceId
- local count, stack = GetSlotStackSize(slot.data.bagId, slot.data.slotIndex)
- -- and B) slots with items that aren't full stacks or single unstackables
- if count ~= stack then
- if bank.lookUp[id] then -- If we've run across this item before
- if not bank.duplicates[id] then -- store the table reference as a duplicate
- bank.duplicates[id] = bank.lookUp[id]
- end
- else
- bank.lookUp[id] = {} -- It's a new item!
- end
- -- Now group all items by id
- table.insert(bank.lookUp[id], {slot = slot.data.slotIndex, count = count, texture = slot.data.iconFile, name = slot.data.name})
- end
- end
- end
- zo_callLater(function() checkingBank = nil end, 3000)
- if KEYBIND_STRIP:HasKeybindButtonGroup(self.runDescriptor) then
- KEYBIND_STRIP:UpdateKeybindButtonGroup(self.runDescriptor)
- end
- currentRun = {}
- self.control:SetHidden(true)
-end
-
---[[
-Right, so this got complicated. Simply calling TransferFromGuildBank did not seem reliable, it would perhaps
-transfer one item in the loop, and disregard the rest.
-
-So instead we're going event based responses. This has the problem of breaking up the flow in a way that might
-be a little complicated to follow, but I'll try to make it simple, if for the basic reason that I have to read
-this crap afterwards.
-
-Let's hope this works.
-]]--
-
-local cInstanceId = nil
-local cDuplicateList = nil
-local cSlotIdx = nil
-local cSlot = nil
-local baseSlot = nil
-local inBagCollection = nil
-local transitBag = nil
-local currentReturnIndex = nil
-
-local function ResetAll()
- cSlotIdx = nil
- cSlot = nil
- inBagCollection = {}
- baseSlot = nil
-end
-
-function Roomba:SelectGuildBank(...)
- local eventId, guildBankId = ...
- self.currentBank = guildBankId
- checkingBank = nil
-end
-
-function Roomba:ReturnItemsToBank(...)
- local error = ...
- local slot
- -- Now that we've stacked it all lets move it back
- currentReturnIndex, slot = next(inBagCollection)
- if slot then
- if error then
- return zo_callLater(function(...) self:ReturnItemsToBank() end, 2000)
- end
- if FindSlot(BACKPACK, slot.bagSlot) then
- self.text:SetText("Returning restacked " .. cSlot.name .. " to the Guild Bank")
- return TransferToGuildBank(INVENTORY_BACKPACK, slot.bagSlot)
- else
- -- we have a space, move to next
- table.remove(inBagCollection, currentReturnIndex)
- return zo_callLater(function(...) self:ReturnItemsToBank(...) end, DELAY)
- end
- else
- -- No more to move, we're complete
- EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR)
- EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED)
- -- Kick off the next transaction
- ResetAll()
- return zo_callLater(function() self:BeginProcess() end, DELAY)
- end
-end
-
-function Roomba:BankItemsReceived(...)
- local eventId, gslot = ...
- local id = GetInstanceId(GUILDBANK, gslot)
- if id ~= cInstanceId then return end
- -- We've moved one back! Remove it from contention
- local slot = table.remove(inBagCollection, currentReturnIndex)
- currentReturnIndex = nil
- return zo_callLater(function(...) self:ReturnItemsToBank() end, DELAY)
-end
-
-
-function Roomba:StartStacking()
- baseSlot = nil
- EVENT_MANAGER:UnregisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
- self.text:SetText("Stacking " .. cSlot.name .. " in inventory")
- for _,slot in pairs(inBagCollection) do
- if not baseSlot then
- -- We want to stack everything on this
- baseSlot = slot
- else
- baseSlot.count, baseSlot.stack = GetSlotStackSize(INVENTORY_BACKPACK, slot.bagSlot)
- -- Find out how much we can fit
- -- If it's too much, move all we can and target this slot as the next to fill
- if (baseSlot.stack - baseSlot.count) < slot.count then
- result = CallSecureProtected("PickupInventoryItem", INVENTORY_BACKPACK, slot.bagSlot)
- if (result) then
- result = CallSecureProtected("PlaceInInventory", INVENTORY_BACKPACK, baseSlot.bagSlot)
- end
- baseSlot = slot
- else -- Just move it all over
- result = CallSecureProtected("PickupInventoryItem", INVENTORY_BACKPACK, slot.bagSlot, slot.count)
- if (result) then result = CallSecureProtected("PlaceInInventory", INVENTORY_BACKPACK, baseSlot.bagSlot) end
- end
- ClearCursor()
- end
- end
- baseSlot = nil
- -- These events will loop the move back to the guild bank
- EVENT_MANAGER:RegisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR, function(...) self:ReturnItemsToBank() end)
- EVENT_MANAGER:RegisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED, function(...) self:BankItemsReceived(...) end)
- return zo_callLater(function(...) self:ReturnItemsToBank() end, DELAY)
-end
-
-
--- Event called that item has arrived
-function Roomba:ReceiveItems(...)
- if baseSlot then return end -- We're still stacking
- local _, bagId, slotId = ...
- if bagId ~= INVENTORY_BACKPACK then return end
- if not cInstanceId then return end
- if IsItemJunk(INVENTORY_BACKPACK, slotId) then
- SetItemIsJunk(INVENTORY_BACKPACK, slotId, false)
- return zo_callLater(function(...) self:ReceiveItems(...) end, 1000)
- end
- if not GetInstanceId(BACKPACK, slotId) then return end -- are we empty
- if GetInstanceId(BACKPACK, slotId) ~= cInstanceId then return end
- cSlot.bagSlot = slotId
- table.insert(inBagCollection, cSlot)
- -- If we have another slot to move
- if next(cDuplicateList, cSlotIdx) then
- cSlotIdx, cSlot = next(cDuplicateList, cSlotIdx)
- TransferFromGuildBank(cSlot.slot)
- else -- No more slots to move, let's stack them
- return zo_callLater(function() self:StartStacking() end, DELAY)
- end
-end
-
-function Roomba:BeginProcess()
- if ZO_GuildBankBackpack:IsHidden() then return end
- local bank = self.guildInfo[self.currentBank]
- if not bank then return end
- if not self:CheckWeHaveEnoughRoom() then return end
-
- ZO_MenuBar_SelectLastVisibleButton(ZO_PlayerInventoryTabs)
-
- cSlotIdx = nil
-
- -- Pull the next job off the stack
- cInstanceId, cDuplicateList = next(bank.duplicates, cInstanceId)
-
- if cInstanceId then currentRun[cInstanceId] = true end
-
- self.control:SetHidden(false)
- local index = TableEntryCount(currentRun)
- local total = TableEntryCount(bank.duplicates)
- ZO_StatusBar_SmoothTransition(self.speedRow.bar, index , total, FORCE_VALUE)
- self.speedRow.name:SetText(string.format(format, (index/total)*100) .. "%")
-
- if cDuplicateList then -- First off the rank
- cSlotIdx, cSlot = next(cDuplicateList, cSlotIdx)
-
- self.icon:SetTexture(cSlot.texture)
-
- -- Clear this batch
- inBagCollection = {}
- -- And start off the job
-
- -- If it suddenly doesn't exist, try the next in the list
- if not FindSlot(GUILDBANK, cSlot.slot) then return zo_callLater(function() self:BeginProcess() end, DELAY) end
-
- EVENT_MANAGER:RegisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, function(...) self:ReceiveItems(...) end)
- self.text:SetText("Retrieving " .. cSlot.name .. " from Guild Bank")
- TransferFromGuildBank(cSlot.slot)
- else
- -- Now rescan and show/hide roomba button
- self.control:SetHidden(true)
- self.text:SetText("Complete")
- self:RoombaReady()
- return false
- end
- return true
-end
-
-local function RoombaLoaded(eventCode, addOnName)
-
- if(addOnName ~= "Roomba") then
- return
- end
-
- ZO_CreateStringId("SI_BINDING_NAME_RUN_ROOMBA", "Run Roomba")
- ZO_CreateStringId("SI_BINDING_NAME_RESCAN_ROOMBA", "Rescan Bank")
-end
-
-function Roomba:InitialiseSettings()
-
- self.guildInfo = {}
- self.currentBank = 1
- self.CurrentState = CurrentState
- GetGuildDetails(self)
-
- self.runDescriptor = {
- alignment = KEYBIND_STRIP_ALIGN_LEFT,
- {
- name = "Run Roomba", -- or function that returns a name
- keybind = "RUN_ROOMBA",
- control = self,
- callback = function(descriptor) self:BeginProcess() end,
- visible = function(descriptor) return self:HaveStuffToStack() end,
- icon = [[Roomba\media\Roomba.dds]],
- },
- {
- name = "Scan Bank",
- keybind = "RESCAN_ROOMBA",
- control = self,
- callback = function(descriptor) self:RoombaReady() end,
- visible = function(descriptor) return ZO_GuildBankBackpackLoading:IsHidden() end,
- icon = [[Roomba\media\RoombaSearch.dds]],
- },
- }
-
-end
-
-function Roomba:Initialise(control)
- self.control = control
- self:InitialiseFrame()
- self:InitialiseSettings()
-
- local bGroup = self.runDescriptor
-
- EVENT_MANAGER:RegisterForEvent("RoombaGuildBankOpen", EVENT_OPEN_GUILD_BANK, function()
- self:InitialiseEvents()
- if not KEYBIND_STRIP:HasKeybindButtonGroup(bGroup) then
- KEYBIND_STRIP:AddKeybindButtonGroup(bGroup)
- end end)
- EVENT_MANAGER:RegisterForEvent("RoombaGuildBankClose", EVENT_CLOSE_GUILD_BANK, function()
- if KEYBIND_STRIP:HasKeybindButtonGroup(bGroup) then
- KEYBIND_STRIP:RemoveKeybindButtonGroup(bGroup)
- end
- self.control:SetHidden(true)
- ResetAll()
- self:UninitialiseEvents()
- end)
-end
-
-function Roomba:InitialiseEvents()
- -- Guild bank is evented to be ready, but wait a short while before processing.
- EVENT_MANAGER:RegisterForEvent("RoombaReady", EVENT_GUILD_BANK_ITEMS_READY, function() zo_callLater(function() self:RoombaReady() end, 1000) end)
- -- Clear the flag when swapping banks
- EVENT_MANAGER:RegisterForEvent("RoombaSelected", EVENT_GUILD_BANK_SELECTED, function(...) self:SelectGuildBank(...) end)
-end
-
-function Roomba:UninitialiseEvents()
- EVENT_MANAGER:UnregisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
- EVENT_MANAGER:UnregisterForEvent("RoombaSelected", EVENT_GUILD_BANK_SELECTED)
- EVENT_MANAGER:UnregisterForEvent("RoombaReady", EVENT_GUILD_BANK_ITEMS_READY)
- EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR)
- EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED)
-end
-
-function Roomba:InitialiseFrame()
- self.control:SetDrawLayer(DL_OVERLAY)
- self.speedRow = self.control:GetNamedChild("SpeedRow")
- self.speedRow.name:SetText(" 0%")
- self.icon = self.control:GetNamedChild("Icon")
- self.text = self.control:GetNamedChild("Description")
- self.text:SetText("...")
- ZO_StatusBar_SetGradientColor(self.speedRow.bar, ZO_XP_BAR_GRADIENT_COLORS)
- ZO_StatusBar_SmoothTransition(self.speedRow.bar, 0, 20, FORCE_VALUE)
-end
-
-function Roomba_Initialise(control)
- ROOMBA = Roomba:New(control)
-end
-
-
+--[[
+-- Roomba
+ - (Thanks to BalkiTheWise for the name)
+ -
+ ]]
+
+Roomba = ZO_Object:Subclass()
+
+function Roomba:New(...)
+ local roomba = ZO_Object.New(self)
+ roomba:Initialise(...)
+ return roomba
+end
+
+local LAM = LibStub:GetLibrary("LibAddonMenu-1.0")
+local BACKPACK = ZO_PlayerInventoryBackpack.data
+local GUILDBANK = ZO_GuildBankBackpack.data
+local WM = WINDOW_MANAGER
+local DELAY = 100
+local settings = {}
+local format = " %3d"
+local containerHooks = { INVENTORY_BACKPACK, INVENTORY_BANK, INVENTORY_GUILD_BANK }
+local currentRun = {}
+
+local function GetItemID(link)
+ return tonumber(string.match(string.match(link, "%d+:"), "%d+"))
+end
+
+local function GetInstanceId(target, slotId)
+ for i,v in ipairs(target) do
+ if v.data.slotIndex == slotId then return v.data.itemInstanceId end
+ end
+ return nil
+end
+
+local function FindSlot(target, slotId)
+ for i,v in ipairs(target) do
+ if v.data.slotIndex == slotId then return i,v.data end
+ end
+ return nil
+end
+
+local function ClearGuildDetails(guildId)
+ return { name = GetGuildName(guildId),
+ lookUp = {},
+ duplicates = {},
+ index = {}
+ }
+end
+
+local function TableEntryCount(t)
+ local i = next(t)
+ local c = 0
+ while i do
+ c = c + 1
+ i = next(t, i)
+ end
+ return c
+end
+
+-- Who is your Guild and what do they do
+local function GetGuildDetails(self)
+ for guildIndex = 1, GetNumGuilds() do
+ local guildId = GetGuildId(guildIndex)
+ if DoesGuildHavePrivilege(guildId, GUILD_PRIVILEGE_BANK_DEPOSIT) then
+ self.guildInfo[guildId] = true
+ end
+ end
+end
+
+-- Okay, let's see.
+-- First we'll take current bag inventory.
+function Roomba:CheckWeHaveEnoughRoom()
+ return CheckInventorySpaceAndWarn(5)
+end
+
+function Roomba:HaveStuffToStack()
+ local bank = self.guildInfo[GetSelectedGuildBankId()]
+ if type(bank) == "table" and next(bank.duplicates) then return true end
+ return false
+end
+
+local checkingBank = false
+
+-- Bank is ready! Find those duplicates!
+function Roomba:RoombaReady()
+ if ZO_GuildBankBackpack:IsHidden() then return end
+ -- Are we in the process of checking the bank?
+ if not checkingBank then checkingBank = true else return end
+
+ local selectedBankId = GetSelectedGuildBankId()
+
+ if not self.guildInfo[selectedBankId] then return end
+
+ self.guildInfo[selectedBankId] = ClearGuildDetails(selectedBankId)
+ local bank = self.guildInfo[selectedBankId]
+
+ -- We only need to store A) slots with items
+ for index, slot in ipairs(GUILDBANK) do
+ if slot.data.equipType == 0 then -- Equipped gear cannot be stacked
+ local id = slot.data.itemInstanceId
+ local count, stack = GetSlotStackSize(slot.data.bagId, slot.data.slotIndex)
+ -- and B) slots with items that aren't full stacks or single unstackables
+ if count ~= stack then
+ if bank.lookUp[id] then -- If we've run across this item before
+ if not bank.duplicates[id] then -- store the table reference as a duplicate
+ bank.duplicates[id] = bank.lookUp[id]
+ end
+ else
+ bank.lookUp[id] = {} -- It's a new item!
+ end
+ -- Now group all items by id
+ table.insert(bank.lookUp[id], {slot = slot.data.slotIndex, count = count, texture = slot.data.iconFile, name = slot.data.name})
+ end
+ end
+ end
+ zo_callLater(function() checkingBank = nil end, 3000)
+ if KEYBIND_STRIP:HasKeybindButtonGroup(self.runDescriptor) then
+ KEYBIND_STRIP:UpdateKeybindButtonGroup(self.runDescriptor)
+ end
+ currentRun = {}
+ self.control:SetHidden(true)
+end
+
+--[[
+Right, so this got complicated. Simply calling TransferFromGuildBank did not seem reliable, it would perhaps
+transfer one item in the loop, and disregard the rest.
+
+So instead we're going event based responses. This has the problem of breaking up the flow in a way that might
+be a little complicated to follow, but I'll try to make it simple, if for the basic reason that I have to read
+this crap afterwards.
+
+Let's hope this works.
+]]--
+
+local cInstanceId = nil
+local cDuplicateList = nil
+local cSlotIdx = nil
+local cSlot = nil
+local baseSlot = nil
+local inBagCollection = nil
+local transitBag = nil
+local currentReturnIndex = nil
+
+local function ResetAll()
+ cSlotIdx = nil
+ cSlot = nil
+ inBagCollection = {}
+ baseSlot = nil
+end
+
+function Roomba:SelectGuildBank(...)
+ local eventId, guildBankId = ...
+ self.currentBank = guildBankId
+ checkingBank = nil
+end
+
+function Roomba:ReturnItemsToBank(...)
+ local error = ...
+ local slot
+ -- Now that we've stacked it all lets move it back
+ currentReturnIndex, slot = next(inBagCollection)
+ if slot then
+ if error then
+ return zo_callLater(function(...) self:ReturnItemsToBank() end, 2000)
+ end
+ if FindSlot(BACKPACK, slot.bagSlot) then
+ self.text:SetText("Returning restacked " .. cSlot.name .. " to the Guild Bank")
+ return TransferToGuildBank(INVENTORY_BACKPACK, slot.bagSlot)
+ else
+ -- we have a space, move to next
+ table.remove(inBagCollection, currentReturnIndex)
+ return zo_callLater(function(...) self:ReturnItemsToBank(...) end, DELAY)
+ end
+ else
+ -- No more to move, we're complete
+ EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR)
+ EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED)
+ -- Kick off the next transaction
+ ResetAll()
+ return zo_callLater(function() self:BeginProcess() end, DELAY)
+ end
+end
+
+function Roomba:BankItemsReceived(...)
+ local eventId, gslot = ...
+ local id = GetInstanceId(GUILDBANK, gslot)
+ if id ~= cInstanceId then return end
+ -- We've moved one back! Remove it from contention
+ local slot = table.remove(inBagCollection, currentReturnIndex)
+ currentReturnIndex = nil
+ return zo_callLater(function(...) self:ReturnItemsToBank() end, DELAY)
+end
+
+
+function Roomba:StartStacking()
+ baseSlot = nil
+ EVENT_MANAGER:UnregisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
+ self.text:SetText("Stacking " .. cSlot.name .. " in inventory")
+ for _,slot in pairs(inBagCollection) do
+ if not baseSlot then
+ -- We want to stack everything on this
+ baseSlot = slot
+ else
+ baseSlot.count, baseSlot.stack = GetSlotStackSize(INVENTORY_BACKPACK, slot.bagSlot)
+ -- Find out how much we can fit
+ -- If it's too much, move all we can and target this slot as the next to fill
+ if (baseSlot.stack - baseSlot.count) < slot.count then
+ result = CallSecureProtected("PickupInventoryItem", INVENTORY_BACKPACK, slot.bagSlot)
+ if (result) then
+ result = CallSecureProtected("PlaceInInventory", INVENTORY_BACKPACK, baseSlot.bagSlot)
+ end
+ baseSlot = slot
+ else -- Just move it all over
+ result = CallSecureProtected("PickupInventoryItem", INVENTORY_BACKPACK, slot.bagSlot, slot.count)
+ if (result) then result = CallSecureProtected("PlaceInInventory", INVENTORY_BACKPACK, baseSlot.bagSlot) end
+ end
+ ClearCursor()
+ end
+ end
+ baseSlot = nil
+ -- These events will loop the move back to the guild bank
+ EVENT_MANAGER:RegisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR, function(...) self:ReturnItemsToBank() end)
+ EVENT_MANAGER:RegisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED, function(...) self:BankItemsReceived(...) end)
+ return zo_callLater(function(...) self:ReturnItemsToBank() end, DELAY)
+end
+
+
+-- Event called that item has arrived
+function Roomba:ReceiveItems(...)
+ if baseSlot then return end -- We're still stacking
+ local _, bagId, slotId = ...
+ if bagId ~= INVENTORY_BACKPACK then return end
+ if not cInstanceId then return end
+ if IsItemJunk(INVENTORY_BACKPACK, slotId) then
+ SetItemIsJunk(INVENTORY_BACKPACK, slotId, false)
+ return zo_callLater(function(...) self:ReceiveItems(...) end, 1000)
+ end
+ if not GetInstanceId(BACKPACK, slotId) then return end -- are we empty
+ if GetInstanceId(BACKPACK, slotId) ~= cInstanceId then return end
+ cSlot.bagSlot = slotId
+ table.insert(inBagCollection, cSlot)
+ -- If we have another slot to move
+ if next(cDuplicateList, cSlotIdx) then
+ cSlotIdx, cSlot = next(cDuplicateList, cSlotIdx)
+ TransferFromGuildBank(cSlot.slot)
+ else -- No more slots to move, let's stack them
+ return zo_callLater(function() self:StartStacking() end, DELAY)
+ end
+end
+
+function Roomba:BeginProcess()
+ if ZO_GuildBankBackpack:IsHidden() then return end
+ local bank = self.guildInfo[self.currentBank]
+ if not bank then return end
+ if not self:CheckWeHaveEnoughRoom() then return end
+
+ ZO_MenuBar_SelectLastVisibleButton(ZO_PlayerInventoryTabs)
+
+ cSlotIdx = nil
+
+ -- Pull the next job off the stack
+ cInstanceId, cDuplicateList = next(bank.duplicates, cInstanceId)
+
+ if cInstanceId then currentRun[cInstanceId] = true end
+
+ self.control:SetHidden(false)
+ local index = TableEntryCount(currentRun)
+ local total = TableEntryCount(bank.duplicates)
+ ZO_StatusBar_SmoothTransition(self.speedRow.bar, index , total, FORCE_VALUE)
+ self.speedRow.name:SetText(string.format(format, (index/total)*100) .. "%")
+
+ if cDuplicateList then -- First off the rank
+ cSlotIdx, cSlot = next(cDuplicateList, cSlotIdx)
+
+ self.icon:SetTexture(cSlot.texture)
+
+ -- Clear this batch
+ inBagCollection = {}
+ -- And start off the job
+
+ -- If it suddenly doesn't exist, try the next in the list
+ if not FindSlot(GUILDBANK, cSlot.slot) then return zo_callLater(function() self:BeginProcess() end, DELAY) end
+
+ EVENT_MANAGER:RegisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, function(...) self:ReceiveItems(...) end)
+ self.text:SetText("Retrieving " .. cSlot.name .. " from Guild Bank")
+ TransferFromGuildBank(cSlot.slot)
+ else
+ -- Now rescan and show/hide roomba button
+ self.control:SetHidden(true)
+ self.text:SetText("Complete")
+ self:RoombaReady()
+ return false
+ end
+ return true
+end
+
+local function RoombaLoaded(eventCode, addOnName)
+
+ if(addOnName ~= "Roomba") then
+ return
+ end
+
+ ZO_CreateStringId("SI_BINDING_NAME_RUN_ROOMBA", "Run Roomba")
+ ZO_CreateStringId("SI_BINDING_NAME_RESCAN_ROOMBA", "Rescan Bank")
+end
+
+function Roomba:InitialiseSettings()
+
+ self.guildInfo = {}
+ self.currentBank = 1
+ self.CurrentState = CurrentState
+ GetGuildDetails(self)
+
+ self.runDescriptor = {
+ alignment = KEYBIND_STRIP_ALIGN_LEFT,
+ {
+ name = "Run Roomba", -- or function that returns a name
+ keybind = "RUN_ROOMBA",
+ control = self,
+ callback = function(descriptor) self:BeginProcess() end,
+ visible = function(descriptor) return self:HaveStuffToStack() end,
+ icon = [[Roomba\media\Roomba.dds]],
+ },
+ {
+ name = "Scan Bank",
+ keybind = "RESCAN_ROOMBA",
+ control = self,
+ callback = function(descriptor) self:RoombaReady() end,
+ visible = function(descriptor) return ZO_GuildBankBackpackLoading:IsHidden() end,
+ icon = [[Roomba\media\RoombaSearch.dds]],
+ },
+ }
+
+end
+
+function Roomba:Initialise(control)
+ self.control = control
+ self:InitialiseFrame()
+ self:InitialiseSettings()
+
+ local bGroup = self.runDescriptor
+
+ EVENT_MANAGER:RegisterForEvent("RoombaGuildBankOpen", EVENT_OPEN_GUILD_BANK, function()
+ self:InitialiseEvents()
+ if not KEYBIND_STRIP:HasKeybindButtonGroup(bGroup) then
+ KEYBIND_STRIP:AddKeybindButtonGroup(bGroup)
+ end end)
+ EVENT_MANAGER:RegisterForEvent("RoombaGuildBankClose", EVENT_CLOSE_GUILD_BANK, function()
+ if KEYBIND_STRIP:HasKeybindButtonGroup(bGroup) then
+ KEYBIND_STRIP:RemoveKeybindButtonGroup(bGroup)
+ end
+ self.control:SetHidden(true)
+ ResetAll()
+ self:UninitialiseEvents()
+ end)
+end
+
+function Roomba:InitialiseEvents()
+ -- Guild bank is evented to be ready, but wait a short while before processing.
+ EVENT_MANAGER:RegisterForEvent("RoombaReady", EVENT_GUILD_BANK_ITEMS_READY, function() zo_callLater(function() self:RoombaReady() end, 1000) end)
+ -- Clear the flag when swapping banks
+ EVENT_MANAGER:RegisterForEvent("RoombaSelected", EVENT_GUILD_BANK_SELECTED, function(...) self:SelectGuildBank(...) end)
+end
+
+function Roomba:UninitialiseEvents()
+ EVENT_MANAGER:UnregisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
+ EVENT_MANAGER:UnregisterForEvent("RoombaSelected", EVENT_GUILD_BANK_SELECTED)
+ EVENT_MANAGER:UnregisterForEvent("RoombaReady", EVENT_GUILD_BANK_ITEMS_READY)
+ EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR)
+ EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED)
+end
+
+function Roomba:InitialiseFrame()
+ self.control:SetDrawLayer(DL_OVERLAY)
+ self.speedRow = self.control:GetNamedChild("SpeedRow")
+ self.speedRow.name:SetText(" 0%")
+ self.icon = self.control:GetNamedChild("Icon")
+ self.text = self.control:GetNamedChild("Description")
+ self.text:SetText("...")
+ ZO_StatusBar_SetGradientColor(self.speedRow.bar, ZO_XP_BAR_GRADIENT_COLORS)
+ ZO_StatusBar_SmoothTransition(self.speedRow.bar, 0, 20, FORCE_VALUE)
+end
+
+function Roomba_Initialise(control)
+ ROOMBA = Roomba:New(control)
+end
+
+
EVENT_MANAGER:RegisterForEvent("RoombaLoaded", EVENT_ADD_ON_LOADED, RoombaLoaded)
\ No newline at end of file
diff --git a/Roomba.txt b/Roomba.txt
index 77c2b5b..1baa5fd 100644
--- a/Roomba.txt
+++ b/Roomba.txt
@@ -1,12 +1,12 @@
-## APIVersion: 100007
-## Title: |cFFFFB0Roomba|r by |c00C000Wobin & CrazyDutchGuy|r
-## Description: Your favorite guild bank cleaner ;)
-## Author: Wobin & CrazyDutchGuy
-## Version: @project-version@
-
-libs/LibStub/LibStub.lua
-libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
-
-Roomba.lua
-Roomba.xml
-bindings.xml
\ No newline at end of file
+## APIVersion: 100008
+## Title: |cFFFFB0Roomba|r by |c00C000Wobin & CrazyDutchGuy|r
+## Description: Your favorite guild bank cleaner ;)
+## Author: Wobin & CrazyDutchGuy
+## Version: @project-version@
+
+libs/LibStub/LibStub.lua
+libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
+
+Roomba.lua
+Roomba.xml
+bindings.xml
diff --git a/Roomba.xml b/Roomba.xml
index 053513e..3c0b915 100644
--- a/Roomba.xml
+++ b/Roomba.xml
@@ -1,29 +1,29 @@
-<GuiXml>
- <Controls>
- <TopLevelControl name="RoombaWindow" hidden="true" mouseEnabled="true">
- <Dimensions x="565" />
- <Anchor point="TOPLEFT" relativeTo="ZO_SharedRightPanelBackground" offsetY="90" />
- <Anchor point="BOTTOMLEFT" relativeTo="ZO_SharedRightPanelBackground" offsetY="-20" />
- <OnInitialized>
- Roomba_Initialise(self)
- </OnInitialized>
- <Controls>
- <Texture name="$(parent)BG" textureFile="EsoUI/Art/Miscellaneous/listItem_backdrop.dds">
- <AnchorFill />
- <TextureCoords left="0" right="1" top="0" bottom=".8125" />
- </Texture>
- <Texture name="$(parent)Icon">
- <Dimensions x="80" y="80" />
- <Anchor point="BOTTOM" relativePoint="CENTER" offsetX="20" offsetY="-40" />
- </Texture>
- <Label name="$(parent)Description" inherits="ZO_TooltipIfTruncatedLabel" font="ZoFontGameMedium" color="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_SECOND_CONTRAST" horizontalAlignment="CENTER">
- <Anchor point="TOPLEFT" relativeTo="$(parent)Icon" relativePoint="BOTTOM" offsetY="5" offsetX="-300"/>
- <Dimensions x="600" y="40" />
- </Label>
- <Control name="$(parent)SpeedRow" inherits="ZO_StableAttributeRow">
- <Anchor point="TOP" relativeTo="$(parent)Icon" relativePoint="BOTTOM" offsetY="30" offsetX="30"/>
- </Control>
- </Controls>
- </TopLevelControl>
- </Controls>
+<GuiXml>
+ <Controls>
+ <TopLevelControl name="RoombaWindow" hidden="true" mouseEnabled="true">
+ <Dimensions x="565" />
+ <Anchor point="TOPLEFT" relativeTo="ZO_SharedRightPanelBackground" offsetY="90" />
+ <Anchor point="BOTTOMLEFT" relativeTo="ZO_SharedRightPanelBackground" offsetY="-20" />
+ <OnInitialized>
+ Roomba_Initialise(self)
+ </OnInitialized>
+ <Controls>
+ <Texture name="$(parent)BG" textureFile="EsoUI/Art/Miscellaneous/listItem_backdrop.dds">
+ <AnchorFill />
+ <TextureCoords left="0" right="1" top="0" bottom=".8125" />
+ </Texture>
+ <Texture name="$(parent)Icon">
+ <Dimensions x="80" y="80" />
+ <Anchor point="BOTTOM" relativePoint="CENTER" offsetX="20" offsetY="-40" />
+ </Texture>
+ <Label name="$(parent)Description" inherits="ZO_TooltipIfTruncatedLabel" font="ZoFontGameMedium" color="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_SECOND_CONTRAST" horizontalAlignment="CENTER">
+ <Anchor point="TOPLEFT" relativeTo="$(parent)Icon" relativePoint="BOTTOM" offsetY="5" offsetX="-300"/>
+ <Dimensions x="600" y="40" />
+ </Label>
+ <Control name="$(parent)SpeedRow" inherits="ZO_StableAttributeRow">
+ <Anchor point="TOP" relativeTo="$(parent)Icon" relativePoint="BOTTOM" offsetY="30" offsetX="30"/>
+ </Control>
+ </Controls>
+ </TopLevelControl>
+ </Controls>
</GuiXml>
\ No newline at end of file
diff --git a/bindings.xml b/bindings.xml
index 8610eca..ffed6ea 100644
--- a/bindings.xml
+++ b/bindings.xml
@@ -1,12 +1,12 @@
-<Bindings>
- <Layer name="General">
- <Category name="Roomba">
- <Action name="RUN_ROOMBA">
- <Down>ROOMBA:BeginProcess()</Down>
- </Action>
- <Action name="RESCAN_ROOMBA">
- <Down>ROOMBA:RoombaReady()</Down>
- </Action>
- </Category>
- </Layer>
+<Bindings>
+ <Layer name="General">
+ <Category name="Roomba">
+ <Action name="RUN_ROOMBA">
+ <Down>ROOMBA:BeginProcess()</Down>
+ </Action>
+ <Action name="RESCAN_ROOMBA">
+ <Down>ROOMBA:RoombaReady()</Down>
+ </Action>
+ </Category>
+ </Layer>
</Bindings>
\ No newline at end of file
diff --git a/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua b/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
index 7e382b1..d7a547c 100644
--- a/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
+++ b/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
@@ -1,373 +1,373 @@
-local MAJOR, MINOR = "LibAddonMenu-1.0", 6
-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--
-lam.lastAddedControl = {}
-local lastAddedControl = lam.lastAddedControl
-local wm = GetWindowManager()
-local strformat = string.format
-local tostring = tostring
-local round = zo_round
-local optionsWindow = ZO_OptionsWindowSettingsScrollChild
-
---maybe return the controls from the creation functions?
-
-function lam:CreateControlPanel(controlPanelID, controlPanelName)
- local panelID
-
- if _G[controlPanelID] then
- panelID = _G[controlPanelID]
- return panelID
- end
-
- ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelName)
-
- --disables Defaults button because we don't need it, but keybind still works :/ ...
- panelID = _G[controlPanelID]
- ZO_PreHook("ZO_OptionsWindow_ChangePanels", function(panel)
- local enable = (panel ~= panelID)
- ZO_OptionsWindowResetToDefaultButton:SetEnabled(enable)
- ZO_OptionsWindowResetToDefaultButton:SetKeybindEnabled(enable)
- end)
-
- return panelID
-end
-
-function lam:AddHeader(panelID, controlName, text)
- local header = wm:CreateControlFromVirtual(controlName, optionsWindow, lastAddedControl[panelID] and "ZO_Options_SectionTitle_WithDivider" or "ZO_Options_SectionTitle")
- if lastAddedControl[panelID] then
- header:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 15)
- else
- header:SetAnchor(TOPLEFT)
- end
- header.controlType = OPTIONS_SECTION_TITLE
- header.panel = panelID
- header.text = text
-
- ZO_OptionsWindow_InitializeControl(header)
-
- lastAddedControl[panelID] = header
-
- return header
-end
-
-
---To-Do list:
---extra sub-options window out to the right?? (or maybe addon list?)
---find alternatives to handler hooks
-
-function lam:AddSlider(panelID, controlName, text, tooltip, minValue, maxValue, step, getFunc, setFunc, warning, warningText)
- local slider = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Slider")
- slider:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
- slider.controlType = OPTIONS_SLIDER
- slider.system = SETTING_TYPE_UI
- slider.panel = panelID
- slider.text = text
- slider.tooltipText = tooltip
- slider.showValue = true
- slider.showValueMin = minValue
- slider.showValueMax = maxValue
- local range = maxValue - minValue
- local slidercontrol = slider:GetNamedChild("Slider")
- local slidervalue = slider:GetNamedChild("ValueLabel")
- slidercontrol:SetValueStep(1/range * step)
- slider:SetHandler("OnShow", function()
- local curValue = getFunc()
- slidercontrol:SetValue((curValue - minValue)/range)
- slidervalue:SetText(tostring(curValue))
- end)
- slidercontrol:SetHandler("OnValueChanged", function (self, value)
- self:SetValue(value)
- value = round(value*range + minValue)
- slidervalue:SetText(strformat("%d", value))
- end)
- slidercontrol:SetHandler("OnSliderReleased", function(self, value)
- value = round(value*range + minValue)
- setFunc(value)
- end)
-
- if warning then
- slider.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", slider, "ZO_Options_WarningIcon")
- slider.warning:SetAnchor(RIGHT, slidercontrol, LEFT, -5, 0)
- slider.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(slider)
-
- lastAddedControl[panelID] = slider
-
- return slider
-end
-
-function lam:AddDropdown(panelID, controlName, text, tooltip, validChoices, getFunc, setFunc, warning, warningText)
- local dropdown = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Dropdown")
- dropdown:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
- dropdown.controlType = OPTIONS_DROPDOWN
- dropdown.system = SETTING_TYPE_UI
- dropdown.panel = panelID
- dropdown.text = text
- dropdown.tooltipText = tooltip
- dropdown.valid = validChoices
- local dropmenu = ZO_ComboBox_ObjectFromContainer(GetControl(dropdown, "Dropdown"))
- local setText = dropmenu.m_selectedItemText.SetText
- local selectedName
- ZO_PreHookHandler(dropmenu.m_selectedItemText, "OnTextChanged", function(self)
- if dropmenu.m_selectedItemData then
- selectedName = dropmenu.m_selectedItemData.name
- setText(self, selectedName)
- setFunc(selectedName)
- end
- end)
- dropdown:SetHandler("OnShow", function()
- dropmenu:SetSelectedItem(getFunc())
- end)
-
- if warning then
- dropdown.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", dropdown, "ZO_Options_WarningIcon")
- dropdown.warning:SetAnchor(RIGHT, dropdown:GetNamedChild("Dropdown"), LEFT, -5, 0)
- dropdown.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(dropdown)
-
- lastAddedControl[panelID] = dropdown
-
- return dropdown
-end
-
-function lam:AddCheckbox(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText)
- local checkbox = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Checkbox")
- checkbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
- checkbox.controlType = OPTIONS_CHECKBOX
- checkbox.system = SETTING_TYPE_UI
- checkbox.settingId = _G[strformat("SETTING_%s", controlName)]
- checkbox.panel = panelID
- checkbox.text = text
- checkbox.tooltipText = tooltip
-
- local checkboxButton = checkbox:GetNamedChild("Checkbox")
-
- ZO_PreHookHandler(checkbox, "OnShow", function()
- checkboxButton:SetState(getFunc() and 1 or 0)
- checkboxButton:toggleFunction(getFunc())
- end)
- ZO_PreHookHandler(checkboxButton, "OnClicked", function() setFunc(not getFunc()) end)
-
- if warning then
- checkbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", checkbox, "ZO_Options_WarningIcon")
- checkbox.warning:SetAnchor(RIGHT, checkboxButton, LEFT, -5, 0)
- checkbox.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(checkbox)
-
- lastAddedControl[panelID] = checkbox
-
- return checkbox
-end
-
-function lam:AddColorPicker(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText)
- local colorpicker = wm:CreateTopLevelWindow(controlName)
- colorpicker:SetParent(optionsWindow)
- colorpicker:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
- colorpicker:SetResizeToFitDescendents(true)
- colorpicker:SetWidth(510)
- colorpicker:SetMouseEnabled(true)
-
- colorpicker.label = wm:CreateControl(controlName.."Label", colorpicker, CT_LABEL)
- local label = colorpicker.label
- label:SetDimensions(300, 26)
- label:SetAnchor(TOPLEFT)
- label:SetFont("ZoFontWinH4")
- label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
- label:SetText(text)
-
- colorpicker.color = wm:CreateControl(controlName.."Color", colorpicker, CT_CONTROL)
- local color = colorpicker.color
- color:SetDimensions(200,26)
- color:SetAnchor(RIGHT)
-
- color.thumb = wm:CreateControl(controlName.."ColorThumb", color, CT_TEXTURE)
- local thumb = color.thumb
- thumb:SetDimensions(36, 18)
- thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
- local r, g, b, a = getFunc()
- thumb:SetColor(r, g, b, a or 1)
-
- color.border = wm:CreateControl(controlName.."ColorBorder", 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 ColorPickerCallback
- if not ColorPickerCallback then
- ColorPickerCallback = function(r, g, b, a)
- thumb:SetColor(r, g, b, a or 1)
- setFunc(r, g, b, a)
- end
- end
-
- colorpicker.controlType = OPTIONS_CUSTOM
- colorpicker.customSetupFunction = function(colorpicker)
- colorpicker:SetHandler("OnMouseUp", function(self, btn, upInside)
- if upInside then
- local r, g, b, a = getFunc()
- COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, text)
- end
- end)
- end
- colorpicker.panel = panelID
- colorpicker.tooltipText = tooltip
- colorpicker:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
- colorpicker:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
- if warning then
- colorpicker.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", colorpicker, "ZO_Options_WarningIcon")
- colorpicker.warning:SetAnchor(RIGHT, colorpicker:GetNamedChild("Color"), LEFT, -5, 0)
- colorpicker.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(colorpicker)
-
- lastAddedControl[panelID] = colorpicker
-
- return colorpicker
-end
-
-function lam:AddEditBox(panelID, controlName, text, tooltip, isMultiLine, getFunc, setFunc, warning, warningText)
- local editbox = wm:CreateTopLevelWindow(controlName)
- editbox:SetParent(optionsWindow)
- editbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
- editbox:SetResizeToFitDescendents(true)
- editbox:SetWidth(510)
- editbox:SetMouseEnabled(true)
-
- editbox.label = wm:CreateControl(controlName.."Label", editbox, CT_LABEL)
- local label = editbox.label
- label:SetDimensions(300, 26)
- label:SetAnchor(TOPLEFT)
- label:SetFont("ZoFontWinH4")
- label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
- label:SetText(text)
-
- editbox.bg = wm:CreateControlFromVirtual(controlName.."BG", editbox, "ZO_EditBackdrop")
- local bg = editbox.bg
- bg:SetDimensions(200,isMultiLine and 100 or 24)
- bg:SetAnchor(RIGHT)
- editbox.edit = wm:CreateControlFromVirtual(controlName.."Edit", bg, isMultiLine and "ZO_DefaultEditMultiLineForBackdrop" or "ZO_DefaultEditForBackdrop")
- editbox.edit:SetText(getFunc())
- editbox.edit:SetHandler("OnFocusLost", function(self) setFunc(self:GetText()) end)
-
-
- editbox.panel = panelID
- editbox.tooltipText = tooltip
- editbox:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
- editbox:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
- if warning then
- editbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", editbox, "ZO_Options_WarningIcon")
- editbox.warning:SetAnchor(TOPRIGHT, editbox:GetNamedChild("BG"), TOPLEFT, -5, 0)
- editbox.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(editbox)
-
- lastAddedControl[panelID] = editbox
-
- return editbox
-end
-
-function lam:AddButton(panelID, controlName, text, tooltip, onClick, warning, warningText)
- local button = wm:CreateTopLevelWindow(controlName)
- button:SetParent(optionsWindow)
- button:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
- button:SetDimensions(510, 28)
- button:SetMouseEnabled(true)
-
- button.btn = wm:CreateControlFromVirtual(controlName.."Button", button, "ZO_DefaultButton")
- local btn = button.btn
- btn:SetAnchor(TOPRIGHT)
- btn:SetWidth(200)
- btn:SetText(text)
- btn:SetHandler("OnClicked", onClick)
-
- button.controlType = OPTIONS_CUSTOM
- button.customSetupFunction = function() end --move handlers into this function? (since I created a function...)
- button.panel = panelID
- btn.tooltipText = tooltip
- btn:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
- btn:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-
- if warning then
- button.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", button, "ZO_Options_WarningIcon")
- button.warning:SetAnchor(RIGHT, btn, LEFT, -5, 0)
- button.warning.tooltipText = warningText
- end
-
- ZO_OptionsWindow_InitializeControl(button)
-
- lastAddedControl[panelID] = button
-
- return button
-end
-
-function lam:AddDescription(panelID, controlName, text, titleText)
- local textBox = wm:CreateTopLevelWindow(controlName)
- textBox:SetParent(optionsWindow)
- textBox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
- textBox:SetResizeToFitDescendents(true)
- textBox:SetWidth(510)
-
- if titleText then
- textBox.title = wm:CreateControl(controlName.."Title", textBox, CT_LABEL)
- local title = textBox.title
- title:SetWidth(510)
- title:SetAnchor(TOPLEFT, textBox, TOPLEFT)
- title:SetFont("ZoFontWinH4")
- title:SetText(titleText)
- end
-
- textBox.desc = wm:CreateControl(controlName.."Text", textBox, CT_LABEL)
- local desc = textBox.desc
- desc:SetWidth(510)
- if titleText then
- desc:SetAnchor(TOPLEFT, textBox.title, BOTTOMLEFT)
- else
- desc:SetAnchor(TOPLEFT)
- end
- desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
- desc:SetFont("ZoFontGame")
- desc:SetText(text)
-
- textBox.controlType = OPTIONS_CUSTOM
- textBox.panel = panelID
-
- ZO_OptionsWindow_InitializeControl(textBox)
-
- lastAddedControl[panelID] = textBox
-
- return textBox
-end
-
-
---test controls & examples--
---[[local controlPanelID = lam:CreateControlPanel("ZAM_ADDON_OPTIONS", "ZAM Addons")
-lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON", "TEST ADDON")
-lam:AddDescription(controlPanelID, "ZAM_Addons_TESTDESC", "This is a test description.", "Header")
-lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER", "Test slider", "Adjust the slider.", 1, 10, 1, function() return 7 end, function(value) end, true, "needs UI reload")
-lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN", "Test Dropdown", "Pick something!", {"thing 1", "thing 2", "thing 3"}, function() return "thing 2" end, function(self,valueString) print(valueString) end)
-local checkbox1 = true
-lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX", "Test Checkbox", "On or off?", function() return checkbox1 end, function(value) checkbox1 = not checkbox1 print(value, checkbox1) end)
-lam:AddColorPicker(controlPanelID, "ZAM_TESTCOLORPICKER", "Test color picker", "What's your favorite color?", function() return 1, 1, 0 end, function(r,g,b) print(r,g,b) end)
-lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX", "Test Edit Box", "This is a tooltip!", false, function() return "hi" end, function(text) print(text) end)
-lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON2", "TEST ADDON 2")
-local checkbox2 = false
-lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX2", "Test Checkbox 2", "On or off?", function() return checkbox2 end, function(value) checkbox2 = not checkbox2 print(value, checkbox2) end)
-lam:AddButton(controlPanelID, "ZAM_TESTBUTTON", "Test Button", "Click me", function() print("hi") end, true, "oh noez!")
-lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX2", "Test Edit Box 2", "This is a tooltip!", true, function() return "hi" end, function(text) print(text) end, true, "warning text")
-lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER2", "Test slider 2", "Adjust the slider.", 50, 100, 10, function() return 80 end, function(value) end)
-lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN2", "Test Dropdown 2", "Pick something!", {"thing 4", "thing 5", "thing 6"}, function() return "thing 6" end, function(self,valueString) print(valueString) end)
+local MAJOR, MINOR = "LibAddonMenu-1.0", 6
+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--
+lam.lastAddedControl = {}
+local lastAddedControl = lam.lastAddedControl
+local wm = GetWindowManager()
+local strformat = string.format
+local tostring = tostring
+local round = zo_round
+local optionsWindow = ZO_OptionsWindowSettingsScrollChild
+
+--maybe return the controls from the creation functions?
+
+function lam:CreateControlPanel(controlPanelID, controlPanelName)
+ local panelID
+
+ if _G[controlPanelID] then
+ panelID = _G[controlPanelID]
+ return panelID
+ end
+
+ ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelName)
+
+ --disables Defaults button because we don't need it, but keybind still works :/ ...
+ panelID = _G[controlPanelID]
+ ZO_PreHook("ZO_OptionsWindow_ChangePanels", function(panel)
+ local enable = (panel ~= panelID)
+ ZO_OptionsWindowResetToDefaultButton:SetEnabled(enable)
+ ZO_OptionsWindowResetToDefaultButton:SetKeybindEnabled(enable)
+ end)
+
+ return panelID
+end
+
+function lam:AddHeader(panelID, controlName, text)
+ local header = wm:CreateControlFromVirtual(controlName, optionsWindow, lastAddedControl[panelID] and "ZO_Options_SectionTitle_WithDivider" or "ZO_Options_SectionTitle")
+ if lastAddedControl[panelID] then
+ header:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 15)
+ else
+ header:SetAnchor(TOPLEFT)
+ end
+ header.controlType = OPTIONS_SECTION_TITLE
+ header.panel = panelID
+ header.text = text
+
+ ZO_OptionsWindow_InitializeControl(header)
+
+ lastAddedControl[panelID] = header
+
+ return header
+end
+
+
+--To-Do list:
+--extra sub-options window out to the right?? (or maybe addon list?)
+--find alternatives to handler hooks
+
+function lam:AddSlider(panelID, controlName, text, tooltip, minValue, maxValue, step, getFunc, setFunc, warning, warningText)
+ local slider = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Slider")
+ slider:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
+ slider.controlType = OPTIONS_SLIDER
+ slider.system = SETTING_TYPE_UI
+ slider.panel = panelID
+ slider.text = text
+ slider.tooltipText = tooltip
+ slider.showValue = true
+ slider.showValueMin = minValue
+ slider.showValueMax = maxValue
+ local range = maxValue - minValue
+ local slidercontrol = slider:GetNamedChild("Slider")
+ local slidervalue = slider:GetNamedChild("ValueLabel")
+ slidercontrol:SetValueStep(1/range * step)
+ slider:SetHandler("OnShow", function()
+ local curValue = getFunc()
+ slidercontrol:SetValue((curValue - minValue)/range)
+ slidervalue:SetText(tostring(curValue))
+ end)
+ slidercontrol:SetHandler("OnValueChanged", function (self, value)
+ self:SetValue(value)
+ value = round(value*range + minValue)
+ slidervalue:SetText(strformat("%d", value))
+ end)
+ slidercontrol:SetHandler("OnSliderReleased", function(self, value)
+ value = round(value*range + minValue)
+ setFunc(value)
+ end)
+
+ if warning then
+ slider.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", slider, "ZO_Options_WarningIcon")
+ slider.warning:SetAnchor(RIGHT, slidercontrol, LEFT, -5, 0)
+ slider.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(slider)
+
+ lastAddedControl[panelID] = slider
+
+ return slider
+end
+
+function lam:AddDropdown(panelID, controlName, text, tooltip, validChoices, getFunc, setFunc, warning, warningText)
+ local dropdown = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Dropdown")
+ dropdown:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
+ dropdown.controlType = OPTIONS_DROPDOWN
+ dropdown.system = SETTING_TYPE_UI
+ dropdown.panel = panelID
+ dropdown.text = text
+ dropdown.tooltipText = tooltip
+ dropdown.valid = validChoices
+ local dropmenu = ZO_ComboBox_ObjectFromContainer(GetControl(dropdown, "Dropdown"))
+ local setText = dropmenu.m_selectedItemText.SetText
+ local selectedName
+ ZO_PreHookHandler(dropmenu.m_selectedItemText, "OnTextChanged", function(self)
+ if dropmenu.m_selectedItemData then
+ selectedName = dropmenu.m_selectedItemData.name
+ setText(self, selectedName)
+ setFunc(selectedName)
+ end
+ end)
+ dropdown:SetHandler("OnShow", function()
+ dropmenu:SetSelectedItem(getFunc())
+ end)
+
+ if warning then
+ dropdown.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", dropdown, "ZO_Options_WarningIcon")
+ dropdown.warning:SetAnchor(RIGHT, dropdown:GetNamedChild("Dropdown"), LEFT, -5, 0)
+ dropdown.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(dropdown)
+
+ lastAddedControl[panelID] = dropdown
+
+ return dropdown
+end
+
+function lam:AddCheckbox(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText)
+ local checkbox = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Checkbox")
+ checkbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
+ checkbox.controlType = OPTIONS_CHECKBOX
+ checkbox.system = SETTING_TYPE_UI
+ checkbox.settingId = _G[strformat("SETTING_%s", controlName)]
+ checkbox.panel = panelID
+ checkbox.text = text
+ checkbox.tooltipText = tooltip
+
+ local checkboxButton = checkbox:GetNamedChild("Checkbox")
+
+ ZO_PreHookHandler(checkbox, "OnShow", function()
+ checkboxButton:SetState(getFunc() and 1 or 0)
+ checkboxButton:toggleFunction(getFunc())
+ end)
+ ZO_PreHookHandler(checkboxButton, "OnClicked", function() setFunc(not getFunc()) end)
+
+ if warning then
+ checkbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", checkbox, "ZO_Options_WarningIcon")
+ checkbox.warning:SetAnchor(RIGHT, checkboxButton, LEFT, -5, 0)
+ checkbox.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(checkbox)
+
+ lastAddedControl[panelID] = checkbox
+
+ return checkbox
+end
+
+function lam:AddColorPicker(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText)
+ local colorpicker = wm:CreateTopLevelWindow(controlName)
+ colorpicker:SetParent(optionsWindow)
+ colorpicker:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
+ colorpicker:SetResizeToFitDescendents(true)
+ colorpicker:SetWidth(510)
+ colorpicker:SetMouseEnabled(true)
+
+ colorpicker.label = wm:CreateControl(controlName.."Label", colorpicker, CT_LABEL)
+ local label = colorpicker.label
+ label:SetDimensions(300, 26)
+ label:SetAnchor(TOPLEFT)
+ label:SetFont("ZoFontWinH4")
+ label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+ label:SetText(text)
+
+ colorpicker.color = wm:CreateControl(controlName.."Color", colorpicker, CT_CONTROL)
+ local color = colorpicker.color
+ color:SetDimensions(200,26)
+ color:SetAnchor(RIGHT)
+
+ color.thumb = wm:CreateControl(controlName.."ColorThumb", color, CT_TEXTURE)
+ local thumb = color.thumb
+ thumb:SetDimensions(36, 18)
+ thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
+ local r, g, b, a = getFunc()
+ thumb:SetColor(r, g, b, a or 1)
+
+ color.border = wm:CreateControl(controlName.."ColorBorder", 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 ColorPickerCallback
+ if not ColorPickerCallback then
+ ColorPickerCallback = function(r, g, b, a)
+ thumb:SetColor(r, g, b, a or 1)
+ setFunc(r, g, b, a)
+ end
+ end
+
+ colorpicker.controlType = OPTIONS_CUSTOM
+ colorpicker.customSetupFunction = function(colorpicker)
+ colorpicker:SetHandler("OnMouseUp", function(self, btn, upInside)
+ if upInside then
+ local r, g, b, a = getFunc()
+ COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, text)
+ end
+ end)
+ end
+ colorpicker.panel = panelID
+ colorpicker.tooltipText = tooltip
+ colorpicker:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+ colorpicker:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+ if warning then
+ colorpicker.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", colorpicker, "ZO_Options_WarningIcon")
+ colorpicker.warning:SetAnchor(RIGHT, colorpicker:GetNamedChild("Color"), LEFT, -5, 0)
+ colorpicker.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(colorpicker)
+
+ lastAddedControl[panelID] = colorpicker
+
+ return colorpicker
+end
+
+function lam:AddEditBox(panelID, controlName, text, tooltip, isMultiLine, getFunc, setFunc, warning, warningText)
+ local editbox = wm:CreateTopLevelWindow(controlName)
+ editbox:SetParent(optionsWindow)
+ editbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
+ editbox:SetResizeToFitDescendents(true)
+ editbox:SetWidth(510)
+ editbox:SetMouseEnabled(true)
+
+ editbox.label = wm:CreateControl(controlName.."Label", editbox, CT_LABEL)
+ local label = editbox.label
+ label:SetDimensions(300, 26)
+ label:SetAnchor(TOPLEFT)
+ label:SetFont("ZoFontWinH4")
+ label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+ label:SetText(text)
+
+ editbox.bg = wm:CreateControlFromVirtual(controlName.."BG", editbox, "ZO_EditBackdrop")
+ local bg = editbox.bg
+ bg:SetDimensions(200,isMultiLine and 100 or 24)
+ bg:SetAnchor(RIGHT)
+ editbox.edit = wm:CreateControlFromVirtual(controlName.."Edit", bg, isMultiLine and "ZO_DefaultEditMultiLineForBackdrop" or "ZO_DefaultEditForBackdrop")
+ editbox.edit:SetText(getFunc())
+ editbox.edit:SetHandler("OnFocusLost", function(self) setFunc(self:GetText()) end)
+
+
+ editbox.panel = panelID
+ editbox.tooltipText = tooltip
+ editbox:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+ editbox:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+ if warning then
+ editbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", editbox, "ZO_Options_WarningIcon")
+ editbox.warning:SetAnchor(TOPRIGHT, editbox:GetNamedChild("BG"), TOPLEFT, -5, 0)
+ editbox.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(editbox)
+
+ lastAddedControl[panelID] = editbox
+
+ return editbox
+end
+
+function lam:AddButton(panelID, controlName, text, tooltip, onClick, warning, warningText)
+ local button = wm:CreateTopLevelWindow(controlName)
+ button:SetParent(optionsWindow)
+ button:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6)
+ button:SetDimensions(510, 28)
+ button:SetMouseEnabled(true)
+
+ button.btn = wm:CreateControlFromVirtual(controlName.."Button", button, "ZO_DefaultButton")
+ local btn = button.btn
+ btn:SetAnchor(TOPRIGHT)
+ btn:SetWidth(200)
+ btn:SetText(text)
+ btn:SetHandler("OnClicked", onClick)
+
+ button.controlType = OPTIONS_CUSTOM
+ button.customSetupFunction = function() end --move handlers into this function? (since I created a function...)
+ button.panel = panelID
+ btn.tooltipText = tooltip
+ btn:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+ btn:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+
+ if warning then
+ button.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", button, "ZO_Options_WarningIcon")
+ button.warning:SetAnchor(RIGHT, btn, LEFT, -5, 0)
+ button.warning.tooltipText = warningText
+ end
+
+ ZO_OptionsWindow_InitializeControl(button)
+
+ lastAddedControl[panelID] = button
+
+ return button
+end
+
+function lam:AddDescription(panelID, controlName, text, titleText)
+ local textBox = wm:CreateTopLevelWindow(controlName)
+ textBox:SetParent(optionsWindow)
+ textBox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10)
+ textBox:SetResizeToFitDescendents(true)
+ textBox:SetWidth(510)
+
+ if titleText then
+ textBox.title = wm:CreateControl(controlName.."Title", textBox, CT_LABEL)
+ local title = textBox.title
+ title:SetWidth(510)
+ title:SetAnchor(TOPLEFT, textBox, TOPLEFT)
+ title:SetFont("ZoFontWinH4")
+ title:SetText(titleText)
+ end
+
+ textBox.desc = wm:CreateControl(controlName.."Text", textBox, CT_LABEL)
+ local desc = textBox.desc
+ desc:SetWidth(510)
+ if titleText then
+ desc:SetAnchor(TOPLEFT, textBox.title, BOTTOMLEFT)
+ else
+ desc:SetAnchor(TOPLEFT)
+ end
+ desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
+ desc:SetFont("ZoFontGame")
+ desc:SetText(text)
+
+ textBox.controlType = OPTIONS_CUSTOM
+ textBox.panel = panelID
+
+ ZO_OptionsWindow_InitializeControl(textBox)
+
+ lastAddedControl[panelID] = textBox
+
+ return textBox
+end
+
+
+--test controls & examples--
+--[[local controlPanelID = lam:CreateControlPanel("ZAM_ADDON_OPTIONS", "ZAM Addons")
+lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON", "TEST ADDON")
+lam:AddDescription(controlPanelID, "ZAM_Addons_TESTDESC", "This is a test description.", "Header")
+lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER", "Test slider", "Adjust the slider.", 1, 10, 1, function() return 7 end, function(value) end, true, "needs UI reload")
+lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN", "Test Dropdown", "Pick something!", {"thing 1", "thing 2", "thing 3"}, function() return "thing 2" end, function(self,valueString) print(valueString) end)
+local checkbox1 = true
+lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX", "Test Checkbox", "On or off?", function() return checkbox1 end, function(value) checkbox1 = not checkbox1 print(value, checkbox1) end)
+lam:AddColorPicker(controlPanelID, "ZAM_TESTCOLORPICKER", "Test color picker", "What's your favorite color?", function() return 1, 1, 0 end, function(r,g,b) print(r,g,b) end)
+lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX", "Test Edit Box", "This is a tooltip!", false, function() return "hi" end, function(text) print(text) end)
+lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON2", "TEST ADDON 2")
+local checkbox2 = false
+lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX2", "Test Checkbox 2", "On or off?", function() return checkbox2 end, function(value) checkbox2 = not checkbox2 print(value, checkbox2) end)
+lam:AddButton(controlPanelID, "ZAM_TESTBUTTON", "Test Button", "Click me", function() print("hi") end, true, "oh noez!")
+lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX2", "Test Edit Box 2", "This is a tooltip!", true, function() return "hi" end, function(text) print(text) end, true, "warning text")
+lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER2", "Test slider 2", "Adjust the slider.", 50, 100, 10, function() return 80 end, function(value) end)
+lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN2", "Test Dropdown 2", "Pick something!", {"thing 4", "thing 5", "thing 6"}, function() return "thing 6" end, function(self,valueString) print(valueString) end)
]]--
\ No newline at end of file
diff --git a/libs/LibStub/LibStub.lua b/libs/LibStub/LibStub.lua
index bfd96df..4c509a5 100644
--- a/libs/LibStub/LibStub.lua
+++ b/libs/LibStub/LibStub.lua
@@ -1,34 +1,34 @@
--- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
--- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
--- LibStub developed for World of Warcraft by above members of the WowAce community.
--- Ported to Elder Scrolls Online by Seerah
-
-local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 1 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-local LibStub = _G[LIBSTUB_MAJOR]
-
-local strformat = string.format
-if not LibStub or LibStub.minor < LIBSTUB_MINOR then
- LibStub = LibStub or {libs = {}, minors = {} }
- _G[LIBSTUB_MAJOR] = LibStub
- LibStub.minor = LIBSTUB_MINOR
-
- function LibStub:NewLibrary(major, minor)
- assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
- minor = assert(tonumber(zo_strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-
- local oldminor = self.minors[major]
- if oldminor and oldminor >= minor then return nil end
- self.minors[major], self.libs[major] = minor, self.libs[major] or {}
- return self.libs[major], oldminor
- end
-
- function LibStub:GetLibrary(major, silent)
- if not self.libs[major] and not silent then
- error(("Cannot find a library instance of %q."):strformat(tostring(major)), 2)
- end
- return self.libs[major], self.minors[major]
- end
-
- function LibStub:IterateLibraries() return pairs(self.libs) end
- setmetatable(LibStub, { __call = LibStub.GetLibrary })
-end
+-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+-- LibStub developed for World of Warcraft by above members of the WowAce community.
+-- Ported to Elder Scrolls Online by Seerah
+
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 1 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+local strformat = string.format
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+ LibStub = LibStub or {libs = {}, minors = {} }
+ _G[LIBSTUB_MAJOR] = LibStub
+ LibStub.minor = LIBSTUB_MINOR
+
+ function LibStub:NewLibrary(major, minor)
+ assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+ minor = assert(tonumber(zo_strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+ local oldminor = self.minors[major]
+ if oldminor and oldminor >= minor then return nil end
+ self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+ return self.libs[major], oldminor
+ end
+
+ function LibStub:GetLibrary(major, silent)
+ if not self.libs[major] and not silent then
+ error(("Cannot find a library instance of %q."):strformat(tostring(major)), 2)
+ end
+ return self.libs[major], self.minors[major]
+ end
+
+ function LibStub:IterateLibraries() return pairs(self.libs) end
+ setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end