diff --git a/Broker_StartMenu.toc b/Broker_StartMenu.toc index 0d1b2bf..d68ccc9 100644 --- a/Broker_StartMenu.toc +++ b/Broker_StartMenu.toc @@ -1,4 +1,4 @@ -## Interface: 60000 +## Interface: 60200 ## Author: Lynxium @@ -17,7 +17,7 @@ libs\CallbackHandler-1.0.lua libs\LibDataBroker-1.1.lua libs\AceLocale-3.0\AceLocale-3.0.xml libs\AceDB-3.0\AceDB-3.0.xml -libs\Libra-34\Libra.xml +libs\Libra-36\Libra.xml libs\LibraEx.lua libs\EasyDisplay.lua diff --git a/libs/EasyDisplay.lua b/libs/EasyDisplay.lua index 0d92667..8f4f5eb 100644 --- a/libs/EasyDisplay.lua +++ b/libs/EasyDisplay.lua @@ -25,7 +25,7 @@ assert(LibStub, "EasyDisplay-1.0 requires LibStub") -local lib, minor = LibStub:NewLibrary("EasyDisplay-1.0", 11) +local lib, minor = LibStub:NewLibrary("EasyDisplay-1.0", 12) if not lib then return end minor = minor or 0 @@ -144,7 +144,7 @@ local interfaces = { button = CompanionsMicroButton, secure = true, command = "TOGGLECOLLECTIONS", - func = function() TogglePetJournal() end, + func = function() ToggleCollectionsJournal() end, }, { name = "guild", diff --git a/libs/Libra-34/AceDBControls.lua b/libs/Libra-34/AceDBControls.lua deleted file mode 100644 index d0cfc8c..0000000 --- a/libs/Libra-34/AceDBControls.lua +++ /dev/null @@ -1,352 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "AceDBControls", 4 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local AceDBControls = Libra.modules[Type] -AceDBControls.Prototype = AceDBControls.Prototype or CreateFrame("Frame") - -local Prototype = AceDBControls.Prototype -local mt = {__index = Prototype} - -local L = { - default = "Default", - reset = "Reset profile", - new = "Create new profile", - choose = "Active profile", - copy = "Copy from", - delete = "Delete a profile", - delete_confirm = "Are you sure you want to delete the selected profile?", - profiles = "Profiles", - - dual_profile = "Dual profile", - enabled = "Enable dual profile", -} - -local LOCALE = GetLocale() -if LOCALE == "deDE" then - L["default"] = "Standard" - L["reset"] = "Profil zur\195\188cksetzen" - L["new"] = "Neu" - L["choose"] = "Vorhandene Profile" - L["copy"] = "Kopieren von..." - L["delete"] = "Profil l\195\182schen" - L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?" - L["profiles"] = "Profile" - - L["dual_profile"] = "Duales Profil" - L["enabled"] = "Aktiviere Duale Profile" -elseif LOCALE == "frFR" then - L["default"] = "D\195\169faut" - L["reset"] = "R\195\169initialiser le profil" - L["new"] = "Nouveau" - L["choose"] = "Profils existants" - L["copy"] = "Copier \195\160 partir de" - L["delete"] = "Supprimer un profil" - L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?" - L["profiles"] = "Profils" - - L["dual_profile"] = 'Second profil' - L["enabled"] = 'Activez le second profil' -elseif LOCALE == "koKR" then - L["default"] = "기본값" - L["reset"] = "프로필 초기화" - L["new"] = "새로운 프로필" - L["choose"] = "프로필 선택" - L["copy"] = "복사" - L["delete"] = "프로필 삭제" - L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?" - L["profiles"] = "프로필" - - L["dual_profile"] = "이중 프로필" - L["enabled"] = "이중 프로필 사용" -elseif LOCALE == "esES" or LOCALE == "esMX" then - L["default"] = "Por defecto" - L["reset"] = "Reiniciar Perfil" - L["new"] = "Nuevo" - L["choose"] = "Perfiles existentes" - L["copy"] = "Copiar de" - L["delete"] = "Borrar un Perfil" - L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?" - L["profiles"] = "Perfiles" -elseif LOCALE == "zhTW" then - L["default"] = "預設" - L["reset"] = "重置設定檔" - L["new"] = "新建" - L["choose"] = "現有的設定檔" - L["copy"] = "複製自" - L["delete"] = "刪除一個設定檔" - L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?" - L["profiles"] = "設定檔" -elseif LOCALE == "zhCN" then - L["default"] = "默认" - L["reset"] = "重置配置文件" - L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。" - L["new"] = "新建" - L["choose"] = "现有的配置文件" - L["copy"] = "复制自" - L["delete"] = "删除一个配置文件" - L["delete_confirm"] = "你确定要删除所选择的配置文件么?" - L["profiles"] = "配置文件" - - L["dual_profile"] = "双重配置文件" - L["enabled"] = "开启双重配置文件" -elseif LOCALE == "ruRU" then - L["default"] = "По умолчанию" - L["reset"] = "Сброс профиля" - L["new"] = "Новый" - L["choose"] = "Существующие профили" - L["copy"] = "Скопировать из" - L["delete"] = "Удалить профиль" - L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?" - L["profiles"] = "Профили" - - L["dual_profile"] = "Второй профиль" - L["enabled"] = "Включить двойной профиль" -end - -local defaultProfiles = {} - -local function profileSort(a, b) - return a.value < b.value -end - -local tempProfiles = {} - -local function getProfiles(db, common, nocurrent) - local profiles = {} - - -- copy existing profiles into the table - local currentProfile = db:GetCurrentProfile() - for _, v in ipairs(db:GetProfiles(tempProfiles)) do - if not (nocurrent and v == currentProfile) then - profiles[v] = v - end - end - - -- add our default profiles to choose from (or rename existing profiles) - for k, v in pairs(defaultProfiles) do - if (common or profiles[k]) and not (nocurrent and k == currentProfile) then - profiles[k] = v - end - end - - local sortProfiles = {} - for k, v in pairs(profiles) do - tinsert(sortProfiles, {text = v, value = k}) - end - sort(sortProfiles, profileSort) - - return sortProfiles -end - -local function dropdownOnClick(self, profile, func) - func(self.owner.db, profile, self.owner) -end - -local function initializeDropdown(self, level, menuList) - for i, v in ipairs(getProfiles(self.db, self.common, self.nocurrent)) do - local info = UIDropDownMenu_CreateInfo() - info.text = v.text - info.func = dropdownOnClick - info.arg1 = v.value - info.arg2 = self.func - info.checked = not self.nocurrent and (v.value == self.getCurrent(self.db)) - info.notCheckable = self.nocurrent - self:AddButton(info) - end -end - -local function createDropdown(parent) - local dropdown = Libra:CreateDropdown("Frame", parent) - dropdown:SetWidth(160) - dropdown:JustifyText("LEFT") - dropdown.initialize = initializeDropdown - return dropdown -end - -local function menuButton_OnClick(self) - self.menu:Toggle() -end - -local function createMenuButton(parent) - local button = Libra:CreateButton(parent) - button:SetScript("OnClick", menuButton_OnClick) - button.arrow:Show() - button:SetWidth(88) - - local menu = Libra:CreateDropdown("Menu") - menu.relativeTo = button - menu.initialize = initializeDropdown - menu.nocurrent = true - menu.db = parent.db - button.menu = menu - - return button -end - -local createProfileScripts = { - OnEnterPressed = function(self) - self.db:SetProfile(self:GetText()) - self:ClearFocus() - end, - OnEditFocusGained = function(self) - self:SetTextColor(1, 1, 1) - end, - OnEditFocusLost = function(self) - self:SetTextColor(0.5, 0.5, 0.5) - self:SetText("") - end, -} - -local function enableDualProfileOnClick(self) - local checked = self:GetChecked() - self.db:SetDualSpecEnabled(checked) - self.dualProfile:SetEnabled(checked) -end - -local function dualProfileOnClick(db, profile, frame) - db:SetDualSpecProfile(profile) - frame:SetText(profile) -end - -local function deleteProfile(db, profile) - StaticPopup_Show("DELETE_PROFILE", nil, nil, {db = db, profile = profile}) -end - -StaticPopupDialogs["DELETE_PROFILE"] = { - text = L.delete_confirm, - button1 = YES, - button2 = NO, - OnAccept = function(self, data) - data.db:DeleteProfile(data.profile) - end, -} - -local function constructor(self, db, parent) - local frame = setmetatable(CreateFrame("Frame", nil, parent), mt) - frame:SetSize(192, 192) - frame.db = db - - db.RegisterCallback(frame, "OnNewProfile") - db.RegisterCallback(frame, "OnProfileChanged") - db.RegisterCallback(frame, "OnProfileDeleted") - - local keys = db.keys - defaultProfiles["Default"] = L.default - defaultProfiles[keys.char] = keys.char - defaultProfiles[keys.realm] = keys.realm - defaultProfiles[keys.class] = UnitClass("player") - - local objects = {} - - do -- create the controls - local choose = createDropdown(frame) - choose:SetPoint("TOP") - choose.label:SetText(L.choose) - choose.func = db.SetProfile - choose.getCurrent = db.GetCurrentProfile - choose.common = true - objects.choose = choose - - local newProfile = Libra:CreateEditbox(frame) - newProfile:SetPoint("TOPLEFT", choose, "BOTTOMLEFT", 24, -8) - newProfile:SetPoint("TOPRIGHT", choose, "BOTTOMRIGHT", -17, -8) - newProfile:SetTextColor(0.5, 0.5, 0.5) - newProfile:SetScript("OnEscapePressed", newProfile.ClearFocus) - for script, handler in pairs(createProfileScripts) do - newProfile:SetScript(script, handler) - end - objects.newProfile = newProfile - - local label = newProfile:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") - label:SetHeight(18) - label:SetPoint("BOTTOMLEFT", newProfile, "TOPLEFT", -5, -2) - label:SetPoint("BOTTOMRIGHT", newProfile, "TOPRIGHT", 0, -2) - label:SetJustifyH("LEFT") - label:SetText(L.new) - - local copy = createMenuButton(frame) - copy:SetPoint("TOPLEFT", newProfile, "BOTTOMLEFT", -9, -4) - copy:SetText("Copy from") - copy.menu.func = db.CopyProfile - objects.copy = copy - - local delete = createMenuButton(frame) - delete:SetPoint("TOPRIGHT", newProfile, "BOTTOMRIGHT", 4, -4) - delete:SetText("Delete") - delete.menu.func = deleteProfile - objects.delete = delete - - local reset = Libra:CreateButton(frame) - reset:SetPoint("TOPLEFT", copy, "BOTTOM", 0, -4) - reset:SetPoint("TOPRIGHT", delete, "BOTTOM", 0, -4) - reset:SetScript("OnClick", function(self) self.db:ResetProfile() end) - reset:SetText(L.reset) - objects.reset = reset - - local hasDualProfile = db:GetNamespace("LibDualSpec-1.0", true) - if hasDualProfile then - local isDualSpecEnabled = db:IsDualSpecEnabled() - - local dualProfile = createDropdown(frame) - dualProfile:SetPoint("TOP", reset, "BOTTOM", 0, -28) - dualProfile:SetEnabled(isDualSpecEnabled) - dualProfile:SetText(db:GetDualSpecProfile()) - dualProfile.func = dualProfileOnClick - dualProfile.getCurrent = db.GetDualSpecProfile - dualProfile.common = true - objects.dualProfile = dualProfile - - local enabled = CreateFrame("CheckButton", nil, frame, "OptionsBaseCheckButtonTemplate") - enabled:SetPoint("BOTTOMLEFT", dualProfile, "TOPLEFT", 16, 0) - enabled:SetPushedTextOffset(0, 0) - enabled:SetScript("OnClick", enableDualProfileOnClick) - enabled:SetChecked(isDualSpecEnabled) - enabled.tooltipText = L.enable_desc - enabled.dualProfile = dualProfile - objects.dualEnabled = enabled - - local text = enabled:CreateFontString(nil, nil, "GameFontHighlight") - text:SetPoint("LEFT", enabled, "RIGHT", 0, 1) - text:SetText(L.enabled) - - frame.hasDualProfile = true - end - end - - for k, object in pairs(objects) do - object.db = db - frame[k] = object - end - - frame.choose:SetText(db:GetCurrentProfile()) - - frame:CheckProfiles() - - return frame -end - -function Prototype:CheckProfiles() - local hasProfiles = not self:HasNoProfiles() - self.copy:SetEnabled(hasProfiles) - self.delete:SetEnabled(hasProfiles) -end - -function Prototype:HasNoProfiles() - return next(getProfiles(self.db, nil, true)) == nil -end - -function Prototype:OnProfileChanged(event, db, profile) - self.choose:SetText(profile) - self:CheckProfiles() - if self.hasDualProfile then - self.dualProfile:SetText(db:GetDualSpecProfile()) - end -end - -Prototype.OnNewProfile = Prototype.CheckProfiles -Prototype.OnProfileDeleted = Prototype.CheckProfiles - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Addon.lua b/libs/Libra-34/Addon.lua deleted file mode 100644 index 415b774..0000000 --- a/libs/Libra-34/Addon.lua +++ /dev/null @@ -1,193 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Addon", 3 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local object = Libra.modules[Type] -object.frame = object.frame or CreateFrame("Frame") -object.addons = object.addons or {} -object.events = object.events or {} -object.onUpdates = object.onUpdates or {} -object.defaults = object.defaults or {} - -local function safecall(object, method, ...) - if object[method] then - object[method](object, ...) - end -end - -local function removeDefaults(tbl, defaults) - for k, v in pairs(defaults) do - if type(v) == "table" then - removeDefaults(tbl[k], v) - if not next(tbl[k]) then - tbl[k] = nil - end - elseif v == tbl[k] then - tbl[k] = nil - end - end -end - -object.frame:RegisterEvent("ADDON_LOADED") -object.frame:RegisterEvent("PLAYER_LOGOUT") -object.frame:SetScript("OnEvent", function(self, event, ...) - if event == "ADDON_LOADED" then - local addon = object.addons[...] - if addon then - safecall(addon, "OnInitialize") - addon.OnInitialize = nil - for i, module in addon:IterateModules() do - safecall(module, "OnInitialize") - module.OnInitialize = nil - end - end - end - if event == "PLAYER_LOGOUT" then - for tbl, defaults in pairs(object.defaults) do - removeDefaults(tbl, defaults) - end - end - for module, eventHandler in pairs(object.events[event]) do - eventHandler(module, ...) - end -end) - -local function onUpdate(self, elapsed) - for module, update in pairs(object.onUpdates) do - update(module, elapsed) - end -end - -setmetatable(object.events, { - __index = function(table, key) - local newTable = {} - table[key] = newTable - return newTable - end -}) - -local AddonPrototype = {} -local ObjectPrototype = {} - -local function AddonEmbed(target) - for k, v in pairs(AddonPrototype) do - target[k] = v - end -end - -local function ObjectEmbed(target) - for k, v in pairs(ObjectPrototype) do - target[k] = v - end -end - -function Libra:NewAddon(name, addonObject) - if object.addons[name] then - error(format("Addon '%s' already exists.", name), 2) - end - - local addon = addonObject or {} - addon.name = name - addon.modules = {} - AddonEmbed(addon) - ObjectEmbed(addon) - object.addons[name] = addon - return addon, name -end - -function Libra:GetAddon(name) - return object.addons[name] -end - -function AddonPrototype:NewModule(name, table) - if self:GetModule(name) then - error(format("Module '%s' already exists in %s.", name, self.name), 2) - end - - local module = table or {} - ObjectEmbed(module) - module.name = name - tinsert(self.modules, module) - safecall(self, "OnModuleCreated", name, module) - return module, name -end - -function AddonPrototype:GetModule(name) - for i, module in self:IterateModules() do - if module.name == name then - return module - end - end -end - -function AddonPrototype:IterateModules() - return next, self.modules -end - -local function copyDefaults(src, dst) - if not src then return {} end - if not dst then dst = {} end - for k, v in pairs(src) do - if type(v) == "table" then - dst[k] = copyDefaults(v, dst[k]) - elseif type(v) ~= type(dst[k]) then - dst[k] = v - end - end - return dst -end - -function AddonPrototype:CreateDB(global, defaults) - local db = _G[global] - db = copyDefaults(defaults, db) - _G[global] = db - object.defaults[db] = defaults - return db -end - -function ObjectPrototype:RegisterEvent(event, handler) - if not next(object.events[event]) then - object.frame:RegisterEvent(event) - end - if type(handler) ~= "function" then - handler = self[handler] or self[event] - end - object.events[event][self] = handler -end - -function ObjectPrototype:UnregisterEvent(event) - object.events[event][self] = nil - if not next(object.events[event]) then - object.frame:UnregisterEvent(event) - end -end - -function ObjectPrototype:SetOnUpdate(handler) - if not next(object.onUpdates) then - object.frame:SetScript("OnUpdate", onUpdate) - end - if type(handler) ~= "function" then - handler = self[handler] - end - object.onUpdates[self] = handler -end - -function ObjectPrototype:RemoveOnUpdate() - object.onUpdates[self] = nil - if not next(object.onUpdates) then - object.frame:SetScript("OnUpdate", nil) - end -end - --- upgrade embeds -for k, v in pairs(object.addons) do - AddonEmbed(v) - ObjectEmbed(v) - for i, v in v:IterateModules() do - ObjectEmbed(v) - end -end - -Libra:RegisterModule(Type, Version) \ No newline at end of file diff --git a/libs/Libra-34/Button.lua b/libs/Libra-34/Button.lua deleted file mode 100644 index 9ee43a7..0000000 --- a/libs/Libra-34/Button.lua +++ /dev/null @@ -1,27 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Button", 2 -if Libra:GetModuleVersion(Type) >= Version then return end - -local function onEnable(self) - self.arrow:SetDesaturated(false) -end - -local function onDisable(self) - self.arrow:SetDesaturated(true) -end - -local function constructor(self, parent) - local button = CreateFrame("Button", nil, parent, "UIMenuButtonStretchTemplate") - button:SetHeight(23) - button:SetScript("OnEnable", onEnable) - button:SetScript("OnDisable", onDisable) - button.arrow = button:CreateTexture() - button.arrow:SetSize(10, 12) - button.arrow:SetPoint("RIGHT", -5, 0) - button.arrow:SetTexture([[Interface\ChatFrame\ChatFrameExpandArrow]]) - button.arrow:Hide() - button.Icon = button.arrow - return button -end - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Core.lua b/libs/Libra-34/Core.lua deleted file mode 100644 index 70f2943..0000000 --- a/libs/Libra-34/Core.lua +++ /dev/null @@ -1,65 +0,0 @@ -local MAJOR, MINOR = "Libra", 2 -local lib = LibStub:NewLibrary(MAJOR, MINOR) - -if not lib then return end - -lib.modules = lib.modules or {} -lib.moduleVersions = lib.moduleVersions or {} -lib.embeds = lib.widgetEmbeds or lib.embeds or {} -lib.methods = lib.methods or {} -lib.controls = lib.widgets or lib.controls or {} -lib.namespaces = lib.namespaces or {} - -function lib:RegisterModule(object, version, constructor) - self.moduleVersions[object] = version - if constructor then - self.controls[object] = constructor - self["Create"..object] = constructor - for k in pairs(self.embeds) do - k["Create"..object] = constructor - end - end -end - -function lib:GetModuleVersion(module) - return self.moduleVersions[module] or 0 -end - -function lib:RegisterMethods(tbl) - for k, v in pairs(tbl) do - for target in pairs(self.embeds) do - target[k] = v - end - self.methods[k] = v - end -end - -function lib:GetWidgetName(name) - name = name or "Generic" - local namespace = self.namespaces[name] - if not namespace then - local n = 0 - namespace = function() - n = n + 1 - return format("%sLibraWidget%d", name, n) - end - self.namespaces[name] = namespace - end - return namespace() -end - -function lib:Embed(target) - for k, v in pairs(self.methods) do - target[k] = v - end - for k, v in pairs(self.controls) do - target["Create"..k] = v - end - self.embeds[target] = true -end - -lib.EmbedWidgets = lib.Embed - -for k in pairs(lib.embeds) do - lib:Embed(k) -end \ No newline at end of file diff --git a/libs/Libra-34/Dropdown.lua b/libs/Libra-34/Dropdown.lua deleted file mode 100644 index ea80487..0000000 --- a/libs/Libra-34/Dropdown.lua +++ /dev/null @@ -1,548 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Dropdown", 12 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local Dropdown = Libra.modules[Type] -Dropdown.Prototype = Dropdown.Prototype or CreateFrame("Frame") -Dropdown.MenuPrototype = Dropdown.MenuPrototype or setmetatable({}, {__index = Dropdown.Prototype}) -Dropdown.FramePrototype = Dropdown.FramePrototype or setmetatable({}, {__index = Dropdown.Prototype}) -Dropdown.objects = Dropdown.objects or {} -Dropdown.listData = Dropdown.listData or {} -Dropdown.hookedLists = Dropdown.hookedLists or {} -Dropdown.hookedButtons = Dropdown.hookedButtons or {} -Dropdown.secureButtons = Dropdown.secureButtons or {} -Dropdown.secureBin = Dropdown.secureBin or {} - -local menuMT = {__index = Dropdown.MenuPrototype} -local frameMT = {__index = Dropdown.FramePrototype} - -local Prototype = Dropdown.Prototype -local MenuPrototype = Dropdown.MenuPrototype -local FramePrototype = Dropdown.FramePrototype -local objects = Dropdown.objects -local listData = Dropdown.listData - -local function setHeight() end - -local function constructor(self, type, parent, name) - local dropdown - if type == "Menu" then - -- adding a SetHeight dummy lets us use a simple table instead of a frame, no side effects noticed so far - dropdown = setmetatable({}, menuMT) - dropdown:SetDisplayMode("MENU") - dropdown.SetHeight = setHeight - dropdown.xOffset = 0 - dropdown.yOffset = 0 - end - if type == "Frame" then - name = name or Libra:GetWidgetName(self.name) - dropdown = setmetatable(CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate"), frameMT) - dropdown:SetWidth(115) - dropdown.label = dropdown:CreateFontString(name.."Label", "BACKGROUND", "GameFontNormalSmall") - dropdown.label:SetPoint("BOTTOMLEFT", dropdown, "TOPLEFT", 16, 3) - end - - objects[dropdown] = true - - return dropdown -end - - -local methods = { - Refresh = UIDropDownMenu_Refresh, -} - -for k, v in pairs(methods) do - Prototype[k] = v -end - -function Prototype:AddButton(info, level) - info.owner = self - if info.icon and not info.iconOnly then - -- hack to properly increase button width for icon when .iconOnly is not set - info.padding = (info.padding or 0) + 10 - end - self.displayMode = self._displayMode - self.selectedName = self._selectedName - self.selectedValue = self._selectedValue - self.selectedID = self._selectedID - UIDropDownMenu_AddButton(info, level) - self.displayMode = nil - self.selectedName = nil - self.selectedValue = nil - self.selectedID = nil -end - -function Prototype:ToggleMenu(value, anchorName, xOffset, yOffset, menuList, level, ...) - ToggleDropDownMenu(level, value, self, anchorName, xOffset, yOffset, menuList, ...) -end - -function Prototype:RebuildMenu(level) - level = level or 1 - if self:IsMenuShown(level) then - -- hiding a menu will also hide all deeper level menus, so we'll check which ones are open and restore them afterwards - local maxLevel - for i = level, UIDROPDOWNMENU_MENU_LEVEL do - if _G["DropDownList"..i]:IsShown() then - maxLevel = i - else - break - end - end - self:HideMenu(level) - for i = level, maxLevel do - local listData = listData[i] - -- set .rebuild to indicate that we don't want to reset the scroll offset on the next ToggleDropDownMenu - self.rebuild = true - self:ToggleMenu(listData.value, listData.anchorName, listData.xOffset, listData.yOffset, listData.menuList, i, listData.button, listData.autoHideDelay) - end - end -end - -function Prototype:HideMenu(level) - if UIDropDownMenu_GetCurrentDropDown() == self then - HideDropDownMenu(level) - end -end - -function Prototype:CloseMenus(level) - if UIDropDownMenu_GetCurrentDropDown() == self then - CloseDropDownMenus(level) - end -end - -function Prototype:IsMenuShown(level) - level = level or 1 - local listFrame = _G["DropDownList"..level] - return UIDropDownMenu_GetCurrentDropDown() == self and listFrame and listFrame:IsShown() -end - -function Prototype:SetSelectedName(name, useValue) - self._selectedName = name - self._selectedValue = nil - self._selectedID = nil - self.selectedName = name - self:Refresh(useValue) - self.selectedName = nil -end - -function Prototype:SetSelectedValue(value, useValue) - self._selectedValue = value - self._selectedName = nil - self._selectedID = nil - self.selectedValue = value - self:Refresh(useValue) - self.selectedValue = nil -end - -function Prototype:SetSelectedID(id, useValue) - self._selectedID = id - self._selectedName = nil - self._selectedValue = nil - self.selectedID = id - self:Refresh(useValue) - self.selectedID = nil -end - -function Prototype:GetSelectedName() - return self._selectedName -end - -function Prototype:GetSelectedValue() - return self._selectedValue -end - -function Prototype:GetSelectedID() - if self._selectedID then - return self._selectedID - else - -- If no explicit selectedID then try to send the id of a selected value or name - for i=1, UIDROPDOWNMENU_MAXBUTTONS do - local button = _G["DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..i] - -- See if checked or not - if self:GetSelectedName() then - if button:GetText() == self:GetSelectedName() then - return i - end - elseif self:GetSelectedValue() then - if button.value == self:GetSelectedValue() then - return i - end - end - end - end -end - -function Prototype:SetDisplayMode(mode) - self._displayMode = mode -end - - -local menuMethods = { - Toggle = Prototype.ToggleMenu, - Rebuild = Prototype.RebuildMenu, - Hide = Prototype.HideMenu, - Close = Prototype.CloseMenus, - IsShown = Prototype.IsMenuShown, -} - -for k, v in pairs(menuMethods) do - MenuPrototype[k] = v -end - - -local frameMethods = { - Enable = UIDropDownMenu_EnableDropDown, - Disable = UIDropDownMenu_DisableDropDown, - IsEnabled = UIDropDownMenu_IsEnabled, - JustifyText = UIDropDownMenu_JustifyText, - SetButtonWidth = UIDropDownMenu_SetButtonWidth, - SetText = UIDropDownMenu_SetText, - GetText = UIDropDownMenu_GetText, -} - -for k, v in pairs(frameMethods) do - FramePrototype[k] = v -end - -local setWidth = Prototype.SetWidth - -function FramePrototype:SetWidth(width, padding) - _G[self:GetName().."Middle"]:SetWidth(width) - local defaultPadding = 25 - if padding then - setWidth(self, width + padding) - _G[self:GetName().."Text"]:SetWidth(width) - else - setWidth(self, width + defaultPadding + defaultPadding) - _G[self:GetName().."Text"]:SetWidth(width - defaultPadding) - end - self.noResize = 1 -end - -function FramePrototype:SetLabel(text) - self.label:SetText(text) -end - -function FramePrototype:SetEnabled(enable) - if enable then - self:Enable() - else - self:Disable() - end -end - - -local numShownButtons - -local function update(level) - local scroll = listData[level].scroll - for i = 1, UIDROPDOWNMENU_MAXBUTTONS do - local button = _G["DropDownList"..level.."Button"..i] - local _, _, _, x, y = button:GetPoint() - local y = -((button:GetID() - 1 - scroll) * UIDROPDOWNMENU_BUTTON_HEIGHT) - UIDROPDOWNMENU_BORDER_HEIGHT - button:SetPoint("TOPLEFT", x, y) - button:SetShown(i > scroll and i <= (numShownButtons + scroll)) - end - Dropdown.scrollButtons[level].up:SetShown(scroll > 0) - Dropdown.scrollButtons[level].down:SetShown(scroll < _G["DropDownList"..level].numButtons - numShownButtons) -end - -local function scroll(self, delta) - local level = self:GetID() - local listData = listData[level] - delta = (type(delta) == "number" and delta or self.delta) - if IsShiftKeyDown() then delta = delta * (numShownButtons - 1) end - listData.scroll = listData.scroll - (type(delta) == "number" and delta or self.delta) - listData.scroll = min(listData.scroll, (self.numButtons or self:GetParent().numButtons) - numShownButtons) - listData.scroll = max(listData.scroll, 0) - update(level) -end - -local scrollScripts = { - OnEnter = function(self) - UIDropDownMenu_StopCounting(self:GetParent()) - end, - OnLeave = function(self) - UIDropDownMenu_StartCounting(self:GetParent()) - end, - OnMouseDown = function(self) - self.texture:SetPoint("CENTER", 1, -1) - end, - OnMouseUp = function(self) - self.texture:SetPoint("CENTER") - end, - OnHide = function(self) - self.texture:SetPoint("CENTER") - -- explicitly hide so that they are hidden for unmanaged dropdowns - self:Hide() - end, -} - -local function createScrollButton(listFrame) - local level = listFrame:GetID() - local button = CreateFrame("Button", nil, listFrame) - button:SetSize(16, 16) - button:SetScript("OnClick", scroll) - for script, handler in pairs(scrollScripts) do - button:SetScript(script, handler) - end - button:SetID(level) - button.texture = button:CreateTexture() - button.texture:SetSize(16, 16) - button.texture:SetPoint("CENTER") - button.texture:SetTexture([[Interface\Calendar\MoreArrow]]) - return button -end - -local function createScrollButtons(listFrame) - local scrollUp = listFrame.scrollUp or createScrollButton(listFrame) - scrollUp:SetPoint("TOP") - scrollUp.delta = 1 - scrollUp.texture:SetTexCoord(0, 1, 1, 0) - listFrame.scrollUp = scrollUp - - local scrollDown = listFrame.scrollDown or createScrollButton(listFrame) - scrollDown:SetPoint("BOTTOM") - scrollDown.delta = -1 - listFrame.scrollDown = scrollDown -end - -Dropdown.scrollButtons = Dropdown.scrollButtons or setmetatable({}, { - __index = function(self, level) - local listFrame = _G["DropDownList"..level] - createScrollButtons(listFrame) - self[level] = { - up = listFrame.scrollUp, - down = listFrame.scrollDown, - } - return self[level] - end, -}) - -function Dropdown:ToggleDropDownMenuHook(level, value, dropdownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay) - level = level or 1 - if level ~= 1 then - dropdownFrame = dropdownFrame or UIDROPDOWNMENU_OPEN_MENU - end - local listFrameName = "DropDownList"..level - local listFrame = _G[listFrameName] - if not objects[dropdownFrame] then - listFrame:SetScript("OnMouseWheel", nil) - return - end - if dropdownFrame and dropdownFrame._displayMode == "MENU" then - _G[listFrameName.."Backdrop"]:Hide() - _G[listFrameName.."MenuBackdrop"]:Show() - end - - -- store all parameters per level so we can use them to rebuild the menu - listData[level] = listData[level] or {} - local listData = listData[level] - listData.value = value - listData.anchorName = anchorName - listData.xOffset = xOffset - listData.yOffset = yOffset - listData.menuList = menuList - listData.button = button - listData.autoHideDelay = autoHideDelay - - numShownButtons = dropdownFrame.numShownButtons or floor((UIParent:GetHeight() - UIDROPDOWNMENU_BORDER_HEIGHT * 2) / UIDROPDOWNMENU_BUTTON_HEIGHT) - local scrollable = numShownButtons < listFrame.numButtons - if scrollable then - -- make scrollable - listData.scroll = listData.scroll or 0 - if not dropdownFrame.rebuild then - listData.scroll = 0 - end - listFrame:SetScript("OnMouseWheel", scroll) - listFrame:SetHeight((numShownButtons * UIDROPDOWNMENU_BUTTON_HEIGHT) + (UIDROPDOWNMENU_BORDER_HEIGHT * 2)) - if listFrame:GetTop() > GetScreenHeight() then - local point, anchorFrame, relativePoint, x, y = listFrame:GetPoint() - local offTop = (GetScreenHeight() - listFrame:GetTop())-- / listFrame:GetScale() - listFrame:SetPoint(point, anchorFrame, relativePoint, x, y + offTop) - end - update(level) - else - if listFrame:GetTop() > GetScreenHeight() then - local point, anchorFrame, relativePoint, x, y = listFrame:GetPoint() - local offTop = (GetScreenHeight() - listFrame:GetTop())-- / listFrame:GetScale() - listFrame:SetPoint(point, anchorFrame, relativePoint, x, y + offTop) - end - listFrame:SetScript("OnMouseWheel", nil) - self.scrollButtons[level].up:Hide() - self.scrollButtons[level].down:Hide() - end - dropdownFrame.rebuild = nil -end - -if not Dropdown.hookToggleDropDownMenu then - hooksecurefunc("ToggleDropDownMenu", function(...) - Dropdown:ToggleDropDownMenuHook(...) - end) - Dropdown.hookToggleDropDownMenu = true -end - -function Dropdown:AddButtonHook(info, level) - if not objects[UIDropDownMenu_GetCurrentDropDown()] then return end - local listFrameName = "DropDownList"..(level or 1) - local listFrame = _G[listFrameName] - local button = _G[listFrameName.."Button"..(listFrame.numButtons)] - button.onEnter = info.onEnter - button.onLeave = info.onLeave - button.tooltipLines = info.tooltipLines - if info.attributes and not InCombatLockdown() then - local secureButton = self.secureBin[1] - tremove(Dropdown.secureBin, 1) - -- since this is a separate button, we need to set the disabled state on it too - secureButton:SetEnabled(not info.disabled) - secureButton:SetParent(button) - secureButton:SetAllPoints() - secureButton:Show() - -- clear existing attributes - for attribute in pairs(secureButton.attributes) do - secureButton:SetAttribute(attribute, nil) - secureButton.attributes[attribute] = nil - end - for attribute, value in pairs(info.attributes) do - secureButton:SetAttribute(attribute, value) - secureButton.attributes[attribute] = true - end - tinsert(Dropdown.secureButtons, secureButton) - end -end - -if not Dropdown.hookAddButton then - hooksecurefunc("UIDropDownMenu_AddButton", function(...) - Dropdown:AddButtonHook(...) - end) - Dropdown.hookAddButton = true -end - -local function onEnter(self) - if self.onEnter then - self:onEnter() - elseif self.tooltipLines and self.tooltipTitle then - GameTooltip:SetOwner(self, "ANCHOR_RIGHT") - GameTooltip:AddLine(self.tooltipTitle, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) - if self.tooltipText then - for line in self.tooltipText:gmatch("[^\n]+") do - GameTooltip:AddLine(line) - end - end - GameTooltip:Show() - end -end - -local function onLeave(self) - if self.onLeave then - self:onLeave() - end -end - -local function invisibleButtonOnEnter(self) - local parent = self:GetParent() - if parent.onEnter or parent.tooltipWhileDisabled then - onEnter(parent) - end -end - -local function invisibleButtonOnLeave(self) - local parent = self:GetParent() - if parent.onLeave or parent.tooltipWhileDisabled then - onLeave(parent) - end -end - -local function listOnHide(self) - if not InCombatLockdown() then - for i = #Dropdown.secureButtons, 1, -1 do - -- hide secure buttons attached to this list frame - local button = Dropdown.secureButtons[i] - if button:GetParent():GetParent() == self then - Dropdown:DismissSecureButton(button) - tremove(Dropdown.secureButtons, i) - end - end - end -end - -function Dropdown:CreateFramesHook(numLevels, numButtons) - for level = 1, numLevels do - if not self.hookedLists[level] then - _G["DropDownList"..level]:HookScript("OnHide", listOnHide) - self.hookedLists[level] = true - end - self.hookedButtons[level] = self.hookedButtons[level] or {} - for i = 1, numButtons do - if not self.hookedButtons[level][i] then - _G["DropDownList"..level.."Button"..i]:HookScript("OnEnter", onEnter) - _G["DropDownList"..level.."Button"..i]:HookScript("OnLeave", onLeave) - _G["DropDownList"..level.."Button"..i.."InvisibleButton"]:HookScript("OnEnter", invisibleButtonOnEnter) - _G["DropDownList"..level.."Button"..i.."InvisibleButton"]:HookScript("OnLeave", invisibleButtonOnLeave) - self.hookedButtons[level][i] = true - end - end - end -end - -if not Dropdown.hookCreateFrames then - Dropdown:CreateFramesHook(UIDROPDOWNMENU_MAXLEVELS, UIDROPDOWNMENU_MAXBUTTONS) - hooksecurefunc("UIDropDownMenu_CreateFrames", function(...) - Dropdown:CreateFramesHook(...) - end) - Dropdown.hookCreateFrames = true -end - --- script handlers to mimic regular dropdown button behaviour -local scripts = { - PreClick = function(self) - local parent = self:GetParent() - parent:GetScript("OnClick")(parent) - end, - OnMouseDown = function(self) - self:GetParent():SetButtonState("PUSHED") - end, - OnMouseUp = function(self) - self:GetParent():SetButtonState("NORMAL") - end, - OnEnter = function(self) - local parent = self:GetParent() - parent:GetScript("OnEnter")(parent) - end, - OnLeave = function(self) - local parent = self:GetParent() - parent:GetScript("OnLeave")(parent) - end, -} - -setmetatable(Dropdown.secureBin, { - __index = function(self, index) - local button = CreateFrame("Button", nil, nil, "SecureActionButtonTemplate") - for script, handler in pairs(scripts) do - button:SetScript(script, handler) - end - button.attributes = {} - return button - end, -}) - -function Dropdown:DismissSecureButton(button) - button:Hide() - button:ClearAllPoints() - button:SetParent(nil) - tinsert(Dropdown.secureBin, button) -end - -Dropdown.frame = Dropdown.frame or CreateFrame("Frame") -Dropdown.frame:RegisterEvent("PLAYER_REGEN_DISABLED") -Dropdown.frame:SetScript("OnEvent", function(self) - for i, button in ipairs(Dropdown.secureButtons) do - Dropdown:DismissSecureButton(button) - end - wipe(Dropdown.secureButtons) -end) - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Editbox.lua b/libs/Libra-34/Editbox.lua deleted file mode 100644 index 28358a2..0000000 --- a/libs/Libra-34/Editbox.lua +++ /dev/null @@ -1,12 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Editbox", 3 -if Libra:GetModuleVersion(Type) >= Version then return end - -local function constructor(self, parent, isSearchBox) - local editbox = CreateFrame("EditBox", nil, parent, isSearchBox and "SearchBoxTemplate" or "InputBoxTemplate") - editbox:SetHeight(20) - editbox:SetAutoFocus(false) - return editbox -end - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Libra.xml b/libs/Libra-34/Libra.xml deleted file mode 100644 index 02a5fb6..0000000 --- a/libs/Libra-34/Libra.xml +++ /dev/null @@ -1,16 +0,0 @@ -<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ -..\FrameXML\UI.xsd"> - <Script file="Core.lua"/> - - <Script file="Addon.lua"/> - <Script file="AceDBControls.lua"/> - <Script file="Button.lua"/> - <Script file="Dropdown.lua"/> - <Script file="Editbox.lua"/> - <Script file="OptionsFrame.lua"/> - <Script file="ScrollFrame.lua"/> - <Script file="Slider.lua"/> - <Script file="Templates.lua"/> - <Script file="UIPanel.lua"/> - <Script file="Utils.lua"/> -</Ui> \ No newline at end of file diff --git a/libs/Libra-34/OptionsFrame.lua b/libs/Libra-34/OptionsFrame.lua deleted file mode 100644 index e9dfeab..0000000 --- a/libs/Libra-34/OptionsFrame.lua +++ /dev/null @@ -1,475 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "OptionsFrame", 4 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local Options = Libra.modules[Type] - -Options.Prototype = Options.Prototype or CreateFrame("Frame") -Options.ParentPrototype = Options.ParentPrototype or {} -Options.controls = Options.controls or {} -Options.controlData = Options.controlData or {} - -local mt = {__index = Options.Prototype} -local parentMT = {__index = setmetatable(Options.ParentPrototype, {__index = Options.Prototype})} - -local Prototype = Options.Prototype -local ParentPrototype = Options.ParentPrototype - -local function createFrame(name, parent) - local frame = CreateFrame("Frame") - frame.name = name - frame.parent = parent - InterfaceOptions_AddCategory(frame) - - local title = frame:CreateFontString(nil, nil, "GameFontNormalLarge") - title:SetPoint("TOPLEFT", 16, -16) - title:SetPoint("RIGHT", -16, 0) - title:SetJustifyH("LEFT") - title:SetJustifyV("TOP") - title:SetText(name) - frame.title = title - - local desc = frame:CreateFontString(nil, nil, "GameFontHighlightSmall") - desc:SetHeight(32) - desc:SetPoint("TOPLEFT", frame.title, "BOTTOMLEFT", 0, -8) - desc:SetPoint("RIGHT", -31, 0) - desc:SetJustifyH("LEFT") - desc:SetJustifyV("TOP") - desc:SetNonSpaceWrap(true) - frame.desc = desc - - return frame -end - -local function constructor(self, name) - local frame = setmetatable(createFrame(name), parentMT) - frame.controls = {} - frame.allcontrols = {} - return frame -end - - -function ParentPrototype:AddSubCategory(name, inherit) - local frame = setmetatable(createFrame(name, self.name), mt) - if inherit then - frame.db = self.db - frame.useProfile = self.useProfile - frame.handler = self.handler - frame.allcontrols = self.allcontrols - else - frame.allcontrols = {} - end - frame.inherit = inherit - frame.controls = {} - self.subCategories = self.subCategories or {} - tinsert(self.subCategories, frame) - return frame -end - -function Prototype:SetDescription(text) - self.desc:SetText(text) -end - -function Prototype:SetDatabase(database, useProfile) - self.db = database - self.useProfile = useProfile - if self.subCategories then - for i, v in ipairs(self.subCategories) do - if v.inherit then - v.db = database - end - end - end -end - -function Prototype:SetHandler(tbl) - self.handler = tbl - if self.subCategories then - for i, v in ipairs(self.subCategories) do - if v.inherit then - v.handler = tbl - end - end - end -end - - -local function getTable(control) - local tbl = control.parent.db - if control.parent.useProfile then - tbl = tbl.profile - end - if control.keyTable then - tbl = tbl[control.keyTable] - end - return tbl -end - -local function getFunc(control, method, key, value) - local func = control[method] - if func then - local object = control - if type(func) == "string" then - object = control.parent.handler - func = object[func] - end - if key then - return true, func(object, key, value) - else - return true, func(object, value) - end - return true - end -end - -local function set(self, value, key) - if not getFunc(self, "set", key, value) then - local tbl = getTable(self) - if tbl then - tbl[key or self.key] = value - end - end - getFunc(self, "func", key, value) - for key, control in pairs(self.parent.allcontrols) do - if control.disabled then - control:SetEnabled(not control.disabled()) - end - end -end - -local function get(self, key) - local hasFunc, value = getFunc(self, "get", key) - if hasFunc then - return value - else - local tbl = getTable(self) - if tbl then - return tbl[key or self.key] - end - end -end - -local controls = Options.controls -local controlData = Options.controlData - -do -- CheckButton - controlData.CheckButton = { - x = -2, - y = -16, - bottomOffset = 8, - } - - local function onClick(self) - local checked = self:GetChecked() - PlaySound(checked and "igMainMenuOptionCheckBoxOn" or "igMainMenuOptionCheckBoxOff") - set(self, checked) - end - - controls.CheckButton = function(parent) - local checkButton = CreateFrame("CheckButton", nil, parent, "OptionsBaseCheckButtonTemplate") - checkButton:SetNormalFontObject("GameFontHighlight") - checkButton:SetDisabledFontObject("GameFontDisable") - checkButton:SetPushedTextOffset(0, 0) - checkButton:SetScript("OnClick", onClick) - checkButton.SetValue = checkButton.SetChecked - - checkButton.label = checkButton:CreateFontString() - checkButton.label:SetPoint("LEFT", checkButton, "RIGHT", 0, 1) - checkButton:SetFontString(checkButton.label) - - return checkButton - end -end - -do -- ColorButton - controlData.ColorButton = { - x = 3, - y = -21, - bottomOffset = 3, - } - - local ColorPickerFrame = ColorPickerFrame - - local function setColor(self, color) - self.swatch:SetVertexColor(color.r, color.g, color.b) - end - - local function saveColor(self, r, g, b) - self.swatch:SetVertexColor(r, g, b) - local color = get(self) - color.r = r - color.g = g - color.b = b - set(self, color) - end - - local function swatchFunc() - saveColor(ColorPickerFrame.extraInfo, ColorPickerFrame:GetColorRGB()) - end - - local function cancelFunc(prev) - saveColor(ColorPickerFrame.extraInfo, ColorPicker_GetPreviousValues()) - end - - local scripts = { - OnClick = function(self) - local info = UIDropDownMenu_CreateInfo() - local color = get(self) - info.r, info.g, info.b = color.r, color.g, color.b - info.swatchFunc = swatchFunc - info.cancelFunc = cancelFunc - info.extraInfo = self - OpenColorPicker(info) - end, - - OnEnter = function(self) - self.bg:SetVertexColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) - if self.tooltipText then - GameTooltip:SetOwner(self, "ANCHOR_RIGHT") - GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true) - end - end, - - OnLeave = function(self) - self.bg:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) - GameTooltip:Hide() - end, - - OnEnable = function(self) - if self:IsMouseOver() then - self:OnEnter() - else - self.bg:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) - end - end, - - OnDisable = function(self) - self.bg:SetVertexColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b) - end, - } - - controls.ColorButton = function(parent, data) - local colorButton = CreateFrame("Button", nil, parent) - colorButton:SetSize(16, 16) - colorButton:SetNormalFontObject("GameFontHighlight") - colorButton:SetDisabledFontObject("GameFontDisable") - colorButton:SetPushedTextOffset(0, 0) - for script, handler in pairs(scripts) do - colorButton:SetScript(script, handler) - colorButton[script] = handler - end - colorButton.SetValue = setColor - - colorButton:SetNormalTexture([[Interface\ChatFrame\ChatFrameColorSwatch]]) - colorButton.swatch = colorButton:GetNormalTexture() - - colorButton.bg = colorButton:CreateTexture(nil, "BACKGROUND") - colorButton.bg:SetSize(14, 14) - colorButton.bg:SetPoint("CENTER") - colorButton.bg:SetTexture(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) - - colorButton.label = colorButton:CreateFontString() - colorButton.label:SetPoint("LEFT", colorButton, "RIGHT", 5, 1) - colorButton:SetFontString(colorButton.label) - - return colorButton - end -end - -do -- Slider - controlData.Slider = { - x = 7, - y = -27, - bottomOffset = -5, - } - - local function onValueChanged(self, value, isUserInput) - if isUserInput then - set(self, value) - end - if self.isPercent then - self.currentValue:SetFormattedText("%.0f%%", value * 100) - else - self.currentValue:SetText(value) - end - end - - local function onMinMaxChanged(self, min, max) - if self.minText or not self.isPercent then - self.min:SetText(self.minText or min) - else - self.min:SetFormattedText("%.0f%%", min * 100) - end - if self.maxText or not self.isPercent then - self.max:SetText(self.maxText or max) - else - self.max:SetFormattedText("%.0f%%", max * 100) - end - end - - controls.Slider = function(parent, data) - local slider = Libra:CreateSlider(parent) - slider:SetScript("OnValueChanged", onValueChanged) - slider:SetScript("OnMinMaxChanged", onMinMaxChanged) - slider.isPercent = data.isPercent - slider.minText = data.minText - slider.maxText = data.maxText - slider:SetMinMaxValues(data.min, data.max) - slider:SetValueStep(data.step) - return slider - end -end - -do -- Dropdown - controlData.Dropdown = { - x = -15, - y = -32, - bottomOffset = 8, - } - - local function getValue(dropdown, property, value) - local properties = dropdown.properties - local property = properties and properties[property] - if not properties or not property then - return value - else - if type(property) == "function" then - return property(value) - elseif type(property) == "table" then - return property[value] - else - return property - end - end - end - - local function setText(self, value) - self:SetText(getValue(self, "text", value)) - end - - local defaultProperties = { - "text", - "value", - "arg1", - } - - local function onClick(self, arg1, arg2, checked) - if self.owner.multiSelect then - set(self.owner, checked, arg1) - else - self.owner:SetText(self:GetText()) - set(self.owner, arg1) - end - end - - local function checked(self) - if self.owner.multiSelect then - return get(self.owner, self.arg1) - else - return self.arg1 == get(self.owner) - end - end - - local function initialize(self, level, menuList) - menuList = menuList or self.menulist - if type(menuList) == "function" then - menuList = menuList() - end - for i, v in ipairs(menuList) do - local info = UIDropDownMenu_CreateInfo() - info.func = onClick - info.checked = checked - info.isNotRadio = self.multiSelect - for i, propertyName in ipairs(defaultProperties) do - info[propertyName] = getValue(self, propertyName, v) - end - if self.properties then - for propertyName in pairs(self.properties) do - info[propertyName] = getValue(self, propertyName, v) - end - end - self:AddButton(info) - end - end - - controls.Dropdown = function(parent, data) - local dropdown = Libra:CreateDropdown("Frame", parent) - dropdown:JustifyText("LEFT") - dropdown.SetValue = setText - dropdown.initialize = data.initialize or initialize - dropdown.menulist = data.menuList - dropdown.multiSelect = data.multiSelect - if data.properties then - dropdown.properties = {} - for k, v in pairs(data.properties) do - dropdown.properties[k] = v - end - end - return dropdown - end -end - -function Libra:AddControlType(type, constructor, controlData) - if Options.controls[type] then - error(format("Control type '%s' already exists.", type), 2) - end - Options.controls[type] = constructor - controlData = controlData or {} - controlData.x = controlData.x or 0 - controlData.y = controlData.y or 0 - controlData.bottomOffset = controlData.bottomOffset or 0 - Options.controlData[type] = controlData -end - -function Prototype:CreateOptions(options) - for i, option in ipairs(options) do - local control = controls[option.type](self, option) - local data = controlData[option.type] - if i == 1 then - control:SetPoint("TOPLEFT", self.desc, "BOTTOMLEFT", data.x, data.y + 8) - elseif option.newColumn then - control:SetPoint("TOPLEFT", self.desc, "BOTTOM", data.x - 2, data.y + 8) - else - local previousOption = options[i - 1] - local previousData = controlData[previousOption.type] - control:SetPoint("TOPLEFT", self.controls[i - 1], "BOTTOMLEFT", data.x - previousData.x, data.y + previousData.bottomOffset - (option.padding or 0)) - end - if option.width then - control:SetWidth(option.width) - end - control.parent = self - control.label:SetText(option.text) - control.tooltipText = option.tooltip - control.key = option.key - control.keyTable = option.keyTable - control.set = option.set - control.get = option.get - control.func = option.func - control.disabled = option.disabled - tinsert(self.controls, control) - tinsert(self.allcontrols, control) - end -end - -function Prototype:SetupControls() - for i, control in ipairs(self.allcontrols) do - local value = get(control) - control:SetValue(value) - getFunc(control, "func", key, value) - if control.disabled then - control:SetEnabled(not control.disabled()) - end - end -end - -function Prototype:GetControlByKey(key, keyTable) - for i, control in ipairs(self.allcontrols) do - if control.key == key and control.keyTable == keyTable then - return control - end - end -end - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/ScrollFrame.lua b/libs/Libra-34/ScrollFrame.lua deleted file mode 100644 index dfd8541..0000000 --- a/libs/Libra-34/ScrollFrame.lua +++ /dev/null @@ -1,137 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "ScrollFrame", 6 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local ScrollFrame = Libra.modules[Type] - -ScrollFrame.FauxPrototype = ScrollFrame.FauxPrototype or CreateFrame("ScrollFrame") -ScrollFrame.HybridPrototype = ScrollFrame.HybridPrototype or CreateFrame("ScrollFrame") - -local fauxMT = {__index = ScrollFrame.FauxPrototype} -local hybridMT = {__index = ScrollFrame.HybridPrototype} - -local HybridPrototype = ScrollFrame.HybridPrototype - -local function fauxOnVerticalScroll(self, offset) - self.Scrollbar:SetValue(offset) - self.offset = floor((offset / self.buttonHeight) + 0.5) - self:Update() -end - -local function update(self) - local offset = self:GetOffset() - local numItems = self.getNumItems() - for i, button in ipairs(self.buttons) do - local index = offset + i - if index <= numItems then - self.updateButton(button, index) - end - button:SetShown(index <= numItems) - end - local totalHeight = numItems * self.buttonHeight - local displayedHeight = #self.buttons * self.buttonHeight - if self.dynamic then - totalHeight = self.dynamic() - elseif self.largeButtonTop then - totalHeight = totalHeight - (self.buttonHeight - self.largeButtonHeight) - end - HybridScrollFrame_Update(self, totalHeight, displayedHeight) - if self.onScroll then - self:onScroll() - end -end - -local function constructor(self, type, parent, name) - local scrollFrame - if type == "Faux" then - scrollFrame = setmetatable(CreateFrame("ScrollFrame", name, parent, "FauxScrollFrameTemplate"), fauxMT) - scrollFrame:SetScript("OnVerticalScroll", fauxOnVerticalScroll) - end - if type == "Hybrid" then - name = name or Libra:GetWidgetName(self.name) - scrollFrame = setmetatable(CreateFrame("ScrollFrame", name, parent, "HybridScrollFrameTemplate"), hybridMT) - scrollFrame.update = function() update(scrollFrame) end - scrollFrame.scrollBar = CreateFrame("Slider", nil, scrollFrame, "HybridScrollBarTemplate") - end - - return scrollFrame -end - - -local fauxMethods = { - Update = FauxScrollFrame_Update, - SetOffset = FauxScrollFrame_SetOffset, - GetOffset = FauxScrollFrame_GetOffset, -} - -for k, v in pairs(fauxMethods) do - ScrollFrame.FauxPrototype[k] = v -end - -local hybridMethods = { - -- Update = HybridScrollFrame_Update, - -- SetOffset = HybridScrollFrame_SetOffset, - GetOffset = HybridScrollFrame_GetOffset, - CollapseButton = HybridScrollFrame_CollapseButton, -} - -for k, v in pairs(hybridMethods) do - ScrollFrame.HybridPrototype[k] = v -end - -local function setHeader(self) - self:SetHeight(self.parent.headerHeight) -end - -local function resetHeight(self) - self:SetHeight(self.parent.buttonHeightReal) -end - -function HybridPrototype:CreateButtons() - self.buttons = self.buttons or {} - local scrollChild = self.scrollChild - local numButtons = ceil(self:GetHeight() / self.buttonHeightReal) + 1 - for i = #self.buttons + 1, numButtons do - local button = self.createButton(scrollChild) - if i == 1 then - button:SetPoint(self.initialPoint or "TOPLEFT", scrollChild, self.initialRelative or "TOPLEFT", (self.initialOffsetX or 0), (self.initialOffsetY or 0)) - else - button:SetPoint(self.point or "TOPLEFT", self.buttons[i - 1], self.relativePoint or "BOTTOMLEFT", (self.offsetX or 0), (self.offsetY or 0)) - end - button:SetHeight(self.buttonHeightReal) - button.SetHeader = setHeader - button.ResetHeight = resetHeight - button.parent = self - self.buttons[i] = button - end - - self.buttonHeight = self.buttonHeightReal - (self.offsetY or 0) - - scrollChild:SetWidth(self:GetWidth()) - scrollChild:SetHeight(numButtons * self.buttonHeightReal) - self:SetVerticalScroll(0) - self:UpdateScrollChildRect() - - local scrollBar = self.scrollBar - scrollBar:SetMinMaxValues(0, numButtons * self.buttonHeightReal) - scrollBar.buttonHeight = self.buttonHeightReal - scrollBar:SetValueStep(self.buttonHeightReal) - scrollBar:SetStepsPerPage(numButtons - 2) - scrollBar:SetValue(0) -end - -function HybridPrototype:SetButtonHeight(height) - self.buttonHeightReal = height -end - -function HybridPrototype:SetHeaderHeight(height) - self.headerHeight = height -end - -function HybridPrototype:ExpandButton(numButtons) - HybridScrollFrame_ExpandButton(self, numButtons * self.buttonHeight, self.headerHeight) -end - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Slider.lua b/libs/Libra-34/Slider.lua deleted file mode 100644 index 20202de..0000000 --- a/libs/Libra-34/Slider.lua +++ /dev/null @@ -1,54 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Slider", 2 -if Libra:GetModuleVersion(Type) >= Version then return end - -local backdrop = { - bgFile = [[Interface\Buttons\UI-SliderBar-Background]], - edgeFile = [[Interface\Buttons\UI-SliderBar-Border]], - edgeSize = 8, - insets = {left = 3, right = 3, top = 6, bottom = 6} -} - -local function onEnter(self) - if self:IsEnabled() then - if self.tooltipText then - GameTooltip:SetOwner(self, self.tooltipOwnerPoint or "ANCHOR_RIGHT") - GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true) - end - if self.tooltipRequirement then - GameTooltip:AddLine(self.tooltipRequirement, 1.0, 1.0, 1.0) - GameTooltip:Show() - end - end -end - -local function onLeave(self) - GameTooltip:Hide() -end - -local function constructor(self, parent) - local slider = CreateFrame("Slider", nil, parent) - slider:SetSize(144, 17) - slider:SetBackdrop(backdrop) - slider:SetThumbTexture([[Interface\Buttons\UI-SliderBar-Button-Horizontal]]) - slider:SetOrientation("HORIZONTAL") - slider:SetObeyStepOnDrag(true) - slider:SetScript("OnEnter", onEnter) - slider:SetScript("OnLeave", onLeave) - - slider.label = slider:CreateFontString(nil, nil, "GameFontNormal") - slider.label:SetPoint("BOTTOM", slider, "TOP") - - slider.min = slider:CreateFontString(nil, nil, "GameFontHighlightSmall") - slider.min:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", -4, 3) - - slider.max = slider:CreateFontString(nil, nil, "GameFontHighlightSmall") - slider.max:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", 4, 3) - - slider.currentValue = slider:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall") - slider.currentValue:SetPoint("CENTER", 0, -15) - - return slider -end - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/UIPanel.lua b/libs/Libra-34/UIPanel.lua deleted file mode 100644 index 049a76f..0000000 --- a/libs/Libra-34/UIPanel.lua +++ /dev/null @@ -1,102 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "UIPanel", 1 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local UIPanel = Libra.modules[Type] -UIPanel.Prototype = UIPanel.Prototype or CreateFrame("Frame") - -local Prototype = UIPanel.Prototype -local mt = {__index = Prototype} - -local function safecall(object, method, ...) - if object[method] then - object[method](object, ...) - end -end - -local function constructor(self, name) - name = name or Libra:GetWidgetName(self.name) - local panel = setmetatable(CreateFrame("Frame", name, UIParent, "ButtonFrameTemplate"), mt) - - tinsert(UISpecialFrames, name) - UIPanelWindows[name] = { - area = "left", - pushable = 1, - whileDead = true, - } - - return panel -end - - -local methods = { - ShowPortrait = ButtonFrameTemplate_ShowPortrait, - HidePortrait = ButtonFrameTemplate_HidePortrait, - ShowAttic = ButtonFrameTemplate_ShowAttic, - HideAttic = ButtonFrameTemplate_HideAttic, - ShowButtonBar = ButtonFrameTemplate_ShowButtonBar, - - GetSelectedTab = PanelTemplates_GetSelectedTab, - UpdateTabs = PanelTemplates_UpdateTabs, - EnableTab = PanelTemplates_EnableTab, - DisableTab = PanelTemplates_DisableTab, - -- GetTabWidth = PanelTemplates_GetTabWidth, - -- TabResize = PanelTemplates_TabResize, -} - -for k, v in pairs(methods) do - Prototype[k] = v -end - -function Prototype:SetTitleText(text) - self.TitleText:SetText(text) -end - -function Prototype:HideButtonBar() - ButtonFrameTemplate_HideButtonBar(self) - self.Inset:SetPoint("BOTTOMRIGHT", PANEL_INSET_RIGHT_OFFSET, PANEL_INSET_BOTTOM_OFFSET + 2) -end - - -local function onClick(self) - self:GetParent():SelectTab(self:GetID()) - PlaySound("igCharacterInfoTab") -end - -function Prototype:CreateTab(name) - self.tabs = self.tabs or {} - if type(name) == "number" then - error("Tab name may not be a number.", 2) - end - -- if type(name) == "number" then - -- error(format("%s already has a tab named '%s'.", self:GetName(), name), 2) - -- end - local tabs = self.tabs - local numTabs = #tabs + 1 - local tab = CreateFrame("Button", self:GetName().."Tab"..numTabs, self, "CharacterFrameTabButtonTemplate") - if numTabs == 1 then - tab:SetPoint("BOTTOMLEFT", 19, -30) - else - tab:SetPoint("LEFT", tabs[numTabs - 1], "RIGHT", -15, 0) - end - tab:SetID(numTabs) - tab:SetScript("OnClick", onClick) - tabs[numTabs] = tab - self.numTabs = numTabs - return tab -end - -function Prototype:SelectTab(id) - local selectedTab = self:GetSelectedTab() - if selectedTab then - safecall(self, "OnTabDeselected", selectedTab) - end - self.selectedTab = id - self:UpdateTabs() - safecall(self, "OnTabSelected", id) -end - - -Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-34/Utils.lua b/libs/Libra-34/Utils.lua deleted file mode 100644 index 4edee27..0000000 --- a/libs/Libra-34/Utils.lua +++ /dev/null @@ -1,45 +0,0 @@ -local Libra = LibStub("Libra") -local Type, Version = "Utils", 1 -if Libra:GetModuleVersion(Type) >= Version then return end - -Libra.modules[Type] = Libra.modules[Type] or {} - -local object = Libra.modules[Type] -object.api = object.api or {} -object.frame = object.frame or CreateFrame("Frame") -object.connectedRealms = object.connectedRealms or {} -object.connectedRealmsSorted = object.connectedRealmsSorted or {} - -object.frame:RegisterEvent("PLAYER_LOGIN") -object.frame:SetScript("OnEvent", function(self, event, ...) - object[event](object, ...) - self:UnregisterEvent(event) -end) - -function object:PLAYER_LOGIN() - local _, realm = UnitFullName("player") - self.myRealm = realm - self.connectedRealmsSorted = GetAutoCompleteRealms() or {} - for i, v in ipairs(self.connectedRealmsSorted) do - self.connectedRealms[v] = true - if v == self.myRealm then - tremove(self.connectedRealmsSorted, i) - end - end - sort(self.connectedRealmsSorted) - tinsert(self.connectedRealmsSorted, 1, self.myRealm) -end - -function object.api:IsConnectedRealm(realm, includeOwn) - if not realm then return end - realm = realm:gsub("[ -]", "") - return (realm ~= object.myRealm or includeOwn) and object.connectedRealms[realm] -end - -function object.api:GetConnectedRealms() - return object.connectedRealmsSorted -end - -Libra:RegisterMethods(object.api) - -Libra:RegisterModule(Type, Version) \ No newline at end of file diff --git a/libs/Libra-36/AceDBControls.lua b/libs/Libra-36/AceDBControls.lua new file mode 100644 index 0000000..d0cfc8c --- /dev/null +++ b/libs/Libra-36/AceDBControls.lua @@ -0,0 +1,352 @@ +local Libra = LibStub("Libra") +local Type, Version = "AceDBControls", 4 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local AceDBControls = Libra.modules[Type] +AceDBControls.Prototype = AceDBControls.Prototype or CreateFrame("Frame") + +local Prototype = AceDBControls.Prototype +local mt = {__index = Prototype} + +local L = { + default = "Default", + reset = "Reset profile", + new = "Create new profile", + choose = "Active profile", + copy = "Copy from", + delete = "Delete a profile", + delete_confirm = "Are you sure you want to delete the selected profile?", + profiles = "Profiles", + + dual_profile = "Dual profile", + enabled = "Enable dual profile", +} + +local LOCALE = GetLocale() +if LOCALE == "deDE" then + L["default"] = "Standard" + L["reset"] = "Profil zur\195\188cksetzen" + L["new"] = "Neu" + L["choose"] = "Vorhandene Profile" + L["copy"] = "Kopieren von..." + L["delete"] = "Profil l\195\182schen" + L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?" + L["profiles"] = "Profile" + + L["dual_profile"] = "Duales Profil" + L["enabled"] = "Aktiviere Duale Profile" +elseif LOCALE == "frFR" then + L["default"] = "D\195\169faut" + L["reset"] = "R\195\169initialiser le profil" + L["new"] = "Nouveau" + L["choose"] = "Profils existants" + L["copy"] = "Copier \195\160 partir de" + L["delete"] = "Supprimer un profil" + L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?" + L["profiles"] = "Profils" + + L["dual_profile"] = 'Second profil' + L["enabled"] = 'Activez le second profil' +elseif LOCALE == "koKR" then + L["default"] = "기본값" + L["reset"] = "프로필 초기화" + L["new"] = "새로운 프로필" + L["choose"] = "프로필 선택" + L["copy"] = "복사" + L["delete"] = "프로필 삭제" + L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?" + L["profiles"] = "프로필" + + L["dual_profile"] = "이중 프로필" + L["enabled"] = "이중 프로필 사용" +elseif LOCALE == "esES" or LOCALE == "esMX" then + L["default"] = "Por defecto" + L["reset"] = "Reiniciar Perfil" + L["new"] = "Nuevo" + L["choose"] = "Perfiles existentes" + L["copy"] = "Copiar de" + L["delete"] = "Borrar un Perfil" + L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?" + L["profiles"] = "Perfiles" +elseif LOCALE == "zhTW" then + L["default"] = "預設" + L["reset"] = "重置設定檔" + L["new"] = "新建" + L["choose"] = "現有的設定檔" + L["copy"] = "複製自" + L["delete"] = "刪除一個設定檔" + L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?" + L["profiles"] = "設定檔" +elseif LOCALE == "zhCN" then + L["default"] = "默认" + L["reset"] = "重置配置文件" + L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。" + L["new"] = "新建" + L["choose"] = "现有的配置文件" + L["copy"] = "复制自" + L["delete"] = "删除一个配置文件" + L["delete_confirm"] = "你确定要删除所选择的配置文件么?" + L["profiles"] = "配置文件" + + L["dual_profile"] = "双重配置文件" + L["enabled"] = "开启双重配置文件" +elseif LOCALE == "ruRU" then + L["default"] = "По умолчанию" + L["reset"] = "Сброс профиля" + L["new"] = "Новый" + L["choose"] = "Существующие профили" + L["copy"] = "Скопировать из" + L["delete"] = "Удалить профиль" + L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?" + L["profiles"] = "Профили" + + L["dual_profile"] = "Второй профиль" + L["enabled"] = "Включить двойной профиль" +end + +local defaultProfiles = {} + +local function profileSort(a, b) + return a.value < b.value +end + +local tempProfiles = {} + +local function getProfiles(db, common, nocurrent) + local profiles = {} + + -- copy existing profiles into the table + local currentProfile = db:GetCurrentProfile() + for _, v in ipairs(db:GetProfiles(tempProfiles)) do + if not (nocurrent and v == currentProfile) then + profiles[v] = v + end + end + + -- add our default profiles to choose from (or rename existing profiles) + for k, v in pairs(defaultProfiles) do + if (common or profiles[k]) and not (nocurrent and k == currentProfile) then + profiles[k] = v + end + end + + local sortProfiles = {} + for k, v in pairs(profiles) do + tinsert(sortProfiles, {text = v, value = k}) + end + sort(sortProfiles, profileSort) + + return sortProfiles +end + +local function dropdownOnClick(self, profile, func) + func(self.owner.db, profile, self.owner) +end + +local function initializeDropdown(self, level, menuList) + for i, v in ipairs(getProfiles(self.db, self.common, self.nocurrent)) do + local info = UIDropDownMenu_CreateInfo() + info.text = v.text + info.func = dropdownOnClick + info.arg1 = v.value + info.arg2 = self.func + info.checked = not self.nocurrent and (v.value == self.getCurrent(self.db)) + info.notCheckable = self.nocurrent + self:AddButton(info) + end +end + +local function createDropdown(parent) + local dropdown = Libra:CreateDropdown("Frame", parent) + dropdown:SetWidth(160) + dropdown:JustifyText("LEFT") + dropdown.initialize = initializeDropdown + return dropdown +end + +local function menuButton_OnClick(self) + self.menu:Toggle() +end + +local function createMenuButton(parent) + local button = Libra:CreateButton(parent) + button:SetScript("OnClick", menuButton_OnClick) + button.arrow:Show() + button:SetWidth(88) + + local menu = Libra:CreateDropdown("Menu") + menu.relativeTo = button + menu.initialize = initializeDropdown + menu.nocurrent = true + menu.db = parent.db + button.menu = menu + + return button +end + +local createProfileScripts = { + OnEnterPressed = function(self) + self.db:SetProfile(self:GetText()) + self:ClearFocus() + end, + OnEditFocusGained = function(self) + self:SetTextColor(1, 1, 1) + end, + OnEditFocusLost = function(self) + self:SetTextColor(0.5, 0.5, 0.5) + self:SetText("") + end, +} + +local function enableDualProfileOnClick(self) + local checked = self:GetChecked() + self.db:SetDualSpecEnabled(checked) + self.dualProfile:SetEnabled(checked) +end + +local function dualProfileOnClick(db, profile, frame) + db:SetDualSpecProfile(profile) + frame:SetText(profile) +end + +local function deleteProfile(db, profile) + StaticPopup_Show("DELETE_PROFILE", nil, nil, {db = db, profile = profile}) +end + +StaticPopupDialogs["DELETE_PROFILE"] = { + text = L.delete_confirm, + button1 = YES, + button2 = NO, + OnAccept = function(self, data) + data.db:DeleteProfile(data.profile) + end, +} + +local function constructor(self, db, parent) + local frame = setmetatable(CreateFrame("Frame", nil, parent), mt) + frame:SetSize(192, 192) + frame.db = db + + db.RegisterCallback(frame, "OnNewProfile") + db.RegisterCallback(frame, "OnProfileChanged") + db.RegisterCallback(frame, "OnProfileDeleted") + + local keys = db.keys + defaultProfiles["Default"] = L.default + defaultProfiles[keys.char] = keys.char + defaultProfiles[keys.realm] = keys.realm + defaultProfiles[keys.class] = UnitClass("player") + + local objects = {} + + do -- create the controls + local choose = createDropdown(frame) + choose:SetPoint("TOP") + choose.label:SetText(L.choose) + choose.func = db.SetProfile + choose.getCurrent = db.GetCurrentProfile + choose.common = true + objects.choose = choose + + local newProfile = Libra:CreateEditbox(frame) + newProfile:SetPoint("TOPLEFT", choose, "BOTTOMLEFT", 24, -8) + newProfile:SetPoint("TOPRIGHT", choose, "BOTTOMRIGHT", -17, -8) + newProfile:SetTextColor(0.5, 0.5, 0.5) + newProfile:SetScript("OnEscapePressed", newProfile.ClearFocus) + for script, handler in pairs(createProfileScripts) do + newProfile:SetScript(script, handler) + end + objects.newProfile = newProfile + + local label = newProfile:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") + label:SetHeight(18) + label:SetPoint("BOTTOMLEFT", newProfile, "TOPLEFT", -5, -2) + label:SetPoint("BOTTOMRIGHT", newProfile, "TOPRIGHT", 0, -2) + label:SetJustifyH("LEFT") + label:SetText(L.new) + + local copy = createMenuButton(frame) + copy:SetPoint("TOPLEFT", newProfile, "BOTTOMLEFT", -9, -4) + copy:SetText("Copy from") + copy.menu.func = db.CopyProfile + objects.copy = copy + + local delete = createMenuButton(frame) + delete:SetPoint("TOPRIGHT", newProfile, "BOTTOMRIGHT", 4, -4) + delete:SetText("Delete") + delete.menu.func = deleteProfile + objects.delete = delete + + local reset = Libra:CreateButton(frame) + reset:SetPoint("TOPLEFT", copy, "BOTTOM", 0, -4) + reset:SetPoint("TOPRIGHT", delete, "BOTTOM", 0, -4) + reset:SetScript("OnClick", function(self) self.db:ResetProfile() end) + reset:SetText(L.reset) + objects.reset = reset + + local hasDualProfile = db:GetNamespace("LibDualSpec-1.0", true) + if hasDualProfile then + local isDualSpecEnabled = db:IsDualSpecEnabled() + + local dualProfile = createDropdown(frame) + dualProfile:SetPoint("TOP", reset, "BOTTOM", 0, -28) + dualProfile:SetEnabled(isDualSpecEnabled) + dualProfile:SetText(db:GetDualSpecProfile()) + dualProfile.func = dualProfileOnClick + dualProfile.getCurrent = db.GetDualSpecProfile + dualProfile.common = true + objects.dualProfile = dualProfile + + local enabled = CreateFrame("CheckButton", nil, frame, "OptionsBaseCheckButtonTemplate") + enabled:SetPoint("BOTTOMLEFT", dualProfile, "TOPLEFT", 16, 0) + enabled:SetPushedTextOffset(0, 0) + enabled:SetScript("OnClick", enableDualProfileOnClick) + enabled:SetChecked(isDualSpecEnabled) + enabled.tooltipText = L.enable_desc + enabled.dualProfile = dualProfile + objects.dualEnabled = enabled + + local text = enabled:CreateFontString(nil, nil, "GameFontHighlight") + text:SetPoint("LEFT", enabled, "RIGHT", 0, 1) + text:SetText(L.enabled) + + frame.hasDualProfile = true + end + end + + for k, object in pairs(objects) do + object.db = db + frame[k] = object + end + + frame.choose:SetText(db:GetCurrentProfile()) + + frame:CheckProfiles() + + return frame +end + +function Prototype:CheckProfiles() + local hasProfiles = not self:HasNoProfiles() + self.copy:SetEnabled(hasProfiles) + self.delete:SetEnabled(hasProfiles) +end + +function Prototype:HasNoProfiles() + return next(getProfiles(self.db, nil, true)) == nil +end + +function Prototype:OnProfileChanged(event, db, profile) + self.choose:SetText(profile) + self:CheckProfiles() + if self.hasDualProfile then + self.dualProfile:SetText(db:GetDualSpecProfile()) + end +end + +Prototype.OnNewProfile = Prototype.CheckProfiles +Prototype.OnProfileDeleted = Prototype.CheckProfiles + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Addon.lua b/libs/Libra-36/Addon.lua new file mode 100644 index 0000000..415b774 --- /dev/null +++ b/libs/Libra-36/Addon.lua @@ -0,0 +1,193 @@ +local Libra = LibStub("Libra") +local Type, Version = "Addon", 3 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local object = Libra.modules[Type] +object.frame = object.frame or CreateFrame("Frame") +object.addons = object.addons or {} +object.events = object.events or {} +object.onUpdates = object.onUpdates or {} +object.defaults = object.defaults or {} + +local function safecall(object, method, ...) + if object[method] then + object[method](object, ...) + end +end + +local function removeDefaults(tbl, defaults) + for k, v in pairs(defaults) do + if type(v) == "table" then + removeDefaults(tbl[k], v) + if not next(tbl[k]) then + tbl[k] = nil + end + elseif v == tbl[k] then + tbl[k] = nil + end + end +end + +object.frame:RegisterEvent("ADDON_LOADED") +object.frame:RegisterEvent("PLAYER_LOGOUT") +object.frame:SetScript("OnEvent", function(self, event, ...) + if event == "ADDON_LOADED" then + local addon = object.addons[...] + if addon then + safecall(addon, "OnInitialize") + addon.OnInitialize = nil + for i, module in addon:IterateModules() do + safecall(module, "OnInitialize") + module.OnInitialize = nil + end + end + end + if event == "PLAYER_LOGOUT" then + for tbl, defaults in pairs(object.defaults) do + removeDefaults(tbl, defaults) + end + end + for module, eventHandler in pairs(object.events[event]) do + eventHandler(module, ...) + end +end) + +local function onUpdate(self, elapsed) + for module, update in pairs(object.onUpdates) do + update(module, elapsed) + end +end + +setmetatable(object.events, { + __index = function(table, key) + local newTable = {} + table[key] = newTable + return newTable + end +}) + +local AddonPrototype = {} +local ObjectPrototype = {} + +local function AddonEmbed(target) + for k, v in pairs(AddonPrototype) do + target[k] = v + end +end + +local function ObjectEmbed(target) + for k, v in pairs(ObjectPrototype) do + target[k] = v + end +end + +function Libra:NewAddon(name, addonObject) + if object.addons[name] then + error(format("Addon '%s' already exists.", name), 2) + end + + local addon = addonObject or {} + addon.name = name + addon.modules = {} + AddonEmbed(addon) + ObjectEmbed(addon) + object.addons[name] = addon + return addon, name +end + +function Libra:GetAddon(name) + return object.addons[name] +end + +function AddonPrototype:NewModule(name, table) + if self:GetModule(name) then + error(format("Module '%s' already exists in %s.", name, self.name), 2) + end + + local module = table or {} + ObjectEmbed(module) + module.name = name + tinsert(self.modules, module) + safecall(self, "OnModuleCreated", name, module) + return module, name +end + +function AddonPrototype:GetModule(name) + for i, module in self:IterateModules() do + if module.name == name then + return module + end + end +end + +function AddonPrototype:IterateModules() + return next, self.modules +end + +local function copyDefaults(src, dst) + if not src then return {} end + if not dst then dst = {} end + for k, v in pairs(src) do + if type(v) == "table" then + dst[k] = copyDefaults(v, dst[k]) + elseif type(v) ~= type(dst[k]) then + dst[k] = v + end + end + return dst +end + +function AddonPrototype:CreateDB(global, defaults) + local db = _G[global] + db = copyDefaults(defaults, db) + _G[global] = db + object.defaults[db] = defaults + return db +end + +function ObjectPrototype:RegisterEvent(event, handler) + if not next(object.events[event]) then + object.frame:RegisterEvent(event) + end + if type(handler) ~= "function" then + handler = self[handler] or self[event] + end + object.events[event][self] = handler +end + +function ObjectPrototype:UnregisterEvent(event) + object.events[event][self] = nil + if not next(object.events[event]) then + object.frame:UnregisterEvent(event) + end +end + +function ObjectPrototype:SetOnUpdate(handler) + if not next(object.onUpdates) then + object.frame:SetScript("OnUpdate", onUpdate) + end + if type(handler) ~= "function" then + handler = self[handler] + end + object.onUpdates[self] = handler +end + +function ObjectPrototype:RemoveOnUpdate() + object.onUpdates[self] = nil + if not next(object.onUpdates) then + object.frame:SetScript("OnUpdate", nil) + end +end + +-- upgrade embeds +for k, v in pairs(object.addons) do + AddonEmbed(v) + ObjectEmbed(v) + for i, v in v:IterateModules() do + ObjectEmbed(v) + end +end + +Libra:RegisterModule(Type, Version) \ No newline at end of file diff --git a/libs/Libra-36/Button.lua b/libs/Libra-36/Button.lua new file mode 100644 index 0000000..9ee43a7 --- /dev/null +++ b/libs/Libra-36/Button.lua @@ -0,0 +1,27 @@ +local Libra = LibStub("Libra") +local Type, Version = "Button", 2 +if Libra:GetModuleVersion(Type) >= Version then return end + +local function onEnable(self) + self.arrow:SetDesaturated(false) +end + +local function onDisable(self) + self.arrow:SetDesaturated(true) +end + +local function constructor(self, parent) + local button = CreateFrame("Button", nil, parent, "UIMenuButtonStretchTemplate") + button:SetHeight(23) + button:SetScript("OnEnable", onEnable) + button:SetScript("OnDisable", onDisable) + button.arrow = button:CreateTexture() + button.arrow:SetSize(10, 12) + button.arrow:SetPoint("RIGHT", -5, 0) + button.arrow:SetTexture([[Interface\ChatFrame\ChatFrameExpandArrow]]) + button.arrow:Hide() + button.Icon = button.arrow + return button +end + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Core.lua b/libs/Libra-36/Core.lua new file mode 100644 index 0000000..70f2943 --- /dev/null +++ b/libs/Libra-36/Core.lua @@ -0,0 +1,65 @@ +local MAJOR, MINOR = "Libra", 2 +local lib = LibStub:NewLibrary(MAJOR, MINOR) + +if not lib then return end + +lib.modules = lib.modules or {} +lib.moduleVersions = lib.moduleVersions or {} +lib.embeds = lib.widgetEmbeds or lib.embeds or {} +lib.methods = lib.methods or {} +lib.controls = lib.widgets or lib.controls or {} +lib.namespaces = lib.namespaces or {} + +function lib:RegisterModule(object, version, constructor) + self.moduleVersions[object] = version + if constructor then + self.controls[object] = constructor + self["Create"..object] = constructor + for k in pairs(self.embeds) do + k["Create"..object] = constructor + end + end +end + +function lib:GetModuleVersion(module) + return self.moduleVersions[module] or 0 +end + +function lib:RegisterMethods(tbl) + for k, v in pairs(tbl) do + for target in pairs(self.embeds) do + target[k] = v + end + self.methods[k] = v + end +end + +function lib:GetWidgetName(name) + name = name or "Generic" + local namespace = self.namespaces[name] + if not namespace then + local n = 0 + namespace = function() + n = n + 1 + return format("%sLibraWidget%d", name, n) + end + self.namespaces[name] = namespace + end + return namespace() +end + +function lib:Embed(target) + for k, v in pairs(self.methods) do + target[k] = v + end + for k, v in pairs(self.controls) do + target["Create"..k] = v + end + self.embeds[target] = true +end + +lib.EmbedWidgets = lib.Embed + +for k in pairs(lib.embeds) do + lib:Embed(k) +end \ No newline at end of file diff --git a/libs/Libra-36/Dropdown.lua b/libs/Libra-36/Dropdown.lua new file mode 100644 index 0000000..33d12b4 --- /dev/null +++ b/libs/Libra-36/Dropdown.lua @@ -0,0 +1,553 @@ +local Libra = LibStub("Libra") +local Type, Version = "Dropdown", 13 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local Dropdown = Libra.modules[Type] +Dropdown.Prototype = Dropdown.Prototype or CreateFrame("Frame") +Dropdown.MenuPrototype = Dropdown.MenuPrototype or setmetatable({}, {__index = Dropdown.Prototype}) +Dropdown.FramePrototype = Dropdown.FramePrototype or setmetatable({}, {__index = Dropdown.Prototype}) +Dropdown.objects = Dropdown.objects or {} +Dropdown.listData = Dropdown.listData or {} +Dropdown.hookedLists = Dropdown.hookedLists or {} +Dropdown.hookedButtons = Dropdown.hookedButtons or {} +Dropdown.secureButtons = Dropdown.secureButtons or {} +Dropdown.secureBin = Dropdown.secureBin or {} + +local menuMT = {__index = Dropdown.MenuPrototype} +local frameMT = {__index = Dropdown.FramePrototype} + +local Prototype = Dropdown.Prototype +local MenuPrototype = Dropdown.MenuPrototype +local FramePrototype = Dropdown.FramePrototype +local objects = Dropdown.objects +local listData = Dropdown.listData + +local function setHeight() end + +local function constructor(self, type, parent, name) + local dropdown + if type == "Menu" then + -- adding a SetHeight dummy lets us use a simple table instead of a frame, no side effects noticed so far + dropdown = setmetatable({}, menuMT) + dropdown:SetDisplayMode("MENU") + dropdown.SetHeight = setHeight + dropdown.xOffset = 0 + dropdown.yOffset = 0 + end + if type == "Frame" then + name = name or Libra:GetWidgetName(self.name) + dropdown = setmetatable(CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate"), frameMT) + dropdown:SetWidth(115) + dropdown.label = dropdown:CreateFontString(name.."Label", "BACKGROUND", "GameFontNormalSmall") + dropdown.label:SetPoint("BOTTOMLEFT", dropdown, "TOPLEFT", 16, 3) + end + + objects[dropdown] = true + + return dropdown +end + + +local methods = { + Refresh = UIDropDownMenu_Refresh, +} + +for k, v in pairs(methods) do + Prototype[k] = v +end + +function Prototype:AddButton(info, level) + info.owner = self + if info.icon and not info.iconOnly then + -- hack to properly increase button width for icon when .iconOnly is not set + info.padding = (info.padding or 0) + 10 + end + self.displayMode = self._displayMode + self.selectedName = self._selectedName + self.selectedValue = self._selectedValue + self.selectedID = self._selectedID + UIDropDownMenu_AddButton(info, level) + self.displayMode = nil + self.selectedName = nil + self.selectedValue = nil + self.selectedID = nil +end + +function Prototype:ToggleMenu(value, anchorName, xOffset, yOffset, menuList, level, ...) + ToggleDropDownMenu(level, value, self, anchorName, xOffset, yOffset, menuList, ...) +end + +function Prototype:RebuildMenu(level) + level = level or 1 + if self:IsMenuShown(level) then + -- hiding a menu will also hide all deeper level menus, so we'll check which ones are open and restore them afterwards + local maxLevel + for i = level, UIDROPDOWNMENU_MENU_LEVEL do + if _G["DropDownList"..i]:IsShown() then + maxLevel = i + else + break + end + end + self:HideMenu(level) + for i = level, maxLevel do + local listData = listData[i] + -- set .rebuild to indicate that we don't want to reset the scroll offset on the next ToggleDropDownMenu + self.rebuild = true + self:ToggleMenu(listData.value, listData.anchorName, listData.xOffset, listData.yOffset, listData.menuList, i, listData.button, listData.autoHideDelay) + end + end +end + +function Prototype:HideMenu(level) + if UIDropDownMenu_GetCurrentDropDown() == self then + HideDropDownMenu(level) + end +end + +function Prototype:CloseMenus(level) + if UIDropDownMenu_GetCurrentDropDown() == self then + CloseDropDownMenus(level) + end +end + +function Prototype:IsMenuShown(level) + level = level or 1 + local listFrame = _G["DropDownList"..level] + return UIDropDownMenu_GetCurrentDropDown() == self and listFrame and listFrame:IsShown() +end + +function Prototype:SetSelectedName(name, useValue) + self._selectedName = name + self._selectedValue = nil + self._selectedID = nil + self.selectedName = name + self:Refresh(useValue) + self.selectedName = nil +end + +function Prototype:SetSelectedValue(value, useValue) + self._selectedValue = value + self._selectedName = nil + self._selectedID = nil + self.selectedValue = value + self:Refresh(useValue) + self.selectedValue = nil +end + +function Prototype:SetSelectedID(id, useValue) + self._selectedID = id + self._selectedName = nil + self._selectedValue = nil + self.selectedID = id + self:Refresh(useValue) + self.selectedID = nil +end + +function Prototype:GetSelectedName() + return self._selectedName +end + +function Prototype:GetSelectedValue() + return self._selectedValue +end + +function Prototype:GetSelectedID() + if self._selectedID then + return self._selectedID + else + -- If no explicit selectedID then try to send the id of a selected value or name + for i=1, UIDROPDOWNMENU_MAXBUTTONS do + local button = _G["DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..i] + -- See if checked or not + if self:GetSelectedName() then + if button:GetText() == self:GetSelectedName() then + return i + end + elseif self:GetSelectedValue() then + if button.value == self:GetSelectedValue() then + return i + end + end + end + end +end + +function Prototype:SetDisplayMode(mode) + self._displayMode = mode +end + + +local menuMethods = { + Toggle = Prototype.ToggleMenu, + Rebuild = Prototype.RebuildMenu, + Hide = Prototype.HideMenu, + Close = Prototype.CloseMenus, + IsShown = Prototype.IsMenuShown, +} + +for k, v in pairs(menuMethods) do + MenuPrototype[k] = v +end + + +local frameMethods = { + Enable = UIDropDownMenu_EnableDropDown, + Disable = UIDropDownMenu_DisableDropDown, + IsEnabled = UIDropDownMenu_IsEnabled, + JustifyText = UIDropDownMenu_JustifyText, + SetButtonWidth = UIDropDownMenu_SetButtonWidth, + SetText = UIDropDownMenu_SetText, + GetText = UIDropDownMenu_GetText, +} + +for k, v in pairs(frameMethods) do + FramePrototype[k] = v +end + +local setWidth = Prototype.SetWidth + +function FramePrototype:SetWidth(width, padding) + _G[self:GetName().."Middle"]:SetWidth(width) + local defaultPadding = 25 + if padding then + setWidth(self, width + padding) + _G[self:GetName().."Text"]:SetWidth(width) + else + setWidth(self, width + defaultPadding + defaultPadding) + _G[self:GetName().."Text"]:SetWidth(width - defaultPadding) + end + self.noResize = 1 +end + +function FramePrototype:SetLabel(text) + self.label:SetText(text) +end + +function FramePrototype:SetEnabled(enable) + if enable then + self:Enable() + else + self:Disable() + end +end + + +local numShownButtons + +local function update(level) + local scroll = listData[level].scroll + for i = 1, UIDROPDOWNMENU_MAXBUTTONS do + local button = _G["DropDownList"..level.."Button"..i] + local _, _, _, x, y = button:GetPoint() + local y = -((button:GetID() - 1 - scroll) * UIDROPDOWNMENU_BUTTON_HEIGHT) - UIDROPDOWNMENU_BORDER_HEIGHT + button:SetPoint("TOPLEFT", x, y) + button:SetShown(i > scroll and i <= (numShownButtons + scroll)) + end + Dropdown.scrollButtons[level].up:SetShown(scroll > 0) + Dropdown.scrollButtons[level].down:SetShown(scroll < _G["DropDownList"..level].numButtons - numShownButtons) +end + +local function scroll(self, delta) + local level = self:GetID() + local listData = listData[level] + delta = (type(delta) == "number" and delta or self.delta) + if IsShiftKeyDown() then delta = delta * (numShownButtons - 1) end + listData.scroll = listData.scroll - (type(delta) == "number" and delta or self.delta) + listData.scroll = min(listData.scroll, (self.numButtons or self:GetParent().numButtons) - numShownButtons) + listData.scroll = max(listData.scroll, 0) + update(level) +end + +local scrollScripts = { + OnEnter = function(self) + UIDropDownMenu_StopCounting(self:GetParent()) + end, + OnLeave = function(self) + UIDropDownMenu_StartCounting(self:GetParent()) + end, + OnMouseDown = function(self) + self.texture:SetPoint("CENTER", 1, -1) + end, + OnMouseUp = function(self) + self.texture:SetPoint("CENTER") + end, + OnHide = function(self) + self.texture:SetPoint("CENTER") + -- explicitly hide so that they are hidden for unmanaged dropdowns + self:Hide() + end, +} + +local function createScrollButton(listFrame) + local level = listFrame:GetID() + local button = CreateFrame("Button", nil, listFrame) + button:SetSize(16, 16) + button:SetScript("OnClick", scroll) + for script, handler in pairs(scrollScripts) do + button:SetScript(script, handler) + end + button:SetID(level) + button.texture = button:CreateTexture() + button.texture:SetSize(16, 16) + button.texture:SetPoint("CENTER") + button.texture:SetTexture([[Interface\Calendar\MoreArrow]]) + return button +end + +local function createScrollButtons(listFrame) + local scrollUp = listFrame.scrollUp or createScrollButton(listFrame) + scrollUp:SetPoint("TOP") + scrollUp.delta = 1 + scrollUp.texture:SetTexCoord(0, 1, 1, 0) + listFrame.scrollUp = scrollUp + + local scrollDown = listFrame.scrollDown or createScrollButton(listFrame) + scrollDown:SetPoint("BOTTOM") + scrollDown.delta = -1 + listFrame.scrollDown = scrollDown +end + +Dropdown.scrollButtons = Dropdown.scrollButtons or setmetatable({}, { + __index = function(self, level) + local listFrame = _G["DropDownList"..level] + createScrollButtons(listFrame) + self[level] = { + up = listFrame.scrollUp, + down = listFrame.scrollDown, + } + return self[level] + end, +}) + +function Dropdown:ToggleDropDownMenuHook(level, value, dropdownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay) + level = level or 1 + if level ~= 1 then + dropdownFrame = dropdownFrame or UIDROPDOWNMENU_OPEN_MENU + end + local listFrameName = "DropDownList"..level + local listFrame = _G[listFrameName] + if not objects[dropdownFrame] then return end + if dropdownFrame and dropdownFrame._displayMode == "MENU" then + _G[listFrameName.."Backdrop"]:Hide() + _G[listFrameName.."MenuBackdrop"]:Show() + end + + -- store all parameters per level so we can use them to rebuild the menu + listData[level] = listData[level] or {} + local listData = listData[level] + listData.value = value + listData.anchorName = anchorName + listData.xOffset = xOffset + listData.yOffset = yOffset + listData.menuList = menuList + listData.button = button + listData.autoHideDelay = autoHideDelay + + numShownButtons = dropdownFrame.numShownButtons or floor((UIParent:GetHeight() - UIDROPDOWNMENU_BORDER_HEIGHT * 2) / UIDROPDOWNMENU_BUTTON_HEIGHT) + local scrollable = numShownButtons < listFrame.numButtons + if scrollable then + -- make scrollable + listData.scroll = listData.scroll or 0 + if not dropdownFrame.rebuild then + listData.scroll = 0 + end + listFrame:SetScript("OnMouseWheel", scroll) + listFrame:SetHeight((numShownButtons * UIDROPDOWNMENU_BUTTON_HEIGHT) + (UIDROPDOWNMENU_BORDER_HEIGHT * 2)) + if listFrame:GetTop() > GetScreenHeight() then + local point, anchorFrame, relativePoint, x, y = listFrame:GetPoint() + local offTop = (GetScreenHeight() - listFrame:GetTop())-- / listFrame:GetScale() + listFrame:SetPoint(point, anchorFrame, relativePoint, x, y + offTop) + end + update(level) + else + if listFrame:GetTop() > GetScreenHeight() then + local point, anchorFrame, relativePoint, x, y = listFrame:GetPoint() + local offTop = (GetScreenHeight() - listFrame:GetTop())-- / listFrame:GetScale() + listFrame:SetPoint(point, anchorFrame, relativePoint, x, y + offTop) + end + listFrame:SetScript("OnMouseWheel", nil) + self.scrollButtons[level].up:Hide() + self.scrollButtons[level].down:Hide() + end + dropdownFrame.rebuild = nil +end + +if not Dropdown.hookToggleDropDownMenu then + hooksecurefunc("ToggleDropDownMenu", function(...) + Dropdown:ToggleDropDownMenuHook(...) + end) + Dropdown.hookToggleDropDownMenu = true +end + +function Dropdown:AddButtonHook(info, level) + if not objects[UIDropDownMenu_GetCurrentDropDown()] then return end + local listFrameName = "DropDownList"..(level or 1) + local listFrame = _G[listFrameName] + local button = _G[listFrameName.."Button"..(listFrame.numButtons)] + button.onEnter = info.onEnter + button.onLeave = info.onLeave + button.tooltipLines = info.tooltipLines + if info.attributes and not InCombatLockdown() then + local secureButton = self.secureBin[1] + tremove(Dropdown.secureBin, 1) + -- since this is a separate button, we need to set the disabled state on it too + secureButton:SetEnabled(not info.disabled) + secureButton:SetParent(button) + secureButton:SetAllPoints() + secureButton:Show() + -- clear existing attributes + for attribute in pairs(secureButton.attributes) do + secureButton:SetAttribute(attribute, nil) + secureButton.attributes[attribute] = nil + end + for attribute, value in pairs(info.attributes) do + secureButton:SetAttribute(attribute, value) + secureButton.attributes[attribute] = true + end + tinsert(Dropdown.secureButtons, secureButton) + end +end + +if not Dropdown.hookAddButton then + hooksecurefunc("UIDropDownMenu_AddButton", function(...) + Dropdown:AddButtonHook(...) + end) + Dropdown.hookAddButton = true +end + +local function onEnter(self) + if self.onEnter then + self:onEnter() + elseif self.tooltipLines and self.tooltipTitle then + GameTooltip:SetOwner(self, "ANCHOR_RIGHT") + GameTooltip:AddLine(self.tooltipTitle, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + if self.tooltipText then + for line in self.tooltipText:gmatch("[^\n]+") do + GameTooltip:AddLine(line) + end + end + GameTooltip:Show() + end +end + +local function onLeave(self) + if self.onLeave then + self:onLeave() + end +end + +local function invisibleButtonOnEnter(self) + local parent = self:GetParent() + if parent.onEnter or parent.tooltipWhileDisabled then + onEnter(parent) + end +end + +local function invisibleButtonOnLeave(self) + local parent = self:GetParent() + if parent.onLeave or parent.tooltipWhileDisabled then + onLeave(parent) + end +end + +function Dropdown:HideListHook(self) + if not InCombatLockdown() then + for i = #Dropdown.secureButtons, 1, -1 do + -- hide secure buttons attached to this list frame + local button = Dropdown.secureButtons[i] + if button:GetParent():GetParent() == self then + Dropdown:DismissSecureButton(button) + tremove(Dropdown.secureButtons, i) + end + end + end + if objects[UIDropDownMenu_GetCurrentDropDown()] then + self:SetScript("OnMouseWheel", nil) + end +end + +local function listOnHide(self) + Dropdown:HideListHook(self) +end + +function Dropdown:CreateFramesHook(numLevels, numButtons) + for level = 1, numLevels do + if not self.hookedLists[level] then + _G["DropDownList"..level]:HookScript("OnHide", listOnHide) + self.hookedLists[level] = true + end + self.hookedButtons[level] = self.hookedButtons[level] or {} + for i = 1, numButtons do + if not self.hookedButtons[level][i] then + local button = _G["DropDownList"..level.."Button"..i] + button:HookScript("OnEnter", onEnter) + button:HookScript("OnLeave", onLeave) + button.invisibleButton:HookScript("OnEnter", invisibleButtonOnEnter) + button.invisibleButton:HookScript("OnLeave", invisibleButtonOnLeave) + self.hookedButtons[level][i] = true + end + end + end +end + +if not Dropdown.hookCreateFrames then + Dropdown:CreateFramesHook(UIDROPDOWNMENU_MAXLEVELS, UIDROPDOWNMENU_MAXBUTTONS) + hooksecurefunc("UIDropDownMenu_CreateFrames", function(...) + Dropdown:CreateFramesHook(...) + end) + Dropdown.hookCreateFrames = true +end + +-- script handlers to mimic regular dropdown button behaviour +local scripts = { + PreClick = function(self) + local parent = self:GetParent() + parent:GetScript("OnClick")(parent) + end, + OnMouseDown = function(self) + self:GetParent():SetButtonState("PUSHED") + end, + OnMouseUp = function(self) + self:GetParent():SetButtonState("NORMAL") + end, + OnEnter = function(self) + local parent = self:GetParent() + parent:GetScript("OnEnter")(parent) + end, + OnLeave = function(self) + local parent = self:GetParent() + parent:GetScript("OnLeave")(parent) + end, +} + +setmetatable(Dropdown.secureBin, { + __index = function(self, index) + local button = CreateFrame("Button", nil, nil, "SecureActionButtonTemplate") + for script, handler in pairs(scripts) do + button:SetScript(script, handler) + end + button.attributes = {} + return button + end, +}) + +function Dropdown:DismissSecureButton(button) + button:Hide() + button:ClearAllPoints() + button:SetParent(nil) + tinsert(Dropdown.secureBin, button) +end + +Dropdown.frame = Dropdown.frame or CreateFrame("Frame") +Dropdown.frame:RegisterEvent("PLAYER_REGEN_DISABLED") +Dropdown.frame:SetScript("OnEvent", function(self) + for i, button in ipairs(Dropdown.secureButtons) do + Dropdown:DismissSecureButton(button) + end + wipe(Dropdown.secureButtons) +end) + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Editbox.lua b/libs/Libra-36/Editbox.lua new file mode 100644 index 0000000..28358a2 --- /dev/null +++ b/libs/Libra-36/Editbox.lua @@ -0,0 +1,12 @@ +local Libra = LibStub("Libra") +local Type, Version = "Editbox", 3 +if Libra:GetModuleVersion(Type) >= Version then return end + +local function constructor(self, parent, isSearchBox) + local editbox = CreateFrame("EditBox", nil, parent, isSearchBox and "SearchBoxTemplate" or "InputBoxTemplate") + editbox:SetHeight(20) + editbox:SetAutoFocus(false) + return editbox +end + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Libra.xml b/libs/Libra-36/Libra.xml new file mode 100644 index 0000000..02a5fb6 --- /dev/null +++ b/libs/Libra-36/Libra.xml @@ -0,0 +1,16 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ +..\FrameXML\UI.xsd"> + <Script file="Core.lua"/> + + <Script file="Addon.lua"/> + <Script file="AceDBControls.lua"/> + <Script file="Button.lua"/> + <Script file="Dropdown.lua"/> + <Script file="Editbox.lua"/> + <Script file="OptionsFrame.lua"/> + <Script file="ScrollFrame.lua"/> + <Script file="Slider.lua"/> + <Script file="Templates.lua"/> + <Script file="UIPanel.lua"/> + <Script file="Utils.lua"/> +</Ui> \ No newline at end of file diff --git a/libs/Libra-36/OptionsFrame.lua b/libs/Libra-36/OptionsFrame.lua new file mode 100644 index 0000000..e9dfeab --- /dev/null +++ b/libs/Libra-36/OptionsFrame.lua @@ -0,0 +1,475 @@ +local Libra = LibStub("Libra") +local Type, Version = "OptionsFrame", 4 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local Options = Libra.modules[Type] + +Options.Prototype = Options.Prototype or CreateFrame("Frame") +Options.ParentPrototype = Options.ParentPrototype or {} +Options.controls = Options.controls or {} +Options.controlData = Options.controlData or {} + +local mt = {__index = Options.Prototype} +local parentMT = {__index = setmetatable(Options.ParentPrototype, {__index = Options.Prototype})} + +local Prototype = Options.Prototype +local ParentPrototype = Options.ParentPrototype + +local function createFrame(name, parent) + local frame = CreateFrame("Frame") + frame.name = name + frame.parent = parent + InterfaceOptions_AddCategory(frame) + + local title = frame:CreateFontString(nil, nil, "GameFontNormalLarge") + title:SetPoint("TOPLEFT", 16, -16) + title:SetPoint("RIGHT", -16, 0) + title:SetJustifyH("LEFT") + title:SetJustifyV("TOP") + title:SetText(name) + frame.title = title + + local desc = frame:CreateFontString(nil, nil, "GameFontHighlightSmall") + desc:SetHeight(32) + desc:SetPoint("TOPLEFT", frame.title, "BOTTOMLEFT", 0, -8) + desc:SetPoint("RIGHT", -31, 0) + desc:SetJustifyH("LEFT") + desc:SetJustifyV("TOP") + desc:SetNonSpaceWrap(true) + frame.desc = desc + + return frame +end + +local function constructor(self, name) + local frame = setmetatable(createFrame(name), parentMT) + frame.controls = {} + frame.allcontrols = {} + return frame +end + + +function ParentPrototype:AddSubCategory(name, inherit) + local frame = setmetatable(createFrame(name, self.name), mt) + if inherit then + frame.db = self.db + frame.useProfile = self.useProfile + frame.handler = self.handler + frame.allcontrols = self.allcontrols + else + frame.allcontrols = {} + end + frame.inherit = inherit + frame.controls = {} + self.subCategories = self.subCategories or {} + tinsert(self.subCategories, frame) + return frame +end + +function Prototype:SetDescription(text) + self.desc:SetText(text) +end + +function Prototype:SetDatabase(database, useProfile) + self.db = database + self.useProfile = useProfile + if self.subCategories then + for i, v in ipairs(self.subCategories) do + if v.inherit then + v.db = database + end + end + end +end + +function Prototype:SetHandler(tbl) + self.handler = tbl + if self.subCategories then + for i, v in ipairs(self.subCategories) do + if v.inherit then + v.handler = tbl + end + end + end +end + + +local function getTable(control) + local tbl = control.parent.db + if control.parent.useProfile then + tbl = tbl.profile + end + if control.keyTable then + tbl = tbl[control.keyTable] + end + return tbl +end + +local function getFunc(control, method, key, value) + local func = control[method] + if func then + local object = control + if type(func) == "string" then + object = control.parent.handler + func = object[func] + end + if key then + return true, func(object, key, value) + else + return true, func(object, value) + end + return true + end +end + +local function set(self, value, key) + if not getFunc(self, "set", key, value) then + local tbl = getTable(self) + if tbl then + tbl[key or self.key] = value + end + end + getFunc(self, "func", key, value) + for key, control in pairs(self.parent.allcontrols) do + if control.disabled then + control:SetEnabled(not control.disabled()) + end + end +end + +local function get(self, key) + local hasFunc, value = getFunc(self, "get", key) + if hasFunc then + return value + else + local tbl = getTable(self) + if tbl then + return tbl[key or self.key] + end + end +end + +local controls = Options.controls +local controlData = Options.controlData + +do -- CheckButton + controlData.CheckButton = { + x = -2, + y = -16, + bottomOffset = 8, + } + + local function onClick(self) + local checked = self:GetChecked() + PlaySound(checked and "igMainMenuOptionCheckBoxOn" or "igMainMenuOptionCheckBoxOff") + set(self, checked) + end + + controls.CheckButton = function(parent) + local checkButton = CreateFrame("CheckButton", nil, parent, "OptionsBaseCheckButtonTemplate") + checkButton:SetNormalFontObject("GameFontHighlight") + checkButton:SetDisabledFontObject("GameFontDisable") + checkButton:SetPushedTextOffset(0, 0) + checkButton:SetScript("OnClick", onClick) + checkButton.SetValue = checkButton.SetChecked + + checkButton.label = checkButton:CreateFontString() + checkButton.label:SetPoint("LEFT", checkButton, "RIGHT", 0, 1) + checkButton:SetFontString(checkButton.label) + + return checkButton + end +end + +do -- ColorButton + controlData.ColorButton = { + x = 3, + y = -21, + bottomOffset = 3, + } + + local ColorPickerFrame = ColorPickerFrame + + local function setColor(self, color) + self.swatch:SetVertexColor(color.r, color.g, color.b) + end + + local function saveColor(self, r, g, b) + self.swatch:SetVertexColor(r, g, b) + local color = get(self) + color.r = r + color.g = g + color.b = b + set(self, color) + end + + local function swatchFunc() + saveColor(ColorPickerFrame.extraInfo, ColorPickerFrame:GetColorRGB()) + end + + local function cancelFunc(prev) + saveColor(ColorPickerFrame.extraInfo, ColorPicker_GetPreviousValues()) + end + + local scripts = { + OnClick = function(self) + local info = UIDropDownMenu_CreateInfo() + local color = get(self) + info.r, info.g, info.b = color.r, color.g, color.b + info.swatchFunc = swatchFunc + info.cancelFunc = cancelFunc + info.extraInfo = self + OpenColorPicker(info) + end, + + OnEnter = function(self) + self.bg:SetVertexColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) + if self.tooltipText then + GameTooltip:SetOwner(self, "ANCHOR_RIGHT") + GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true) + end + end, + + OnLeave = function(self) + self.bg:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + GameTooltip:Hide() + end, + + OnEnable = function(self) + if self:IsMouseOver() then + self:OnEnter() + else + self.bg:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + end + end, + + OnDisable = function(self) + self.bg:SetVertexColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b) + end, + } + + controls.ColorButton = function(parent, data) + local colorButton = CreateFrame("Button", nil, parent) + colorButton:SetSize(16, 16) + colorButton:SetNormalFontObject("GameFontHighlight") + colorButton:SetDisabledFontObject("GameFontDisable") + colorButton:SetPushedTextOffset(0, 0) + for script, handler in pairs(scripts) do + colorButton:SetScript(script, handler) + colorButton[script] = handler + end + colorButton.SetValue = setColor + + colorButton:SetNormalTexture([[Interface\ChatFrame\ChatFrameColorSwatch]]) + colorButton.swatch = colorButton:GetNormalTexture() + + colorButton.bg = colorButton:CreateTexture(nil, "BACKGROUND") + colorButton.bg:SetSize(14, 14) + colorButton.bg:SetPoint("CENTER") + colorButton.bg:SetTexture(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + + colorButton.label = colorButton:CreateFontString() + colorButton.label:SetPoint("LEFT", colorButton, "RIGHT", 5, 1) + colorButton:SetFontString(colorButton.label) + + return colorButton + end +end + +do -- Slider + controlData.Slider = { + x = 7, + y = -27, + bottomOffset = -5, + } + + local function onValueChanged(self, value, isUserInput) + if isUserInput then + set(self, value) + end + if self.isPercent then + self.currentValue:SetFormattedText("%.0f%%", value * 100) + else + self.currentValue:SetText(value) + end + end + + local function onMinMaxChanged(self, min, max) + if self.minText or not self.isPercent then + self.min:SetText(self.minText or min) + else + self.min:SetFormattedText("%.0f%%", min * 100) + end + if self.maxText or not self.isPercent then + self.max:SetText(self.maxText or max) + else + self.max:SetFormattedText("%.0f%%", max * 100) + end + end + + controls.Slider = function(parent, data) + local slider = Libra:CreateSlider(parent) + slider:SetScript("OnValueChanged", onValueChanged) + slider:SetScript("OnMinMaxChanged", onMinMaxChanged) + slider.isPercent = data.isPercent + slider.minText = data.minText + slider.maxText = data.maxText + slider:SetMinMaxValues(data.min, data.max) + slider:SetValueStep(data.step) + return slider + end +end + +do -- Dropdown + controlData.Dropdown = { + x = -15, + y = -32, + bottomOffset = 8, + } + + local function getValue(dropdown, property, value) + local properties = dropdown.properties + local property = properties and properties[property] + if not properties or not property then + return value + else + if type(property) == "function" then + return property(value) + elseif type(property) == "table" then + return property[value] + else + return property + end + end + end + + local function setText(self, value) + self:SetText(getValue(self, "text", value)) + end + + local defaultProperties = { + "text", + "value", + "arg1", + } + + local function onClick(self, arg1, arg2, checked) + if self.owner.multiSelect then + set(self.owner, checked, arg1) + else + self.owner:SetText(self:GetText()) + set(self.owner, arg1) + end + end + + local function checked(self) + if self.owner.multiSelect then + return get(self.owner, self.arg1) + else + return self.arg1 == get(self.owner) + end + end + + local function initialize(self, level, menuList) + menuList = menuList or self.menulist + if type(menuList) == "function" then + menuList = menuList() + end + for i, v in ipairs(menuList) do + local info = UIDropDownMenu_CreateInfo() + info.func = onClick + info.checked = checked + info.isNotRadio = self.multiSelect + for i, propertyName in ipairs(defaultProperties) do + info[propertyName] = getValue(self, propertyName, v) + end + if self.properties then + for propertyName in pairs(self.properties) do + info[propertyName] = getValue(self, propertyName, v) + end + end + self:AddButton(info) + end + end + + controls.Dropdown = function(parent, data) + local dropdown = Libra:CreateDropdown("Frame", parent) + dropdown:JustifyText("LEFT") + dropdown.SetValue = setText + dropdown.initialize = data.initialize or initialize + dropdown.menulist = data.menuList + dropdown.multiSelect = data.multiSelect + if data.properties then + dropdown.properties = {} + for k, v in pairs(data.properties) do + dropdown.properties[k] = v + end + end + return dropdown + end +end + +function Libra:AddControlType(type, constructor, controlData) + if Options.controls[type] then + error(format("Control type '%s' already exists.", type), 2) + end + Options.controls[type] = constructor + controlData = controlData or {} + controlData.x = controlData.x or 0 + controlData.y = controlData.y or 0 + controlData.bottomOffset = controlData.bottomOffset or 0 + Options.controlData[type] = controlData +end + +function Prototype:CreateOptions(options) + for i, option in ipairs(options) do + local control = controls[option.type](self, option) + local data = controlData[option.type] + if i == 1 then + control:SetPoint("TOPLEFT", self.desc, "BOTTOMLEFT", data.x, data.y + 8) + elseif option.newColumn then + control:SetPoint("TOPLEFT", self.desc, "BOTTOM", data.x - 2, data.y + 8) + else + local previousOption = options[i - 1] + local previousData = controlData[previousOption.type] + control:SetPoint("TOPLEFT", self.controls[i - 1], "BOTTOMLEFT", data.x - previousData.x, data.y + previousData.bottomOffset - (option.padding or 0)) + end + if option.width then + control:SetWidth(option.width) + end + control.parent = self + control.label:SetText(option.text) + control.tooltipText = option.tooltip + control.key = option.key + control.keyTable = option.keyTable + control.set = option.set + control.get = option.get + control.func = option.func + control.disabled = option.disabled + tinsert(self.controls, control) + tinsert(self.allcontrols, control) + end +end + +function Prototype:SetupControls() + for i, control in ipairs(self.allcontrols) do + local value = get(control) + control:SetValue(value) + getFunc(control, "func", key, value) + if control.disabled then + control:SetEnabled(not control.disabled()) + end + end +end + +function Prototype:GetControlByKey(key, keyTable) + for i, control in ipairs(self.allcontrols) do + if control.key == key and control.keyTable == keyTable then + return control + end + end +end + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/ScrollFrame.lua b/libs/Libra-36/ScrollFrame.lua new file mode 100644 index 0000000..dfd8541 --- /dev/null +++ b/libs/Libra-36/ScrollFrame.lua @@ -0,0 +1,137 @@ +local Libra = LibStub("Libra") +local Type, Version = "ScrollFrame", 6 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local ScrollFrame = Libra.modules[Type] + +ScrollFrame.FauxPrototype = ScrollFrame.FauxPrototype or CreateFrame("ScrollFrame") +ScrollFrame.HybridPrototype = ScrollFrame.HybridPrototype or CreateFrame("ScrollFrame") + +local fauxMT = {__index = ScrollFrame.FauxPrototype} +local hybridMT = {__index = ScrollFrame.HybridPrototype} + +local HybridPrototype = ScrollFrame.HybridPrototype + +local function fauxOnVerticalScroll(self, offset) + self.Scrollbar:SetValue(offset) + self.offset = floor((offset / self.buttonHeight) + 0.5) + self:Update() +end + +local function update(self) + local offset = self:GetOffset() + local numItems = self.getNumItems() + for i, button in ipairs(self.buttons) do + local index = offset + i + if index <= numItems then + self.updateButton(button, index) + end + button:SetShown(index <= numItems) + end + local totalHeight = numItems * self.buttonHeight + local displayedHeight = #self.buttons * self.buttonHeight + if self.dynamic then + totalHeight = self.dynamic() + elseif self.largeButtonTop then + totalHeight = totalHeight - (self.buttonHeight - self.largeButtonHeight) + end + HybridScrollFrame_Update(self, totalHeight, displayedHeight) + if self.onScroll then + self:onScroll() + end +end + +local function constructor(self, type, parent, name) + local scrollFrame + if type == "Faux" then + scrollFrame = setmetatable(CreateFrame("ScrollFrame", name, parent, "FauxScrollFrameTemplate"), fauxMT) + scrollFrame:SetScript("OnVerticalScroll", fauxOnVerticalScroll) + end + if type == "Hybrid" then + name = name or Libra:GetWidgetName(self.name) + scrollFrame = setmetatable(CreateFrame("ScrollFrame", name, parent, "HybridScrollFrameTemplate"), hybridMT) + scrollFrame.update = function() update(scrollFrame) end + scrollFrame.scrollBar = CreateFrame("Slider", nil, scrollFrame, "HybridScrollBarTemplate") + end + + return scrollFrame +end + + +local fauxMethods = { + Update = FauxScrollFrame_Update, + SetOffset = FauxScrollFrame_SetOffset, + GetOffset = FauxScrollFrame_GetOffset, +} + +for k, v in pairs(fauxMethods) do + ScrollFrame.FauxPrototype[k] = v +end + +local hybridMethods = { + -- Update = HybridScrollFrame_Update, + -- SetOffset = HybridScrollFrame_SetOffset, + GetOffset = HybridScrollFrame_GetOffset, + CollapseButton = HybridScrollFrame_CollapseButton, +} + +for k, v in pairs(hybridMethods) do + ScrollFrame.HybridPrototype[k] = v +end + +local function setHeader(self) + self:SetHeight(self.parent.headerHeight) +end + +local function resetHeight(self) + self:SetHeight(self.parent.buttonHeightReal) +end + +function HybridPrototype:CreateButtons() + self.buttons = self.buttons or {} + local scrollChild = self.scrollChild + local numButtons = ceil(self:GetHeight() / self.buttonHeightReal) + 1 + for i = #self.buttons + 1, numButtons do + local button = self.createButton(scrollChild) + if i == 1 then + button:SetPoint(self.initialPoint or "TOPLEFT", scrollChild, self.initialRelative or "TOPLEFT", (self.initialOffsetX or 0), (self.initialOffsetY or 0)) + else + button:SetPoint(self.point or "TOPLEFT", self.buttons[i - 1], self.relativePoint or "BOTTOMLEFT", (self.offsetX or 0), (self.offsetY or 0)) + end + button:SetHeight(self.buttonHeightReal) + button.SetHeader = setHeader + button.ResetHeight = resetHeight + button.parent = self + self.buttons[i] = button + end + + self.buttonHeight = self.buttonHeightReal - (self.offsetY or 0) + + scrollChild:SetWidth(self:GetWidth()) + scrollChild:SetHeight(numButtons * self.buttonHeightReal) + self:SetVerticalScroll(0) + self:UpdateScrollChildRect() + + local scrollBar = self.scrollBar + scrollBar:SetMinMaxValues(0, numButtons * self.buttonHeightReal) + scrollBar.buttonHeight = self.buttonHeightReal + scrollBar:SetValueStep(self.buttonHeightReal) + scrollBar:SetStepsPerPage(numButtons - 2) + scrollBar:SetValue(0) +end + +function HybridPrototype:SetButtonHeight(height) + self.buttonHeightReal = height +end + +function HybridPrototype:SetHeaderHeight(height) + self.headerHeight = height +end + +function HybridPrototype:ExpandButton(numButtons) + HybridScrollFrame_ExpandButton(self, numButtons * self.buttonHeight, self.headerHeight) +end + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Slider.lua b/libs/Libra-36/Slider.lua new file mode 100644 index 0000000..20202de --- /dev/null +++ b/libs/Libra-36/Slider.lua @@ -0,0 +1,54 @@ +local Libra = LibStub("Libra") +local Type, Version = "Slider", 2 +if Libra:GetModuleVersion(Type) >= Version then return end + +local backdrop = { + bgFile = [[Interface\Buttons\UI-SliderBar-Background]], + edgeFile = [[Interface\Buttons\UI-SliderBar-Border]], + edgeSize = 8, + insets = {left = 3, right = 3, top = 6, bottom = 6} +} + +local function onEnter(self) + if self:IsEnabled() then + if self.tooltipText then + GameTooltip:SetOwner(self, self.tooltipOwnerPoint or "ANCHOR_RIGHT") + GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true) + end + if self.tooltipRequirement then + GameTooltip:AddLine(self.tooltipRequirement, 1.0, 1.0, 1.0) + GameTooltip:Show() + end + end +end + +local function onLeave(self) + GameTooltip:Hide() +end + +local function constructor(self, parent) + local slider = CreateFrame("Slider", nil, parent) + slider:SetSize(144, 17) + slider:SetBackdrop(backdrop) + slider:SetThumbTexture([[Interface\Buttons\UI-SliderBar-Button-Horizontal]]) + slider:SetOrientation("HORIZONTAL") + slider:SetObeyStepOnDrag(true) + slider:SetScript("OnEnter", onEnter) + slider:SetScript("OnLeave", onLeave) + + slider.label = slider:CreateFontString(nil, nil, "GameFontNormal") + slider.label:SetPoint("BOTTOM", slider, "TOP") + + slider.min = slider:CreateFontString(nil, nil, "GameFontHighlightSmall") + slider.min:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", -4, 3) + + slider.max = slider:CreateFontString(nil, nil, "GameFontHighlightSmall") + slider.max:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", 4, 3) + + slider.currentValue = slider:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall") + slider.currentValue:SetPoint("CENTER", 0, -15) + + return slider +end + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/UIPanel.lua b/libs/Libra-36/UIPanel.lua new file mode 100644 index 0000000..049a76f --- /dev/null +++ b/libs/Libra-36/UIPanel.lua @@ -0,0 +1,102 @@ +local Libra = LibStub("Libra") +local Type, Version = "UIPanel", 1 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local UIPanel = Libra.modules[Type] +UIPanel.Prototype = UIPanel.Prototype or CreateFrame("Frame") + +local Prototype = UIPanel.Prototype +local mt = {__index = Prototype} + +local function safecall(object, method, ...) + if object[method] then + object[method](object, ...) + end +end + +local function constructor(self, name) + name = name or Libra:GetWidgetName(self.name) + local panel = setmetatable(CreateFrame("Frame", name, UIParent, "ButtonFrameTemplate"), mt) + + tinsert(UISpecialFrames, name) + UIPanelWindows[name] = { + area = "left", + pushable = 1, + whileDead = true, + } + + return panel +end + + +local methods = { + ShowPortrait = ButtonFrameTemplate_ShowPortrait, + HidePortrait = ButtonFrameTemplate_HidePortrait, + ShowAttic = ButtonFrameTemplate_ShowAttic, + HideAttic = ButtonFrameTemplate_HideAttic, + ShowButtonBar = ButtonFrameTemplate_ShowButtonBar, + + GetSelectedTab = PanelTemplates_GetSelectedTab, + UpdateTabs = PanelTemplates_UpdateTabs, + EnableTab = PanelTemplates_EnableTab, + DisableTab = PanelTemplates_DisableTab, + -- GetTabWidth = PanelTemplates_GetTabWidth, + -- TabResize = PanelTemplates_TabResize, +} + +for k, v in pairs(methods) do + Prototype[k] = v +end + +function Prototype:SetTitleText(text) + self.TitleText:SetText(text) +end + +function Prototype:HideButtonBar() + ButtonFrameTemplate_HideButtonBar(self) + self.Inset:SetPoint("BOTTOMRIGHT", PANEL_INSET_RIGHT_OFFSET, PANEL_INSET_BOTTOM_OFFSET + 2) +end + + +local function onClick(self) + self:GetParent():SelectTab(self:GetID()) + PlaySound("igCharacterInfoTab") +end + +function Prototype:CreateTab(name) + self.tabs = self.tabs or {} + if type(name) == "number" then + error("Tab name may not be a number.", 2) + end + -- if type(name) == "number" then + -- error(format("%s already has a tab named '%s'.", self:GetName(), name), 2) + -- end + local tabs = self.tabs + local numTabs = #tabs + 1 + local tab = CreateFrame("Button", self:GetName().."Tab"..numTabs, self, "CharacterFrameTabButtonTemplate") + if numTabs == 1 then + tab:SetPoint("BOTTOMLEFT", 19, -30) + else + tab:SetPoint("LEFT", tabs[numTabs - 1], "RIGHT", -15, 0) + end + tab:SetID(numTabs) + tab:SetScript("OnClick", onClick) + tabs[numTabs] = tab + self.numTabs = numTabs + return tab +end + +function Prototype:SelectTab(id) + local selectedTab = self:GetSelectedTab() + if selectedTab then + safecall(self, "OnTabDeselected", selectedTab) + end + self.selectedTab = id + self:UpdateTabs() + safecall(self, "OnTabSelected", id) +end + + +Libra:RegisterModule(Type, Version, constructor) \ No newline at end of file diff --git a/libs/Libra-36/Utils.lua b/libs/Libra-36/Utils.lua new file mode 100644 index 0000000..955a7d5 --- /dev/null +++ b/libs/Libra-36/Utils.lua @@ -0,0 +1,45 @@ +local Libra = LibStub("Libra") +local Type, Version = "Utils", 2 +if Libra:GetModuleVersion(Type) >= Version then return end + +Libra.modules[Type] = Libra.modules[Type] or {} + +local object = Libra.modules[Type] +object.api = object.api or {} +object.frame = object.frame or CreateFrame("Frame") +object.connectedRealms = object.connectedRealms or {} +object.connectedRealmsSorted = object.connectedRealmsSorted or {} + +object.frame:RegisterEvent("PLAYER_LOGIN") +object.frame:SetScript("OnEvent", function(self, event, ...) + object[event](object, ...) + self:UnregisterEvent(event) +end) + +function object:PLAYER_LOGIN() + local _, realm = UnitFullName("player") + self.myRealm = realm + self.connectedRealmsSorted = {} + for i, v in ipairs(GetAutoCompleteRealms() or {}) do + self.connectedRealms[v] = true + if v ~= self.myRealm then + tinsert(self.connectedRealmsSorted, v) + end + end + sort(self.connectedRealmsSorted) + tinsert(self.connectedRealmsSorted, 1, self.myRealm) +end + +function object.api:IsConnectedRealm(realm, includeOwn) + if not realm then return end + realm = realm:gsub("[ -]", "") + return (realm ~= object.myRealm or includeOwn) and object.connectedRealms[realm] +end + +function object.api:GetConnectedRealms() + return object.connectedRealmsSorted +end + +Libra:RegisterMethods(object.api) + +Libra:RegisterModule(Type, Version) \ No newline at end of file