diff --git a/Pawksickles.lua b/Pawksickles.lua
index ffad21c..892b6c6 100644
--- a/Pawksickles.lua
+++ b/Pawksickles.lua
@@ -1,112 +1,29 @@
+
local kName = 'Pawksickles'
local Pawksickles = {}
local EventMgr = GetEventManager()
+local CBM = CALLBACK_MANAGER
+local LMP = LibStub( 'LibMediaProvider-1.0' )
+if ( not LMP ) then return end
-local NORMAL = [[Pawksickles/fonts/dejavusans.ttf]]
-local BOLD = [[Pawksickles/fonts/dejavusans-bold.ttf]]
-local BOLDITALIC = [[Pawksickles/fonts/dejavusans-boldoblique.ttf]]
-local ITALIC = [[Pawksickles/fonts/dejavusans-oblique.ttf]]
-local NUMBER = [[Pawksickles/fonts/dejavusansmono.ttf]]
-local SERIF = [[Pawksickles/fonts/dejavuserif.ttf]]
-
-local THIN = 'soft-shadow-thin'
-local THICK = 'soft-shadow-thick'
-local SHADOW = 'shadow'
+LMP:Register( 'font', 'DejaVu Sans', [[Pawksickles/fonts/dejavusans.ttf]] )
+LMP:Register( 'font', 'DejaVu Sans Bold', [[Pawksickles/fonts/dejavusans-bold.ttf]] )
+LMP:Register( 'font', 'DejaVu Sans BoldOblique', [[Pawksickles/fonts/dejavusans-boldoblique.ttf]] )
+LMP:Register( 'font', 'DejaVu Sans Oblique', [[Pawksickles/fonts/dejavusans-oblique.ttf]] )
+LMP:Register( 'font', 'DejaVu Sans Mono', [[Pawksickles/fonts/dejavusansmono.ttf]] )
+LMP:Register( 'font', 'DejaVu Serif', [[Pawksickles/fonts/dejavuserif.ttf]] )
function Pawksickles:OnLoaded( event, addon )
if ( addon ~= kName ) then
return
end
- self:SetFont( ZoFontWinH1, BOLD, 22, THICK )
- self:SetFont( ZoFontWinH2, BOLD, 20, THICK )
- self:SetFont( ZoFontWinH3, BOLD, 18, THICK )
- self:SetFont( ZoFontWinH4, BOLD, 16, THICK )
- self:SetFont( ZoFontWinH5, BOLD, 14, THIN )
-
- self:SetFont( ZoFontWinT1, NORMAL, 12, THIN )
-
- self:SetFont( ZoFontGame, NORMAL, 12, THIN )
- self:SetFont( ZoFontGameMedium, NORMAL, 12, THIN )
- self:SetFont( ZoFontGameBold, BOLD, 12, THIN )
- self:SetFont( ZoFontGameOutline, BOLD, 12, THIN )
- self:SetFont( ZoFontGameShadow, BOLD, 12, THIN )
-
- self:SetFont( ZoFontGameSmall, NORMAL, 9, THIN )
- self:SetFont( ZoFontGameLarge, NORMAL, 14, THIN )
- self:SetFont( ZoFontGameLargeBold, BOLD, 14, THICK )
- self:SetFont( ZoFontGameLargeBoldShadow, BOLD, 14, THICK )
-
- self:SetFont( ZoFontHeader, BOLD, 12, THIN )
- self:SetFont( ZoFontHeader2, BOLD, 14, THIN )
- self:SetFont( ZoFontHeader3, BOLD, 16, THIN )
- self:SetFont( ZoFontHeader4, BOLD, 18, THIN )
-
- self:SetFont( ZoFontCallout, BOLD, 20, THICK )
- self:SetFont( ZoFontCallout2, BOLD, 22, THICK )
- self:SetFont( ZoFontCallout3, BOLD, 24, THICK )
-
- self:SetFont( ZoFontEdit, NORMAL, 12, SHADOW )
- self:SetFont( ZoLargeFontEdit, NORMAL, 21, SHADOW )
-
- self:SetFont( ZoFontChat, NORMAL, 12, THIN )
- self:SetFont( ZoFontEditChat, NORMAL, 14, SHADOW )
-
- self:SetFont( ZoFontWindowTitle, BOLDITALIC, 24, THICK )
- self:SetFont( ZoFontWindowSubtitle, NORMAL, 14, THICK )
-
- self:SetFont( ZoFontTooltipTitle, BOLDITALIC, 18 )
- self:SetFont( ZoFontTooltipSubtitle, NORMAL, 14 )
-
- self:SetFont( ZoFontAnnounce, BOLDITALIC, 22, THICK )
- self:SetFont( ZoFontAnnounceMessage, BOLD, 20, THICK )
-
- self:SetFont( ZoFontAnnounceSmall, BOLDITALIC, 12, THICK )
- self:SetFont( ZoFontAnnounceMedium, BOLDITALIC, 20, THICK )
- self:SetFont( ZoFontAnnounceLarge, BOLDITALIC, 28, THICK )
-
- self:SetFont( ZoFontCenterScreenAnnounceLarge, BOLDITALIC, 28, THICK )
- self:SetFont( ZoFontCenterScreenAnnounceSmall, BOLDITALIC, 20, THICK )
-
- self:SetFont( ZoFontAlert, BOLDITALIC, 18, THICK )
-
- self:SetFont( ZoFontConversationName, BOLDITALIC, 20, THICK )
- self:SetFont( ZoFontConversationText, NORMAL, 18, THICK )
- self:SetFont( ZoFontConversationOption, ITALIC, 14, THICK )
- self:SetFont( ZoFontConversationQuestReward, NORMAL, 14, THICK )
-
- self:SetFont( ZoFontKeybindStripKey, BOLD, 14, THIN )
- self:SetFont( ZoFontKeybindStripDescription, BOLD, 14, THICK )
-
- --self:SetFont( ZoCraftingInstruction, NORMAL, 30, THICK )
- self:SetFont( ZoInteractionPrompt, NORMAL, 16, THIN )
-
- self:SetFont( ZoFontBookPaper, SERIF, 14 )
- self:SetFont( ZoFontBookSkin, SERIF, 14 )
- self:SetFont( ZoFontBookRubbing, SERIF, 14 )
- self:SetFont( ZoFontBookLetter, SERIF, 14 )
- self:SetFont( ZoFontBookNote, SERIF, 14 )
- self:SetFont( ZoFontBookScroll, SERIF, 14 )
- self:SetFont( ZoFontBookTablet, SERIF, 14 )
- self:SetFont( ZoFontBookPaperTitle, SERIF, 20 )
- self:SetFont( ZoFontBookSkinTitle, SERIF, 20 )
- self:SetFont( ZoFontBookRubbingTitle, SERIF, 20 )
- self:SetFont( ZoFontBookLetterTitle, SERIF, 20 )
- self:SetFont( ZoFontBookNoteTitle, SERIF, 20 )
- self:SetFont( ZoFontBookScrollTitle, SERIF, 20 )
- self:SetFont( ZoFontBookTabletTitle, SERIF, 20 )
-
- self:SetFont( ZoFontBossName, BOLDITALIC, 16, THIN )
- self:SetFont( ZoFontBoss, BOLD, 12, THIN )
+ CBM:RegisterCallback( 'PAWKSICKLES_FONT_CHANGED', function( ... ) self:SetFont( ... ) end )
+ CBM:FireCallbacks( 'PAWKSICKLES_LOADED' )
end
-function Pawksickles:SetFont( object, fontFace, size, decoration )
- local fmt = '%s|%d'
- if ( decoration ) then
- fmt = fmt .. '|%s'
- end
-
- object:SetFont( string.format( fmt, fontFace, size, decoration ) )
+function Pawksickles:SetFont( object, font )
+ _G[ object ]:SetFont( font )
end
EventMgr:RegisterForEvent( 'Pawksickles', EVENT_ADD_ON_LOADED, function( ... ) Pawksickles:OnLoaded( ... ) end )
\ No newline at end of file
diff --git a/Pawksickles.txt b/Pawksickles.txt
index 1a43d9c..859c737 100644
--- a/Pawksickles.txt
+++ b/Pawksickles.txt
@@ -1,4 +1,11 @@
## Title: Pawksickles
## APIVersion: 100000
+## OptionalDependsOn: LibStub LibMediaProvider-1.0 LibAddonMenu-1.0
+## SavedVariables: PAWKSICKLES_DB
+libs/LibStub/LibStub.lua
+libs/LibMediaProvider-1.0/LibMediaProvider-1.0.lua
+libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
+
+PawksicklesConfig.lua
Pawksickles.lua
diff --git a/PawksicklesConfig.lua b/PawksicklesConfig.lua
new file mode 100644
index 0000000..e033a33
--- /dev/null
+++ b/PawksicklesConfig.lua
@@ -0,0 +1,188 @@
+
+local LAM = LibStub( 'LibAddonMenu-1.0' )
+local LMP = LibStub( 'LibMediaProvider-1.0' )
+
+if ( not LAM ) then return end
+if ( not LMP ) then return end
+
+local tsort = table.sort
+local tinsert = table.insert
+
+local PawksicklesConfig =
+{
+ _name = '_pawksickles',
+ _headers = setmetatable( {}, { __mode = 'kv' } )
+}
+
+local CBM = CALLBACK_MANAGER
+
+local THIN = 'soft-shadow-thin'
+local THICK = 'soft-shadow-thick'
+local SHADOW = 'shadow'
+local NONE = 'none'
+
+local defaults =
+{
+ ZoFontWinH1 = { face = 'DejaVu Sans Bold', size = 22, decoration = THICK },
+ ZoFontWinH2 = { face = 'DejaVu Sans Bold', size = 20, decoration = THICK },
+ ZoFontWinH3 = { face = 'DejaVu Sans Bold', size = 18, decoration = THICK },
+ ZoFontWinH4 = { face = 'DejaVu Sans Bold', size = 16, decoration = THICK },
+ ZoFontWinH5 = { face = 'DejaVu Sans Bold', size = 14, decoration = THIN },
+
+ ZoFontWinT1 = { face = 'DejaVu Sans', size = 12, decoration = THIN },
+
+ ZoFontGame = { face = 'DejaVu Sans', size = 12, decoration = THIN },
+ ZoFontGameMedium = { face = 'DejaVu Sans', size = 12, decoration = THIN },
+ ZoFontGameBold = { face = 'DejaVu Sans Bold', size = 12, decoration = THIN },
+ ZoFontGameOutline = { face = 'DejaVu Sans Bold', size = 12, decoration = THIN },
+ ZoFontGameShadow = { face = 'DejaVu Sans Bold', size = 12, decoration = THIN },
+
+ ZoFontGameSmall = { face = 'DejaVu Sans', size = 9, decoration = THIN },
+ ZoFontGameLarge = { face = 'DejaVu Sans', size = 14, decoration = THIN },
+ ZoFontGameLargeBold = { face = 'DejaVu Sans Bold', size = 14, decoration = THICK },
+ ZoFontGameLargeBoldShadow = { face = 'DejaVu Sans Bold', size = 14, decoration = THICK },
+
+ ZoFontHeader = { face = 'DejaVu Sans Bold', size = 12, decoration = THIN },
+ ZoFontHeader2 = { face = 'DejaVu Sans Bold', size = 14, decoration = THIN },
+ ZoFontHeader3 = { face = 'DejaVu Sans Bold', size = 16, decoration = THIN },
+ ZoFontHeader4 = { face = 'DejaVu Sans Bold', size = 18, decoration = THIN },
+
+ ZoFontCallout = { face = 'DejaVu Sans Bold', size = 20, decoration = THICK },
+ ZoFontCallout2 = { face = 'DejaVu Sans Bold', size = 22, decoration = THICK },
+ ZoFontCallout3 = { face = 'DejaVu Sans Bold', size = 24, decoration = THICK },
+
+ ZoFontEdit = { face = 'DejaVu Sans', size = 12, decoration = SHADOW },
+ ZoLargeFontEdit = { face = 'DejaVu Sans', size = 21, decoration = SHADOW },
+
+ ZoFontChat = { face = 'DejaVu Sans', size = 12, decoration = THIN },
+ ZoFontEditChat = { face = 'DejaVu Sans', size = 14, decoration = SHADOW },
+
+ ZoFontWindowTitle = { face = 'DejaVu Sans BoldOblique', size = 24, decoration = THICK },
+ ZoFontWindowSubtitle = { face = 'DejaVu Sans', size = 14, decoration = THICK },
+
+ ZoFontTooltipTitle = { face = 'DejaVu Sans BoldOblique', size = 18, decoration = NONE },
+ ZoFontTooltipSubtitle = { face = 'DejaVu Sans', size = 14, decoration = NONE },
+
+ ZoFontAnnounce = { face = 'DejaVu Sans BoldOblique', size = 22, decoration = THICK },
+ ZoFontAnnounceMessage = { face = 'DejaVu Sans Bold', size = 20, decoration = THICK },
+
+ ZoFontAnnounceSmall = { face = 'DejaVu Sans BoldOblique', size = 12, decoration = THICK },
+ ZoFontAnnounceMedium = { face = 'DejaVu Sans BoldOblique', size = 20, decoration = THICK },
+ ZoFontAnnounceLarge = { face = 'DejaVu Sans BoldOblique', size = 28, decoration = THICK },
+
+ ZoFontCenterScreenAnnounceLarge = { face = 'DejaVu Sans BoldOblique', size = 28, decoration = THICK },
+ ZoFontCenterScreenAnnounceSmall = { face = 'DejaVu Sans BoldOblique', size = 20, decoration = THICK },
+
+ ZoFontAlert = { face = 'DejaVu Sans BoldOblique', size = 18, decoration = THICK },
+
+ ZoFontConversationName = { face = 'DejaVu Sans BoldOblique', size = 20, decoration = THICK },
+ ZoFontConversationText = { face = 'DejaVu Sans', size = 18, decoration = THICK },
+ ZoFontConversationOption = { face = 'DejaVu Sans Oblique', size = 14, decoration = THICK },
+ ZoFontConversationQuestReward = { face = 'DejaVu Sans', size = 14, decoration = THICK },
+
+ ZoFontKeybindStripKey = { face = 'DejaVu Sans Bold', size = 14, decoration = THIN },
+ ZoFontKeybindStripDescription = { face = 'DejaVu Sans Bold', size = 14, decoration = THICK },
+
+ ZoInteractionPrompt = { face = 'DejaVu Sans', size = 16, decoration = THIN },
+
+ ZoFontBookPaper = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookSkin = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookRubbing = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookLetter = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookNote = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookScroll = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookTablet = { face = 'DejaVu Serif', size = 14, decoration = NONE },
+ ZoFontBookPaperTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookSkinTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookRubbingTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookLetterTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookNoteTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookScrollTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+ ZoFontBookTabletTitle = { face = 'DejaVu Serif', size = 20, decoration = NONE },
+
+ ZoFontBossName = { face = 'DejaVu Sans BoldOblique', size = 16, decoration = THIN },
+ ZoFontBoss = { face = 'DejaVu Sans Bold', size = 12, decoration = THIN }
+}
+
+local logical = {}
+local decorations = { 'none', 'soft-shadow-thin', 'soft-shadow-thick', 'shadow' }
+
+function PawksicklesConfig:FormatFont( fontEntry )
+ local str = '%s|%d'
+ if ( fontEntry.decoration ~= NONE ) then
+ str = str .. '|%s'
+ end
+
+ return string.format( str, LMP:Fetch( LMP.MediaType.FONT, fontEntry.face ), fontEntry.size or 10, fontEntry.decoration )
+end
+
+function PawksicklesConfig:OnLoaded()
+ self.db = ZO_SavedVars:NewAccountWide( 'PAWKSICKLES_DB', 1.0, nil, defaults )
+
+ for k,_ in pairs( defaults ) do
+ tinsert( logical, k )
+ end
+
+ tsort( logical )
+
+ self.config_panel = LAM:CreateControlPanel( self._name, 'Pawksickles' )
+
+ self:BeginAddingOptions()
+end
+
+function PawksicklesConfig:BeginAddingOptions()
+ for i=1,#logical do
+ local gameFont = tostring( logical[ i ] )
+ if ( self.db[ gameFont ] ) then
+ CBM:FireCallbacks( 'PAWKSICKLES_FONT_CHANGED', gameFont, self:FormatFont( self.db[ gameFont ] ) )
+
+ local header = LAM:AddHeader( self.config_panel, self._name .. '_header_' .. i, gameFont ):GetNamedChild( 'Label' )
+ header:SetFont( self:FormatFont( self.db[ gameFont ] ) )
+ self._headers[ gameFont ] = header
+
+ LAM:AddDropdown( self.config_panel, self._name .. '_font_' .. i, 'Font:', '', LMP:List( LMP.MediaType.FONT ),
+ function() return self.db[ gameFont ].face end,
+ function( selection ) self:FontDropdownChanged( gameFont, selection ) end )
+
+ LAM:AddSlider( self.config_panel, self._name .. '_size_' .. i, 'Size', '', 8, 50, 1,
+ function() return self.db[ gameFont ].size end,
+ function( size ) self:SliderChanged( gameFont, size ) end )
+
+ LAM:AddDropdown( self.config_panel, self._name .. '_decoration_' .. i, 'Decoration:', '', decorations,
+ function() return self.db[ gameFont ].decoration end,
+ function( selection ) self:DecorationDropdownChanged( gameFont, selection ) end )
+ end
+ end
+end
+
+function PawksicklesConfig:FontDropdownChanged( gameFont, fontFace )
+ self.db[ gameFont ].face = fontFace
+ local newFont = self:FormatFont( self.db[ gameFont ] )
+ if ( self._headers[ gameFont ] ) then
+ self._headers[ gameFont ]:SetFont( newFont )
+ end
+
+ CBM:FireCallbacks( 'PAWKSICKLES_FONT_CHANGED', gameFont, newFont )
+end
+
+function PawksicklesConfig:SliderChanged( gameFont, size )
+ self.db[ gameFont ].size = size
+ local newFont = self:FormatFont( self.db[ gameFont ] )
+ if ( self._headers[ gameFont ] ) then
+ self._headers[ gameFont ]:SetFont( newFont )
+ end
+
+ CBM:FireCallbacks( 'PAWKSICKLES_FONT_CHANGED', gameFont, newFont )
+end
+
+function PawksicklesConfig:DecorationDropdownChanged( gameFont, decoration )
+ self.db[ gameFont ].decoration = decoration
+ local newFont = self:FormatFont( self.db[ gameFont ] )
+ if ( self._headers[ gameFont ] ) then
+ self._headers[ gameFont ]:SetFont( newFont )
+ end
+
+ CBM:FireCallbacks( 'PAWKSICKLES_FONT_CHANGED', gameFont, newFont )
+end
+
+CBM:RegisterCallback( 'PAWKSICKLES_LOADED', function( ... ) PawksicklesConfig:OnLoaded( ... ) end )
\ 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
new file mode 100644
index 0000000..8e0b61d
--- /dev/null
+++ b/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua
@@ -0,0 +1,373 @@
+local MAJOR, MINOR = "LibAddonMenu-1.0", 5
+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(headerText)
+ 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/LibMediaProvider-1.0/LibMediaProvider-1.0.lua b/libs/LibMediaProvider-1.0/LibMediaProvider-1.0.lua
new file mode 100644
index 0000000..2ad539c
--- /dev/null
+++ b/libs/LibMediaProvider-1.0/LibMediaProvider-1.0.lua
@@ -0,0 +1,165 @@
+--LibMediaProvider-1.0 is inspired by and borrows from LibSharedMedia-3.0 for World of Warcraft by Elkano
+--LibSharedMedia-3.0 and LibMediaProvider-1.0 are under the LGPL-2.1 license
+
+local MAJOR, MINOR = "LibMediaProvider-1.0", 1 -- remember to increase manually on changes
+local LMP = LibStub:NewLibrary(MAJOR, MINOR)
+if not LMP then return end
+
+local cm = CALLBACK_MANAGER
+local tinsert = table.insert
+local tsort = table.sort
+local pairs = pairs
+
+LMP.DefaultMedia = {}
+LMP.MediaList = {}
+LMP.MediaTable = {}
+LMP.MediaType = {}
+local defaultMedia = LMP.DefaultMedia
+local mediaList = LMP.MediaList
+local mediaTable = LMP.MediaTable
+LMP.MediaType = {
+ BACKGROUND = "background", -- background textures
+ BORDER = "border", -- border textures
+ FONT = "font", -- fonts
+ STATUSBAR = "statusbar", -- statusbar textures
+ SOUND = "sound", -- sound files
+}
+
+--DEFAULT UI MEDIA--
+-- BACKGROUND
+LMP.MediaTable.background = {}
+--commented out because it still leaves a white texture behind - addons can use alpha to hide the background
+--LMP.MediaTable.background["None"] = ""
+LMP.MediaTable.background["ESO Black"] = "EsoUI/Art/Miscellaneous/borderedinset_center.dds"
+LMP.MediaTable.background["ESO Chat"] = "EsoUI/Art/chatwindow/chat_bg_center.dds"
+LMP.MediaTable.background["ESO Gray"] = "EsoUI/Art/itemtooltip/simpleprogbarbg_center.dds"
+LMP.MediaTable.background["Solid"] = "EsoUI/Art/miscellaneous/progressbar_genericfill_tall.dds"
+LMP.DefaultMedia.background = "None"
+
+-- BORDER
+LMP.MediaTable.border = {}
+--commented out because it still leaves a white texture behind - addons can use alpha to hide the border
+--LMP.MediaTable.border["None"] = ""
+LMP.MediaTable.border["ESO Gold"] = "EsoUI/Art/Miscellaneous/borderedinsettransparent_edgefile.dds"
+LMP.MediaTable.border["ESO Chat"] = "EsoUI/Art/chatwindow/chat_bg_edge.dds"
+LMP.MediaTable.border["ESO Rounded"] = "EsoUI/Art/miscellaneous/interactkeyframe_edge.dds"
+LMP.MediaTable.border["ESO Blue Highlight"] = "EsoUI/Art/miscellaneous/textentry_highlight_edge.dds"
+LMP.MediaTable.border["ESO Blue Glow"] = "EsoUI/Art/crafting/crafting_tooltip_glow_edge_blue64.dds"
+LMP.MediaTable.border["ESO Red Glow"] = "EsoUI/Art/crafting/crafting_tooltip_glow_edge_red64.dds"
+LMP.MediaTable.border["ESO Red Overlay"] = "EsoUI/Art/uicombatoverlay/uicombatoverlayedge.dds"
+LMP.DefaultMedia.border = "None"
+
+-- FONT
+LMP.MediaTable.font = {}
+LMP.MediaTable.font["ProseAntique"] = "EsoUI/Common/Fonts/ProseAntiquePSMT.otf"
+LMP.MediaTable.font["Arial Narrow"] = "EsoUI/Common/Fonts/arialn.ttf"
+LMP.MediaTable.font["Consolas"] = "EsoUI/Common/Fonts/consola.ttf"
+LMP.MediaTable.font["ESO Cartographer"] = "EsoUI/Common/Fonts/esocartographer-bold.otf"
+LMP.MediaTable.font["Fontin Bold"] = "EsoUI/Common/Fonts/fontin_sans_b.otf"
+LMP.MediaTable.font["Fontin Italic"] = "EsoUI/Common/Fonts/fontin_sans_i.otf"
+LMP.MediaTable.font["Fontin Regular"] = "EsoUI/Common/Fonts/fontin_sans_r.otf"
+LMP.MediaTable.font["Fontin SmallCaps"] = "EsoUI/Common/Fonts/fontin_sans_sc.otf"
+LMP.MediaTable.font["Skyrim Handwritten"] = "EsoUI/Common/Fonts/Handwritten_Bold.otf"
+LMP.MediaTable.font["Trajan Pro"] = "EsoUI/Common/Fonts/trajanpro-regular.otf"
+LMP.MediaTable.font["Univers 55"] = "EsoUI/Common/Fonts/univers55.otf"
+LMP.MediaTable.font["Univers 57"] = "EsoUI/Common/Fonts/univers57.otf"
+LMP.MediaTable.font["Univers 67"] = "EsoUI/Common/Fonts/univers67.otf"
+LMP.DefaultMedia.font = "Arial Narrow"
+
+-- STATUSBAR
+LMP.MediaTable.statusbar = {}
+LMP.MediaTable.statusbar["ESO Basic"] = "EsoUI/Art/miscellaneous/progressbar_genericfill_tall.dds"
+LMP.DefaultMedia.statusbar = "ESO Basic"
+
+-- SOUND
+LMP.MediaTable.sound = {}
+LMP.MediaTable.sound["None"] = ""
+LMP.MediaTable.sound["AvA Gate Open"] = SOUNDS.AVA_GATE_OPENED
+LMP.MediaTable.sound["AvA Gate Close"] = SOUNDS.AVA_GATE_CLOSED
+LMP.MediaTable.sound["Emperor Coronated"] = SOUNDS.EMPEROR_CORONATED_DAGGERFALL
+LMP.MediaTable.sound["Level Up"] = SOUNDS.LEVEL_UP
+LMP.MediaTable.sound["Skill Gained"] = SOUNDS.SKILL_GAINED
+LMP.MediaTable.sound["Ability Purchased"] = SOUNDS.ABILITY_SKILL_PURCHASED
+LMP.MediaTable.sound["Book Acquired"] = SOUNDS.BOOK_ACQUIRED
+LMP.MediaTable.sound["Unlock"] = SOUNDS.LOCKPICKING_UNLOCKED
+LMP.MediaTable.sound["Enchanting Extract"] = SOUNDS.ENCHANTING_EXTRACT_START_ANIM
+LMP.MediaTable.sound["Enchanting Create"] = SOUNDS.ENCHANTING_CREATE_TOOLTIP_GLOW
+LMP.MediaTable.sound["Blacksmith Improve"] = SOUNDS.BLACKSMITH_IMPROVE_TOOLTIP_GLOW_SUCCESS
+LMP.DefaultMedia.sound = "None"
+
+local function rebuildMediaList(mediatype)
+ local mtable = mediaTable[mediatype]
+ if not mtable then return end
+ if not mediaList[mediatype] then mediaList[mediatype] = {} end
+ local mlist = mediaList[mediatype]
+ -- list can only get larger, so simply overwrite it
+ local i = 0
+ for k in pairs(mtable) do
+ i = i + 1
+ mlist[i] = k
+ end
+ tsort(mlist)
+end
+
+function LMP:Register(mediatype, key, data)
+ if type(mediatype) ~= "string" then
+ error(MAJOR..":Register(mediatype, key, data) - mediatype must be string, got "..type(mediatype))
+ end
+ if type(key) ~= "string" then
+ error(MAJOR..":Register(mediatype, key, data) - key must be string, got "..type(key))
+ end
+ mediatype = mediatype:lower()
+ if not mediaTable[mediatype] then
+ mediaTable[mediatype] = {}
+ end
+
+ local mtable = mediaTable[mediatype]
+ if mtable[key] then
+ return false
+ end
+ mtable[key] = data
+ rebuildMediaList(mediatype)
+ cm:FireCallbacks("LibMediaProvider_Registered", mediatype, key)
+ return true
+end
+
+function LMP:Fetch(mediatype, key)
+ local mtt = mediaTable[mediatype]
+ local result = mtt and mtt[key]
+ return result ~= "" and result or nil
+end
+
+function LMP:IsValid(mediatype, key)
+ return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
+end
+
+function LMP:HashTable(mediatype)
+ return mediaTable[mediatype]
+end
+
+--Will this work with ESO's dropdowns?
+--Does something else need to be done here?
+function LMP:List(mediatype)
+ if not mediaTable[mediatype] then
+ return nil
+ end
+ if not mediaList[mediatype] then
+ rebuildMediaList(mediatype)
+ end
+ return mediaList[mediatype]
+end
+
+function LMP:GetDefault(mediatype)
+ return defaultMedia[mediatype]
+end
+
+function LMP:SetDefault(mediatype, key)
+ if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
+ defaultMedia[mediatype] = key
+ return true
+ else
+ return false
+ end
+end
+
+
diff --git a/libs/LibStub/LibStub.lua b/libs/LibStub/LibStub.lua
new file mode 100644
index 0000000..4c509a5
--- /dev/null
+++ b/libs/LibStub/LibStub.lua
@@ -0,0 +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