Version 0.7.2-beta
- minimap button - graphical move arrows - crash on matches with 0-width
This commit is contained in:
		| @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | ||||
| ## [Upcoming] Version 0.8.0-beta - 2020-06-08 | ||||
| ### Added | ||||
| - handle replacement via slash command | ||||
| - emote detection | ||||
|  | ||||
| ## Version 0.7.2-beta - 2020-06-08 | ||||
| ### Added | ||||
| - minimap button | ||||
| ### Changed | ||||
| - graphical move arrows | ||||
| ###Fixed | ||||
| - crash on matches with 0-width | ||||
|  | ||||
| ## Version 0.7.1-beta - 2020-06-07 | ||||
| ### Added | ||||
|   | ||||
| @@ -35,10 +35,10 @@ function Grichelde:OnInitialize() | ||||
|     self:UpgradeDatabase() | ||||
|  | ||||
|     self.options, self.dialog = self:SetupOptions() | ||||
|  | ||||
|     -- populate UI from database | ||||
|     self:RefreshOptions("OnProfileChanged") | ||||
|  | ||||
|     self.ldb, self.icon = self:MinimapButton() | ||||
|  | ||||
|     self:SetupSlashCommands() | ||||
| end | ||||
|  | ||||
| @@ -63,15 +63,16 @@ end | ||||
| function Grichelde:HandleSlashCommand(input) | ||||
|     -- Show the GUI if no input is supplied, otherwise handle the chat input. | ||||
|     if self.functions.nilOrEmpty(input) then | ||||
|         LibStub("AceConfigDialog-3.0"):Open(self.name) | ||||
|         self:OpenOptions() | ||||
|     else | ||||
|         -- handle slash ourselves | ||||
|         self:DebugPrint("Handle slash command: " .. input) | ||||
|         if input == "mappings" then | ||||
|             self:ShowMappings() | ||||
|         end | ||||
|         if input == "options" then | ||||
|             self:ToogleMappings() | ||||
|         elseif input == "options" then | ||||
|             self:PrintOptions() | ||||
|         elseif input == "profile" then | ||||
|             self:PrintProfile() | ||||
|         end | ||||
|     end | ||||
| end | ||||
| @@ -3,7 +3,7 @@ | ||||
| ## Title: Grichelde | ||||
| ## Notes: Replaces characters from the chat box | ||||
| ## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile | ||||
| ## Version: 0.7.1-beta | ||||
| ## Version: 0.7.2-beta | ||||
| ## Author: Teilzeit-Jedi | ||||
| ## eMail: tj@teilzeit-jedi.de | ||||
|  | ||||
| @@ -11,10 +11,10 @@ | ||||
| ## X-Curse-Project-ID: 385480 | ||||
| ## X-License: GPLv3 | ||||
| ## X-Category: Chat/Communication | ||||
| ## X-Credits: Teilzeit-Jedi, Nathan Pieper | ||||
| ## X-Credits: Teilzeit-Jedi | ||||
| ## X-Embeds: Ace3 | ||||
|  | ||||
| ## OptionalDeps: Ace3 | ||||
| ## OptionalDeps: Ace3, LibDataBroker, LibIcon | ||||
| ## SavedVariables: GricheldeDB | ||||
|  | ||||
| libs.xml | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
| local _G = _G | ||||
| local Grichelde = _G.Grichelde | ||||
|  | ||||
| local nilOrEmpty, ipairs, spairs, tContains, tFilter, tInsert, tConcat, find, sub, isUpper, isLower, toUpper, toLower, trim, length | ||||
|     = Grichelde.functions.nilOrEmpty, Grichelde.functions.ipairs, Grichelde.functions.spairs, Grichelde.functions.tContains, Grichelde.functions.tFilter, Grichelde.functions.tInsert, Grichelde.functions.tConcat, | ||||
| local IsAddOnLoaded, nilOrEmpty, ipairs, spairs, tContains, tFilter, tInsert, tConcat, find, sub, isUpper, isLower, toUpper, toLower, trim, length | ||||
|     = Grichelde.functions.IsAddOnLoaded, Grichelde.functions.nilOrEmpty, Grichelde.functions.ipairs, Grichelde.functions.spairs, Grichelde.functions.tContains, Grichelde.functions.tFilter, Grichelde.functions.tInsert, Grichelde.functions.tConcat, | ||||
|       Grichelde.functions.find, Grichelde.functions.sub, Grichelde.functions.isUpper, Grichelde.functions.isLower, Grichelde.functions.toUpper, Grichelde.functions.toLower, Grichelde.functions.trim, Grichelde.functions.length | ||||
|  | ||||
| --- Before a chat message is sent, check if replacement is required and replace the text accordingly. | ||||
| @@ -27,7 +27,7 @@ end | ||||
| function Grichelde:CheckAndReplace(message, type) | ||||
|     local text = message | ||||
|     if (self:CheckReplacement(text, type)) then | ||||
|         if (_G.Misspelled) then | ||||
|         if (IsAddOnLoaded("Misspelled")) then | ||||
|             self:DebugPrint("Misspelled detected: cleansing message") | ||||
|             text = _G.Misspelled:RemoveHighlighting(text) | ||||
|         end | ||||
| @@ -218,7 +218,7 @@ function Grichelde:ReplaceCharacters(text) | ||||
|                 local oldResult = result | ||||
|  | ||||
|                 local pos1, pos2 = find(oldResult, search, pos) | ||||
|                 while (pos1 and pos2) do | ||||
|                 while (pos1 and pos2 and pos1 <= pos2) do | ||||
|                     self:TracePrint("pos1: %d, pos2: %d", pos1, pos2) | ||||
|                     local pre = sub(result, 1, pos1 - 1 + offset) | ||||
|                     local post = sub(result, pos2 + 1 + offset) | ||||
| @@ -247,7 +247,7 @@ function Grichelde:ReplaceCharacters(text) | ||||
|                 local lowerSearch = toLower(search) | ||||
|  | ||||
|                 local pos1, pos2 = find(lowerResult, lowerSearch, pos) | ||||
|                 while (pos1 and pos2) do | ||||
|                 while (pos1 and pos2 and pos1 <= pos2) do | ||||
|                     self:TracePrint("pos1: %d, pos2: %d", pos1, pos2) | ||||
|                     local pre = sub(result, 1, pos1 - 1 + offset) | ||||
|                     local match = sub(result, pos1 + offset, pos2 + offset) | ||||
|   | ||||
| @@ -9,7 +9,17 @@ Grichelde.LOG_LEVEL.TRACE = 2 | ||||
|  | ||||
| Grichelde.MAPPING_OFFSET = 10 | ||||
|  | ||||
| Grichelde.ICONS = {} | ||||
| Grichelde.ICONS.MOVE_UP = "Interface\\MainMenuBar\\UI-MainMenu-ScrollUpButton-Up" | ||||
| Grichelde.ICONS.MOVE_DOWN = "Interface\\MainMenuBar\\UI-MainMenu-ScrollDownButton-Up" | ||||
|  | ||||
| -- colors: | ||||
| Grichelde.COLORS = {} | ||||
| Grichelde.COLORS.NORMAL    = _G.NORMAL_FONT_COLOR | ||||
| Grichelde.COLORS.HIGHLIGHT = _G.HIGHLIGHT_FONT_COLOR | ||||
| Grichelde.COLORS.RED       = _G.RED_FONT_COLOR | ||||
| Grichelde.COLORS.GREEN     = _G.GREEN_FONT_COLOR | ||||
|  | ||||
| Grichelde.COLOR_CODES = {} | ||||
| Grichelde.COLOR_CODES.PREFIX      = "|c00FFAA00" | ||||
| -- https://github.com/stoneharry/Misc-WoW-Stuff/blob/master/EoC%20Interface/FrameXML/Constants.lua | ||||
| @@ -120,42 +130,43 @@ end | ||||
|  | ||||
| -- faster function lookups by mapping to local refs | ||||
| Grichelde.functions = {} | ||||
| Grichelde.functions.type         = _G.type | ||||
| Grichelde.functions.print        = _G.print | ||||
| Grichelde.functions.nilOrEmpty   = nilOrEmpty | ||||
| Grichelde.functions.pairs        = _G.pairs | ||||
| Grichelde.functions.ipairs       = _G.ipairs | ||||
| Grichelde.functions.spairs       = spairs | ||||
| Grichelde.functions.tContains    = _G.tContains | ||||
| Grichelde.functions.tFilter      = tFilter | ||||
| Grichelde.functions.tInsert      = _G.table.insert | ||||
| Grichelde.functions.tConcat      = _G.table.concat | ||||
| Grichelde.functions.tSize        = tSize | ||||
| Grichelde.functions.tSort        = _G.table.sort | ||||
| Grichelde.functions.tClone       = tClone | ||||
| Grichelde.functions.tNext        = _G.next | ||||
| Grichelde.functions.setmetatable = _G.setmetatable | ||||
| Grichelde.functions.getmetatable = _G.getmetatable | ||||
| Grichelde.functions.select       = _G.select | ||||
| Grichelde.functions.unpack       = _G.unpack | ||||
| Grichelde.functions.find         = _G.string.find | ||||
| Grichelde.functions.sub          = _G.string.sub | ||||
| Grichelde.functions.gsub         = _G.string.gsub | ||||
| Grichelde.functions.match        = _G.strmatch | ||||
| Grichelde.functions.join         = _G.strjoin | ||||
| Grichelde.functions.split        = _G.strsplit | ||||
| Grichelde.functions.toUpper      = _G.strupper | ||||
| Grichelde.functions.toLower      = _G.strlower | ||||
| Grichelde.functions.isChar       = isChar | ||||
| Grichelde.functions.isNumber     = isNumber | ||||
| Grichelde.functions.isUpper      = isUpper | ||||
| Grichelde.functions.isLower      = isLower | ||||
| Grichelde.functions.isCapital    = isCapital | ||||
| Grichelde.functions.format       = _G.string.format | ||||
| Grichelde.functions.rep          = _G.string.rep | ||||
| Grichelde.functions.trim         = _G.strtrim | ||||
| Grichelde.functions.length       = _G.string.len | ||||
| Grichelde.functions.toString     = _G.tostring | ||||
| Grichelde.functions.toNumber     = _G.tonumber | ||||
| Grichelde.functions.max          = _G.math.max | ||||
| Grichelde.functions.min          = _G.math.min | ||||
| Grichelde.functions.IsAddOnLoaded = _G.IsAddOnLoaded | ||||
| Grichelde.functions.type          = _G.type | ||||
| Grichelde.functions.print         = _G.print | ||||
| Grichelde.functions.nilOrEmpty    = nilOrEmpty | ||||
| Grichelde.functions.pairs         = _G.pairs | ||||
| Grichelde.functions.ipairs        = _G.ipairs | ||||
| Grichelde.functions.spairs        = spairs | ||||
| Grichelde.functions.tContains     = _G.tContains | ||||
| Grichelde.functions.tFilter       = tFilter | ||||
| Grichelde.functions.tInsert       = _G.table.insert | ||||
| Grichelde.functions.tConcat       = _G.table.concat | ||||
| Grichelde.functions.tSize         = tSize | ||||
| Grichelde.functions.tSort         = _G.table.sort | ||||
| Grichelde.functions.tClone        = tClone | ||||
| Grichelde.functions.tNext         = _G.next | ||||
| Grichelde.functions.setmetatable  = _G.setmetatable | ||||
| Grichelde.functions.getmetatable  = _G.getmetatable | ||||
| Grichelde.functions.select        = _G.select | ||||
| Grichelde.functions.unpack        = _G.unpack | ||||
| Grichelde.functions.find          = _G.string.find | ||||
| Grichelde.functions.sub           = _G.string.sub | ||||
| Grichelde.functions.gsub          = _G.string.gsub | ||||
| Grichelde.functions.match         = _G.strmatch | ||||
| Grichelde.functions.join          = _G.strjoin | ||||
| Grichelde.functions.split         = _G.strsplit | ||||
| Grichelde.functions.toUpper       = _G.strupper | ||||
| Grichelde.functions.toLower       = _G.strlower | ||||
| Grichelde.functions.isChar        = isChar | ||||
| Grichelde.functions.isNumber      = isNumber | ||||
| Grichelde.functions.isUpper       = isUpper | ||||
| Grichelde.functions.isLower       = isLower | ||||
| Grichelde.functions.isCapital     = isCapital | ||||
| Grichelde.functions.format        = _G.string.format | ||||
| Grichelde.functions.rep           = _G.string.rep | ||||
| Grichelde.functions.trim          = _G.strtrim | ||||
| Grichelde.functions.length        = _G.string.len | ||||
| Grichelde.functions.toString      = _G.tostring | ||||
| Grichelde.functions.toNumber      = _G.tonumber | ||||
| Grichelde.functions.max           = _G.math.max | ||||
| Grichelde.functions.min           = _G.math.min | ||||
| @@ -10,6 +10,9 @@ function Grichelde:GetDefaultConfig() | ||||
|         global = {}, | ||||
|         profile = { | ||||
|             enabled = true, | ||||
|             minimapButton = { | ||||
|                 hide = false | ||||
|             }, | ||||
|             channels = { | ||||
|                 ["*"] = false, | ||||
|                 say = true, | ||||
|   | ||||
| @@ -22,7 +22,15 @@ function Grichelde:CreateOptionsUI() | ||||
|                 desc = self:Format(self.L.Options_Enabled_Desc, self.L.AddonName), | ||||
|                 disabled = false, | ||||
|             }, | ||||
|  | ||||
|             minimapButton = { | ||||
|                 order = 1, | ||||
|                 type = "toggle", | ||||
|                 name = self.L.Options_Minimap_Button_Name, | ||||
|                 desc = self.L.Options_Minimap_Button_Desc, | ||||
|                 set = function(info, val) self:ToogleMinimapButton(info, val) end, | ||||
|                 get = function(info) return not self.db.profile.minimapButton.hide end, | ||||
|                 disabled = false, | ||||
|             }, | ||||
|             channels = { | ||||
|                 order = 2, | ||||
|                 type = "group", | ||||
| @@ -184,28 +192,28 @@ function Grichelde:CreateMapping(offset) | ||||
|             moveUp = { | ||||
|                 order = 10, | ||||
|                 type = "execute", | ||||
|                 --name = self.L.Options_Mapping_MoveUp_Name, | ||||
|                 -- name = self.L.Options_Mapping_MoveUp_Name, | ||||
|                 name = "", | ||||
|                 desc = self.L.Options_Mapping_MoveUp_Desc, | ||||
|                 image = "Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Up", | ||||
|                 width = 0.25, | ||||
|                 image = Grichelde.ICONS.MOVE_UP, | ||||
|                 width = 0.15, | ||||
|                 func = function(info) self:MoveUp(info) end | ||||
|             }, | ||||
|             moveDown = { | ||||
|                 order = 11, | ||||
|                 type = "execute", | ||||
|                 --name = self.L.Options_Mapping_MoveDown_Name, | ||||
|                 -- name = self.L.Options_Mapping_MoveDown_Name, | ||||
|                 name = "", | ||||
|                 desc = self.L.Options_Mapping_MoveDown_Desc, | ||||
|                 image = "Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up", | ||||
|                 width = 0.25, | ||||
|                 image = Grichelde.ICONS.MOVE_DOWN, | ||||
|                 width = 0.15, | ||||
|                 func = function(info) self:MoveDown(info) end | ||||
|             }, | ||||
|             spacer = { | ||||
|                 order = 18, | ||||
|                 type = "description", | ||||
|                 name = "", | ||||
|                 width = 1, | ||||
|                 width = 1.2, | ||||
|             }, | ||||
|             delete = { | ||||
|                 order = 19, | ||||
| @@ -221,14 +229,6 @@ function Grichelde:CreateMapping(offset) | ||||
|     } | ||||
| end | ||||
|  | ||||
| --dropButton:SetWidth(24) | ||||
| --dropButton:SetHeight(24) | ||||
| --dropButton:SetPoint("TOPRIGHT", DRight, "TOPRIGHT", -16, -18) | ||||
| --dropButton:SetNormalTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Up]]) | ||||
| --dropButton:SetPushedTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Down]]) | ||||
| --dropButton:SetDisabledTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Disabled]]) | ||||
| --dropButton:SetHighlightTexture([[Interface\Buttons\UI-Common-MouseHilight]], "ADD") | ||||
|  | ||||
| function Grichelde:SetupOptions() | ||||
|     -- add DB-backed profiles to UI options | ||||
|     local options = self:CreateOptionsUI() | ||||
| @@ -243,25 +243,6 @@ function Grichelde:SetupOptions() | ||||
|     return options, dialog | ||||
| end | ||||
|  | ||||
| function Grichelde:IsDisabled(info) | ||||
|     if info.option.type == "group" then | ||||
|         return false | ||||
|     end | ||||
|     return not self.db.profile.enabled | ||||
| end | ||||
|  | ||||
| function Grichelde:MappingName(info) | ||||
| --  self:TracePrint("MappingName : info") | ||||
| --  self:TracePrint(info) | ||||
|     local option = self.db.profile.replacements[info[2]] | ||||
|  | ||||
|     if nilOrEmpty(option.searchText) and nilOrEmpty(option.replaceText) then | ||||
|         return self.L.Options_Mapping_EmptyMapping | ||||
|     else | ||||
|         return self:Format(self.L.Options_Mapping_Group_Name, option.searchText or "", option.replaceText or "") | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Grichelde:RefreshOptions(event) | ||||
|     self:DebugPrint("RefreshOptions : event:", event) | ||||
|     if event == "OnNewProfile" then | ||||
| @@ -282,6 +263,87 @@ function Grichelde:RefreshOptions(event) | ||||
|     self:RefreshReplacements(self.db.profile.replacements) | ||||
| end | ||||
|  | ||||
| --- add Minimap button | ||||
| function Grichelde:MinimapButton() | ||||
|     local function toggleOptionsUI(_, button) | ||||
|         if button == 'LeftButton' then | ||||
|             self:ToggleOptions() | ||||
|         elseif button == 'RightButton' then | ||||
|             self:ToogleMappings() | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     local function tooltip(tooltip) | ||||
|         if not tooltip or not tooltip.AddLine then return end | ||||
|         tooltip:SetText(self.L.AddonName, | ||||
|             Grichelde.COLORS.HIGHLIGHT.r, Grichelde.COLORS.HIGHLIGHT.g, Grichelde.COLORS.HIGHLIGHT.b, Grichelde.COLORS.HIGHLIGHT.a | ||||
|         ) | ||||
|  | ||||
|         tooltip:AddDoubleLine(self.L.Options_Minimap_Tooltip_Options_Left, self.L.Options_Minimap_Tooltip_Options_Right, | ||||
|             Grichelde.COLORS.GREEN.r, Grichelde.COLORS.GREEN.g, Grichelde.COLORS.GREEN.b, Grichelde.COLORS.GREEN.a, | ||||
|             Grichelde.COLORS.NORMAL.r, Grichelde.COLORS.NORMAL.g, Grichelde.COLORS.NORMAL.b, Grichelde.COLORS.NORMAL.a | ||||
|         ) | ||||
|         tooltip:AddDoubleLine(self.L.Options_Minimap_Tooltip_Mappings_Left, self.L.Options_Minimap_Tooltip_Mappings_Right, | ||||
|             Grichelde.COLORS.GREEN.r, Grichelde.COLORS.GREEN.g, Grichelde.COLORS.GREEN.b, Grichelde.COLORS.GREEN.a, | ||||
|             Grichelde.COLORS.NORMAL.r, Grichelde.COLORS.NORMAL.g, Grichelde.COLORS.NORMAL.b, Grichelde.COLORS.NORMAL.a | ||||
|         ) | ||||
|     end | ||||
|  | ||||
|     local ldb = LibStub("LibDataBroker-1.1"):NewDataObject(self.name, { | ||||
|         type = "launcher", | ||||
|         text = self.AddonName, | ||||
|         icon = "Interface\\Icons\\Spell_Holy_Silence", | ||||
|         --icon = ([[Interface\Addons\%s\%s]]):format(self.name, self.name), | ||||
|         OnClick = toggleOptionsUI, | ||||
|         OnRightClick = function() self:ShowMappings() end, | ||||
|         OnTooltipShow = tooltip, | ||||
|     }) | ||||
|  | ||||
|     local icon = LibStub("LibDBIcon-1.0") | ||||
|     self:DebugPrint("MinimapButton : hidden: ", self.db.profile.minimapButton.hide) | ||||
|     icon:Register(self.name, ldb, self.db.profile.minimapButton) | ||||
|  | ||||
|     return ldb, icon | ||||
| end | ||||
|  | ||||
|  | ||||
| function Grichelde:ToggleOptions() | ||||
|     self:DebugPrint("MinimapButton : options open: ", self.dialog.OpenFrames[self.name]) | ||||
|     if self.dialog.OpenFrames[self.name] then | ||||
|         self:CloseOptions() | ||||
|     else | ||||
|         self:OpenOptions() | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Grichelde:OpenOptions() | ||||
|     self.dialog:Open(self.name) | ||||
| end | ||||
|  | ||||
| function Grichelde:CloseOptions() | ||||
|     self.dialog:Close(self.name) | ||||
| end | ||||
|  | ||||
| function Grichelde:IsDisabled(info) | ||||
|     if info.option.type == "group" then | ||||
|         return false | ||||
|     end | ||||
|     return not self.db.profile.enabled | ||||
| end | ||||
|  | ||||
| function Grichelde:MappingName(info) | ||||
| --  self:TracePrint("MappingName : info") | ||||
| --  self:TracePrint(info) | ||||
|     local option = self.db.profile.replacements[info[2]] | ||||
|  | ||||
|     if nilOrEmpty(option.searchText) and nilOrEmpty(option.replaceText) then | ||||
|         return self.L.Options_Mapping_EmptyMapping | ||||
|     else | ||||
|         return self:Format(self.L.Options_Mapping_Group_Name, option.searchText or "", option.replaceText or "") | ||||
|     end | ||||
| end | ||||
|  | ||||
|  | ||||
| --- Create UI options for rhe given replacement table (from DB). | ||||
| --- Usually called with with self.db.profile.replacements | ||||
| -- @param replacementsTable | ||||
| @@ -440,3 +502,21 @@ function Grichelde:DeleteAllMappings() | ||||
|  | ||||
|     self:RefreshOptions("DeleteAllMappings") | ||||
| end | ||||
|  | ||||
| function Grichelde:ToogleMinimapButton(info, val) | ||||
|     self:TracePrint("ToogleMinimapButton : info") | ||||
|     for i = 0, #info do | ||||
|         self:TracePrint("%d = %s", i, info[i]) | ||||
|     end | ||||
|  | ||||
|     self.db.profile.minimapButton.hide = not val | ||||
|     self:DebugPrint("ToogleMinimapButton : hidden: ", self.db.profile.minimapButton.hide) | ||||
|  | ||||
|     if self.db.profile.minimapButton.hide then | ||||
|         self.icon:Hide(self.name); | ||||
|     else | ||||
|         self.icon:Show(self.name); | ||||
|     end | ||||
| end | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ function Grichelde:Upgrade_To_v060() | ||||
|     self:PrefixedPrint(self.L.Upgrade_ToVersion, Grichelde.COLOR_CODES.ORANGE .. "0.6.0" .. Grichelde.COLOR_CODES.CLOSE) | ||||
|  | ||||
|     local replacements = self.db.profile.replacements or {} | ||||
|     self:DebugPrint("Upgrade_To_060 : old database") | ||||
|     self:DebugPrint("Upgrade_To_v060 : old database") | ||||
|     self:DebugPrint(replacements) | ||||
|  | ||||
|     for _, replTable in pairs(replacements) do | ||||
| @@ -16,7 +16,7 @@ function Grichelde:Upgrade_To_v060() | ||||
|         replTable["caseSensitive"] = nil | ||||
|     end | ||||
|  | ||||
|     self:DebugPrint("Upgrade_To_060 : new database") | ||||
|     self:DebugPrint("Upgrade_To_v060 : new database") | ||||
|     self:DebugPrint(replacements) | ||||
|     return 0, 6, 0 | ||||
| end | ||||
| @@ -25,7 +25,7 @@ function Grichelde:Upgrade_To_v070() | ||||
|     self:PrefixedPrint(self.L.Upgrade_ToVersion, Grichelde.COLOR_CODES.ORANGE .. "0.7.0" .. Grichelde.COLOR_CODES.CLOSE) | ||||
|  | ||||
|     local replacements = self.db.profile.replacements or {} | ||||
|     self:DebugPrint("Upgrade_To_070 : old database") | ||||
|     self:DebugPrint("Upgrade_To_v070 : old database") | ||||
|     self:DebugPrint(replacements) | ||||
|  | ||||
|     for _, replTable in pairs(replacements) do | ||||
| @@ -33,16 +33,23 @@ function Grichelde:Upgrade_To_v070() | ||||
|         replTable["ignoreCase"] = nil | ||||
|     end | ||||
|  | ||||
|     self:DebugPrint("Upgrade_To_070 : new database") | ||||
|     self:DebugPrint("Upgrade_To_v070 : new database") | ||||
|     self:DebugPrint(replacements) | ||||
|     return 0, 7, 0 | ||||
| end | ||||
|  | ||||
| --[[ | ||||
| function Grichelde:Upgrade_To_v071() | ||||
|     return 0, 7, 1 | ||||
| function Grichelde:Upgrade_To_v072() | ||||
|     self:PrefixedPrint(self.L.Upgrade_ToVersion, Grichelde.COLOR_CODES.ORANGE .. "0.7.2" .. Grichelde.COLOR_CODES.CLOSE) | ||||
|  | ||||
|     self:DebugPrint("Upgrade_To_v072 : old database") | ||||
|     self:DebugPrint(self.db.profile) | ||||
|  | ||||
|     self.db.profile["minimapButton"] = { hide = false } | ||||
|  | ||||
|     self:DebugPrint("Upgrade_To_v072 : new database") | ||||
|     self:DebugPrint(self.db.profile) | ||||
|     return 0, 7, 2 | ||||
| end | ||||
| ]] | ||||
|  | ||||
| function Grichelde:UpgradeDatabase() | ||||
|     local dbVersion = self.db.global.version or "0.0.0" | ||||
| @@ -63,14 +70,12 @@ function Grichelde:UpgradeDatabase() | ||||
|             upgrade = upgrade + 1 | ||||
|             major, minor, patch = self:Upgrade_To_v070(dbVersion) | ||||
|         end | ||||
| --[[ | ||||
|         if minor == 7 then | ||||
|             if patch < 1 then | ||||
|             if patch < 2 then | ||||
|                 upgrade = upgrade + 1 | ||||
|                 major, minor, patch = self:Upgrade_To_v71(dbVersion) | ||||
|                 major, minor, patch = self:Upgrade_To_v072(dbVersion) | ||||
|             end | ||||
|         end | ||||
| ]] | ||||
|     end | ||||
|  | ||||
|     if upgrade == 0 then | ||||
|   | ||||
| @@ -172,6 +172,14 @@ function Grichelde:PrintOptions() | ||||
|     end, self.options.args.replacements.args) | ||||
| end | ||||
|  | ||||
| --- Print DB | ||||
| function Grichelde:PrintProfile() | ||||
|     self:PrefixedPrint(self.COLOR_CODES.PREFIX .. self.L.Debug_Profile .. self.COLOR_CODES.CLOSE) | ||||
|     self:LogPrint(-1, function(...) | ||||
|         print(self.COLOR_CODES.PREFIX .. self.L.AddonName .. self.COLOR_CODES.CLOSE .. ":", self:Format(...)) | ||||
|     end, self.db.profile) | ||||
| end | ||||
|  | ||||
| --- Print DB replacements to chat frame | ||||
| function Grichelde:PrintMappings() | ||||
|     self:PrefixedPrint(self.COLOR_CODES.PREFIX .. self.L.Debug_Mappings .. self.COLOR_CODES.CLOSE) | ||||
| @@ -181,9 +189,11 @@ function Grichelde:PrintMappings() | ||||
| end | ||||
|  | ||||
| --- Open UI windows with replacements in it | ||||
| function Grichelde:ShowMappings() | ||||
|     if self.debugFrame and self.debugFrame:IsShown() then | ||||
|         self.debugFrame:Release(self.debugFrame) | ||||
| function Grichelde:ToogleMappings() | ||||
|     local AceGUI = LibStub("AceGUI-3.0") | ||||
|  | ||||
|     if self.debugFrame then | ||||
|         AceGUI:Release(self.debugFrame) | ||||
|         self.debugFrame = nil | ||||
|     else | ||||
|         local replacements = self.db.profile.replacements or {} | ||||
| @@ -194,28 +204,40 @@ function Grichelde:ShowMappings() | ||||
|             end | ||||
|         end | ||||
|  | ||||
|         local AceGUI = LibStub("AceGUI-3.0") | ||||
|         local frame = AceGUI:Create("Frame"); | ||||
|         frame:SetTitle(self.L.Debug_Mappings); | ||||
|         frame:SetStatusText(self:Format(self.L.Debug_Mappings_Found, repls)) | ||||
|         frame:SetWidth(400); | ||||
|         frame:SetHeight(600); | ||||
|         frame:SetLayout("Fill"); | ||||
|  | ||||
|         local function closeFrame() frame:Release(frame) end | ||||
|         frame:SetAutoAdjustHeight(true) | ||||
|         --frame:SetFullHeight(true) | ||||
|         frame:SetLayout("Flow"); | ||||
|         local function closeFrame(widget) AceGUI:Release(widget); self.debugFrame = nil end | ||||
|         frame:SetCallback("OnClose", closeFrame) | ||||
|  | ||||
|         local hint = AceGUI:Create("Label"); | ||||
|         hint:SetText(self.L.Debug_Mappings_Hint) | ||||
|         hint:SetFullWidth(true) | ||||
|         frame:AddChild(hint); | ||||
|  | ||||
|         local scroll = AceGUI:Create("ScrollFrame"); | ||||
|         scroll:SetFullWidth(true) | ||||
|         scroll:SetFullHeight(true) | ||||
|         scroll:SetLayout("Fill"); | ||||
|  | ||||
|         local configBox = AceGUI:Create("MultiLineEditBox"); | ||||
|         configBox:SetLabel("") | ||||
|         local text = "" | ||||
|         tPrint(replacements, 0, {}, function(s) text = text .. s .. "|n" end) | ||||
|         configBox:SetLabel("") | ||||
|         configBox:SetText(text) | ||||
|         configBox:SetFullWidth(true) | ||||
|         configBox:SetFullHeight(true) | ||||
|         configBox:DisableButton(true) | ||||
|         --configBox:SetDisabled(true) | ||||
|         configBox:SetNumLines(30); | ||||
|         configBox:SetNumLines(50); | ||||
|         configBox:SetFocus() | ||||
|         scroll:AddChild(configBox); | ||||
|  | ||||
|         frame:AddChild(configBox); | ||||
|         frame:AddChild(scroll); | ||||
|         self.debugFrame = frame | ||||
|     end | ||||
| end | ||||
							
								
								
									
										470
									
								
								Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										470
									
								
								Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,470 @@ | ||||
|  | ||||
| ----------------------------------------------------------------------- | ||||
| -- LibDBIcon-1.0 | ||||
| -- | ||||
| -- Allows addons to easily create a lightweight minimap icon as an alternative to heavier LDB displays. | ||||
| -- | ||||
|  | ||||
| local DBICON10 = "LibDBIcon-1.0" | ||||
| local DBICON10_MINOR = 43 -- Bump on changes | ||||
| if not LibStub then error(DBICON10 .. " requires LibStub.") end | ||||
| local ldb = LibStub("LibDataBroker-1.1", true) | ||||
| if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end | ||||
| local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR) | ||||
| if not lib then return end | ||||
|  | ||||
| lib.objects = lib.objects or {} | ||||
| lib.callbackRegistered = lib.callbackRegistered or nil | ||||
| lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) | ||||
| lib.notCreated = lib.notCreated or {} | ||||
| lib.radius = lib.radius or 5 | ||||
| lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate") | ||||
| local next, Minimap = next, Minimap | ||||
| local isDraggingButton = false | ||||
|  | ||||
| function lib:IconCallback(event, name, key, value) | ||||
| 	if lib.objects[name] then | ||||
| 		if key == "icon" then | ||||
| 			lib.objects[name].icon:SetTexture(value) | ||||
| 		elseif key == "iconCoords" then | ||||
| 			lib.objects[name].icon:UpdateCoord() | ||||
| 		elseif key == "iconR" then | ||||
| 			local _, g, b = lib.objects[name].icon:GetVertexColor() | ||||
| 			lib.objects[name].icon:SetVertexColor(value, g, b) | ||||
| 		elseif key == "iconG" then | ||||
| 			local r, _, b = lib.objects[name].icon:GetVertexColor() | ||||
| 			lib.objects[name].icon:SetVertexColor(r, value, b) | ||||
| 		elseif key == "iconB" then | ||||
| 			local r, g = lib.objects[name].icon:GetVertexColor() | ||||
| 			lib.objects[name].icon:SetVertexColor(r, g, value) | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
| if not lib.callbackRegistered then | ||||
| 	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback") | ||||
| 	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback") | ||||
| 	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconR", "IconCallback") | ||||
| 	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconG", "IconCallback") | ||||
| 	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconB", "IconCallback") | ||||
| 	lib.callbackRegistered = true | ||||
| end | ||||
|  | ||||
| local function getAnchors(frame) | ||||
| 	local x, y = frame:GetCenter() | ||||
| 	if not x or not y then return "CENTER" end | ||||
| 	local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or "" | ||||
| 	local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM" | ||||
| 	return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf | ||||
| end | ||||
|  | ||||
| local function onEnter(self) | ||||
| 	if isDraggingButton then return end | ||||
|  | ||||
| 	for _, button in next, lib.objects do | ||||
| 		if button.showOnMouseover then | ||||
| 			button.fadeOut:Stop() | ||||
| 			button:SetAlpha(1) | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	local obj = self.dataObject | ||||
| 	if obj.OnTooltipShow then | ||||
| 		lib.tooltip:SetOwner(self, "ANCHOR_NONE") | ||||
| 		lib.tooltip:SetPoint(getAnchors(self)) | ||||
| 		obj.OnTooltipShow(lib.tooltip) | ||||
| 		lib.tooltip:Show() | ||||
| 	elseif obj.OnEnter then | ||||
| 		obj.OnEnter(self) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function onLeave(self) | ||||
| 	lib.tooltip:Hide() | ||||
|  | ||||
| 	if not isDraggingButton then | ||||
| 		for _, button in next, lib.objects do | ||||
| 			if button.showOnMouseover then | ||||
| 				button.fadeOut:Play() | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	local obj = self.dataObject | ||||
| 	if obj.OnLeave then | ||||
| 		obj.OnLeave(self) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
|  | ||||
| local onDragStart, updatePosition | ||||
|  | ||||
| do | ||||
| 	local minimapShapes = { | ||||
| 		["ROUND"] = {true, true, true, true}, | ||||
| 		["SQUARE"] = {false, false, false, false}, | ||||
| 		["CORNER-TOPLEFT"] = {false, false, false, true}, | ||||
| 		["CORNER-TOPRIGHT"] = {false, false, true, false}, | ||||
| 		["CORNER-BOTTOMLEFT"] = {false, true, false, false}, | ||||
| 		["CORNER-BOTTOMRIGHT"] = {true, false, false, false}, | ||||
| 		["SIDE-LEFT"] = {false, true, false, true}, | ||||
| 		["SIDE-RIGHT"] = {true, false, true, false}, | ||||
| 		["SIDE-TOP"] = {false, false, true, true}, | ||||
| 		["SIDE-BOTTOM"] = {true, true, false, false}, | ||||
| 		["TRICORNER-TOPLEFT"] = {false, true, true, true}, | ||||
| 		["TRICORNER-TOPRIGHT"] = {true, false, true, true}, | ||||
| 		["TRICORNER-BOTTOMLEFT"] = {true, true, false, true}, | ||||
| 		["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false}, | ||||
| 	} | ||||
|  | ||||
| 	local rad, cos, sin, sqrt, max, min = math.rad, math.cos, math.sin, math.sqrt, math.max, math.min | ||||
| 	function updatePosition(button, position) | ||||
| 		local angle = rad(position or 225) | ||||
| 		local x, y, q = cos(angle), sin(angle), 1 | ||||
| 		if x < 0 then q = q + 1 end | ||||
| 		if y > 0 then q = q + 2 end | ||||
| 		local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND" | ||||
| 		local quadTable = minimapShapes[minimapShape] | ||||
| 		local w = (Minimap:GetWidth() / 2) + lib.radius | ||||
| 		local h = (Minimap:GetHeight() / 2) + lib.radius | ||||
| 		if quadTable[q] then | ||||
| 			x, y = x*w, y*h | ||||
| 		else | ||||
| 			local diagRadiusW = sqrt(2*(w)^2)-10 | ||||
| 			local diagRadiusH = sqrt(2*(h)^2)-10 | ||||
| 			x = max(-w, min(x*diagRadiusW, w)) | ||||
| 			y = max(-h, min(y*diagRadiusH, h)) | ||||
| 		end | ||||
| 		button:SetPoint("CENTER", Minimap, "CENTER", x, y) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function onClick(self, b) | ||||
| 	if self.dataObject.OnClick then | ||||
| 		self.dataObject.OnClick(self, b) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function onMouseDown(self) | ||||
| 	self.isMouseDown = true | ||||
| 	self.icon:UpdateCoord() | ||||
| end | ||||
|  | ||||
| local function onMouseUp(self) | ||||
| 	self.isMouseDown = false | ||||
| 	self.icon:UpdateCoord() | ||||
| end | ||||
|  | ||||
| do | ||||
| 	local deg, atan2 = math.deg, math.atan2 | ||||
| 	local function onUpdate(self) | ||||
| 		local mx, my = Minimap:GetCenter() | ||||
| 		local px, py = GetCursorPosition() | ||||
| 		local scale = Minimap:GetEffectiveScale() | ||||
| 		px, py = px / scale, py / scale | ||||
| 		local pos = 225 | ||||
| 		if self.db then | ||||
| 			pos = deg(atan2(py - my, px - mx)) % 360 | ||||
| 			self.db.minimapPos = pos | ||||
| 		else | ||||
| 			pos = deg(atan2(py - my, px - mx)) % 360 | ||||
| 			self.minimapPos = pos | ||||
| 		end | ||||
| 		updatePosition(self, pos) | ||||
| 	end | ||||
|  | ||||
| 	function onDragStart(self) | ||||
| 		self:LockHighlight() | ||||
| 		self.isMouseDown = true | ||||
| 		self.icon:UpdateCoord() | ||||
| 		self:SetScript("OnUpdate", onUpdate) | ||||
| 		isDraggingButton = true | ||||
| 		lib.tooltip:Hide() | ||||
| 		for _, button in next, lib.objects do | ||||
| 			if button.showOnMouseover then | ||||
| 				button.fadeOut:Stop() | ||||
| 				button:SetAlpha(1) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function onDragStop(self) | ||||
| 	self:SetScript("OnUpdate", nil) | ||||
| 	self.isMouseDown = false | ||||
| 	self.icon:UpdateCoord() | ||||
| 	self:UnlockHighlight() | ||||
| 	isDraggingButton = false | ||||
| 	for _, button in next, lib.objects do | ||||
| 		if button.showOnMouseover then | ||||
| 			button.fadeOut:Play() | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local defaultCoords = {0, 1, 0, 1} | ||||
| local function updateCoord(self) | ||||
| 	local coords = self:GetParent().dataObject.iconCoords or defaultCoords | ||||
| 	local deltaX, deltaY = 0, 0 | ||||
| 	if not self:GetParent().isMouseDown then | ||||
| 		deltaX = (coords[2] - coords[1]) * 0.05 | ||||
| 		deltaY = (coords[4] - coords[3]) * 0.05 | ||||
| 	end | ||||
| 	self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY) | ||||
| end | ||||
|  | ||||
| local function createButton(name, object, db) | ||||
| 	local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap) | ||||
| 	button.dataObject = object | ||||
| 	button.db = db | ||||
| 	button:SetFrameStrata("MEDIUM") | ||||
| 	button:SetSize(31, 31) | ||||
| 	button:SetFrameLevel(8) | ||||
| 	button:RegisterForClicks("anyUp") | ||||
| 	button:RegisterForDrag("LeftButton") | ||||
| 	button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight" | ||||
| 	local overlay = button:CreateTexture(nil, "OVERLAY") | ||||
| 	overlay:SetSize(53, 53) | ||||
| 	overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder" | ||||
| 	overlay:SetPoint("TOPLEFT") | ||||
| 	local background = button:CreateTexture(nil, "BACKGROUND") | ||||
| 	background:SetSize(20, 20) | ||||
| 	background:SetTexture(136467) --"Interface\\Minimap\\UI-Minimap-Background" | ||||
| 	background:SetPoint("TOPLEFT", 7, -5) | ||||
| 	local icon = button:CreateTexture(nil, "ARTWORK") | ||||
| 	icon:SetSize(17, 17) | ||||
| 	icon:SetTexture(object.icon) | ||||
| 	icon:SetPoint("TOPLEFT", 7, -6) | ||||
| 	button.icon = icon | ||||
| 	button.isMouseDown = false | ||||
|  | ||||
| 	local r, g, b = icon:GetVertexColor() | ||||
| 	icon:SetVertexColor(object.iconR or r, object.iconG or g, object.iconB or b) | ||||
|  | ||||
| 	icon.UpdateCoord = updateCoord | ||||
| 	icon:UpdateCoord() | ||||
|  | ||||
| 	button:SetScript("OnEnter", onEnter) | ||||
| 	button:SetScript("OnLeave", onLeave) | ||||
| 	button:SetScript("OnClick", onClick) | ||||
| 	if not db or not db.lock then | ||||
| 		button:SetScript("OnDragStart", onDragStart) | ||||
| 		button:SetScript("OnDragStop", onDragStop) | ||||
| 	end | ||||
| 	button:SetScript("OnMouseDown", onMouseDown) | ||||
| 	button:SetScript("OnMouseUp", onMouseUp) | ||||
|  | ||||
| 	button.fadeOut = button:CreateAnimationGroup() | ||||
| 	local animOut = button.fadeOut:CreateAnimation("Alpha") | ||||
| 	animOut:SetOrder(1) | ||||
| 	animOut:SetDuration(0.2) | ||||
| 	animOut:SetFromAlpha(1) | ||||
| 	animOut:SetToAlpha(0) | ||||
| 	animOut:SetStartDelay(1) | ||||
| 	button.fadeOut:SetToFinalAlpha(true) | ||||
|  | ||||
| 	lib.objects[name] = button | ||||
|  | ||||
| 	if lib.loggedIn then | ||||
| 		updatePosition(button, db and db.minimapPos) | ||||
| 		if not db or not db.hide then | ||||
| 			button:Show() | ||||
| 		else | ||||
| 			button:Hide() | ||||
| 		end | ||||
| 	end | ||||
| 	lib.callbacks:Fire("LibDBIcon_IconCreated", button, name) -- Fire 'Icon Created' callback | ||||
| end | ||||
|  | ||||
| -- We could use a metatable.__index on lib.objects, but then we'd create | ||||
| -- the icons when checking things like :IsRegistered, which is not necessary. | ||||
| local function check(name) | ||||
| 	if lib.notCreated[name] then | ||||
| 		createButton(name, lib.notCreated[name][1], lib.notCreated[name][2]) | ||||
| 		lib.notCreated[name] = nil | ||||
| 	end | ||||
| end | ||||
|  | ||||
| -- Wait a bit with the initial positioning to let any GetMinimapShape addons | ||||
| -- load up. | ||||
| if not lib.loggedIn then | ||||
| 	local f = CreateFrame("Frame") | ||||
| 	f:SetScript("OnEvent", function(f) | ||||
| 		for _, button in next, lib.objects do | ||||
| 			updatePosition(button, button.db and button.db.minimapPos) | ||||
| 			if not button.db or not button.db.hide then | ||||
| 				button:Show() | ||||
| 			else | ||||
| 				button:Hide() | ||||
| 			end | ||||
| 		end | ||||
| 		lib.loggedIn = true | ||||
| 		f:SetScript("OnEvent", nil) | ||||
| 	end) | ||||
| 	f:RegisterEvent("PLAYER_LOGIN") | ||||
| end | ||||
|  | ||||
| local function getDatabase(name) | ||||
| 	return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db | ||||
| end | ||||
|  | ||||
| function lib:Register(name, object, db) | ||||
| 	if not object.icon then error("Can't register LDB objects without icons set!") end | ||||
| 	if lib.objects[name] or lib.notCreated[name] then error(DBICON10.. ": Object '".. name .."' is already registered.") end | ||||
| 	if not db or not db.hide then | ||||
| 		createButton(name, object, db) | ||||
| 	else | ||||
| 		lib.notCreated[name] = {object, db} | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:Lock(name) | ||||
| 	if not lib:IsRegistered(name) then return end | ||||
| 	if lib.objects[name] then | ||||
| 		lib.objects[name]:SetScript("OnDragStart", nil) | ||||
| 		lib.objects[name]:SetScript("OnDragStop", nil) | ||||
| 	end | ||||
| 	local db = getDatabase(name) | ||||
| 	if db then | ||||
| 		db.lock = true | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:Unlock(name) | ||||
| 	if not lib:IsRegistered(name) then return end | ||||
| 	if lib.objects[name] then | ||||
| 		lib.objects[name]:SetScript("OnDragStart", onDragStart) | ||||
| 		lib.objects[name]:SetScript("OnDragStop", onDragStop) | ||||
| 	end | ||||
| 	local db = getDatabase(name) | ||||
| 	if db then | ||||
| 		db.lock = nil | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:Hide(name) | ||||
| 	if not lib.objects[name] then return end | ||||
| 	lib.objects[name]:Hide() | ||||
| end | ||||
|  | ||||
| function lib:Show(name) | ||||
| 	check(name) | ||||
| 	local button = lib.objects[name] | ||||
| 	if button then | ||||
| 		button:Show() | ||||
| 		updatePosition(button, button.db and button.db.minimapPos or button.minimapPos) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:IsRegistered(name) | ||||
| 	return (lib.objects[name] or lib.notCreated[name]) and true or false | ||||
| end | ||||
|  | ||||
| function lib:Refresh(name, db) | ||||
| 	check(name) | ||||
| 	local button = lib.objects[name] | ||||
| 	if db then | ||||
| 		button.db = db | ||||
| 	end | ||||
| 	updatePosition(button, button.db and button.db.minimapPos or button.minimapPos) | ||||
| 	if not button.db or not button.db.hide then | ||||
| 		button:Show() | ||||
| 	else | ||||
| 		button:Hide() | ||||
| 	end | ||||
| 	if not button.db or not button.db.lock then | ||||
| 		button:SetScript("OnDragStart", onDragStart) | ||||
| 		button:SetScript("OnDragStop", onDragStop) | ||||
| 	else | ||||
| 		button:SetScript("OnDragStart", nil) | ||||
| 		button:SetScript("OnDragStop", nil) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:GetMinimapButton(name) | ||||
| 	return lib.objects[name] | ||||
| end | ||||
|  | ||||
| do | ||||
| 	local function OnMinimapEnter() | ||||
| 		if isDraggingButton then return end | ||||
| 		for _, button in next, lib.objects do | ||||
| 			if button.showOnMouseover then | ||||
| 				button.fadeOut:Stop() | ||||
| 				button:SetAlpha(1) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	local function OnMinimapLeave() | ||||
| 		if isDraggingButton then return end | ||||
| 		for _, button in next, lib.objects do | ||||
| 			if button.showOnMouseover then | ||||
| 				button.fadeOut:Play() | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	Minimap:HookScript("OnEnter", OnMinimapEnter) | ||||
| 	Minimap:HookScript("OnLeave", OnMinimapLeave) | ||||
|  | ||||
| 	function lib:ShowOnEnter(name, value) | ||||
| 		local button = lib.objects[name] | ||||
| 		if button then | ||||
| 			if value then | ||||
| 				button.showOnMouseover = true | ||||
| 				button.fadeOut:Stop() | ||||
| 				button:SetAlpha(0) | ||||
| 			else | ||||
| 				button.showOnMouseover = false | ||||
| 				button.fadeOut:Stop() | ||||
| 				button:SetAlpha(1) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:GetButtonList() | ||||
| 	local t = {} | ||||
| 	for name in next, lib.objects do | ||||
| 		t[#t+1] = name | ||||
| 	end | ||||
| 	return t | ||||
| end | ||||
|  | ||||
| function lib:SetButtonRadius(radius) | ||||
| 	if type(radius) == "number" then | ||||
| 		lib.radius = radius | ||||
| 		for _, button in next, lib.objects do | ||||
| 			updatePosition(button, button.db and button.db.minimapPos or button.minimapPos) | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function lib:SetButtonToPosition(button, position) | ||||
| 	updatePosition(lib.objects[button] or button, position) | ||||
| end | ||||
|  | ||||
| -- Upgrade! | ||||
| for name, button in next, lib.objects do | ||||
| 	local db = getDatabase(name) | ||||
| 	if not db or not db.lock then | ||||
| 		button:SetScript("OnDragStart", onDragStart) | ||||
| 		button:SetScript("OnDragStop", onDragStop) | ||||
| 	end | ||||
| 	button:SetScript("OnEnter", onEnter) | ||||
| 	button:SetScript("OnLeave", onLeave) | ||||
| 	button:SetScript("OnClick", onClick) | ||||
| 	button:SetScript("OnMouseDown", onMouseDown) | ||||
| 	button:SetScript("OnMouseUp", onMouseUp) | ||||
|  | ||||
| 	if not button.fadeOut then -- Upgrade to 39 | ||||
| 		button.fadeOut = button:CreateAnimationGroup() | ||||
| 		local animOut = button.fadeOut:CreateAnimation("Alpha") | ||||
| 		animOut:SetOrder(1) | ||||
| 		animOut:SetDuration(0.2) | ||||
| 		animOut:SetFromAlpha(1) | ||||
| 		animOut:SetToAlpha(0) | ||||
| 		animOut:SetStartDelay(1) | ||||
| 		button.fadeOut:SetToFinalAlpha(true) | ||||
| 	end | ||||
| end | ||||
| lib:SetButtonRadius(lib.radius) -- Upgrade to 40 | ||||
							
								
								
									
										7
									
								
								Libs/LibDBIcon-1.0/lib.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Libs/LibDBIcon-1.0/lib.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <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="LibDBIcon-1.0.lua"/> | ||||
|  | ||||
| </Ui> | ||||
|  | ||||
							
								
								
									
										90
									
								
								Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
|  | ||||
| assert(LibStub, "LibDataBroker-1.1 requires LibStub") | ||||
| assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0") | ||||
|  | ||||
| local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4) | ||||
| if not lib then return end | ||||
| oldminor = oldminor or 0 | ||||
|  | ||||
|  | ||||
| lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib) | ||||
| lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {} | ||||
| local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks | ||||
|  | ||||
| if oldminor < 2 then | ||||
| 	lib.domt = { | ||||
| 		__metatable = "access denied", | ||||
| 		__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end, | ||||
| 	} | ||||
| end | ||||
|  | ||||
| if oldminor < 3 then | ||||
| 	lib.domt.__newindex = function(self, key, value) | ||||
| 		if not attributestorage[self] then attributestorage[self] = {} end | ||||
| 		if attributestorage[self][key] == value then return end | ||||
| 		attributestorage[self][key] = value | ||||
| 		local name = namestorage[self] | ||||
| 		if not name then return end | ||||
| 		callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self) | ||||
| 		callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self) | ||||
| 		callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self) | ||||
| 		callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| if oldminor < 2 then | ||||
| 	function lib:NewDataObject(name, dataobj) | ||||
| 		if self.proxystorage[name] then return end | ||||
|  | ||||
| 		if dataobj then | ||||
| 			assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table") | ||||
| 			self.attributestorage[dataobj] = {} | ||||
| 			for i,v in pairs(dataobj) do | ||||
| 				self.attributestorage[dataobj][i] = v | ||||
| 				dataobj[i] = nil | ||||
| 			end | ||||
| 		end | ||||
| 		dataobj = setmetatable(dataobj or {}, self.domt) | ||||
| 		self.proxystorage[name], self.namestorage[dataobj] = dataobj, name | ||||
| 		self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj) | ||||
| 		return dataobj | ||||
| 	end | ||||
| end | ||||
|  | ||||
| if oldminor < 1 then | ||||
| 	function lib:DataObjectIterator() | ||||
| 		return pairs(self.proxystorage) | ||||
| 	end | ||||
|  | ||||
| 	function lib:GetDataObjectByName(dataobjectname) | ||||
| 		return self.proxystorage[dataobjectname] | ||||
| 	end | ||||
|  | ||||
| 	function lib:GetNameByDataObject(dataobject) | ||||
| 		return self.namestorage[dataobject] | ||||
| 	end | ||||
| end | ||||
|  | ||||
| if oldminor < 4 then | ||||
| 	local next = pairs(attributestorage) | ||||
| 	function lib:pairs(dataobject_or_name) | ||||
| 		local t = type(dataobject_or_name) | ||||
| 		assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)") | ||||
|  | ||||
| 		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name | ||||
| 		assert(attributestorage[dataobj], "Data object not found") | ||||
|  | ||||
| 		return next, attributestorage[dataobj], nil | ||||
| 	end | ||||
|  | ||||
| 	local ipairs_iter = ipairs(attributestorage) | ||||
| 	function lib:ipairs(dataobject_or_name) | ||||
| 		local t = type(dataobject_or_name) | ||||
| 		assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)") | ||||
|  | ||||
| 		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name | ||||
| 		assert(attributestorage[dataobj], "Data object not found") | ||||
|  | ||||
| 		return ipairs_iter, attributestorage[dataobj], 0 | ||||
| 	end | ||||
| end | ||||
							
								
								
									
										13
									
								
								Libs/LibDataBroker-1.1/README.textile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Libs/LibDataBroker-1.1/README.textile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| LibDataBroker is a small WoW addon library designed to provide a "MVC":http://en.wikipedia.org/wiki/Model-view-controller interface for use in various addons. | ||||
| LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon. | ||||
| Plugins can provide data into a simple table, and display addons can receive callbacks to refresh their display of this data. | ||||
| LDB also provides a place for addons to register "quicklaunch" functions, removing the need for authors to embed many large libraries to create minimap buttons. | ||||
| Users who do not wish to be "plagued" by these buttons simply do not install an addon to render them. | ||||
|  | ||||
| Due to it's simple generic design, LDB can be used for any design where you wish to have an addon notified of changes to a table. | ||||
|  | ||||
| h2. Links | ||||
|  | ||||
| * "API documentation":http://github.com/tekkub/libdatabroker-1-1/wikis/api | ||||
| * "Data specifications":http://github.com/tekkub/libdatabroker-1-1/wikis/data-specifications | ||||
| * "Addons using LDB":http://github.com/tekkub/libdatabroker-1-1/wikis/addons-using-ldb | ||||
							
								
								
									
										25
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								README.md
									
									
									
									
									
								
							| @@ -8,4 +8,27 @@ Intentionally started as a helper addon for a roleplaying friend, Grichelde can | ||||
| * write out abbreviations for you | ||||
| * create hilarious moments during roleplay | ||||
|  | ||||
| <!-- Did you ever had an Undead without a jaw and wondered how it might sound like if s/he'd actually speak? -->  | ||||
| ## FAQ | ||||
|  | ||||
| ### How do I start | ||||
|  | ||||
| Grichelde is active right from the start with default mappings. To open the options UI, either left-click on | ||||
| the new minimap icon, or type `/gri` or `/grichelde` in the chatbox. All mappings and channels can be configured there. | ||||
|  | ||||
| ### My replacement is not taken. | ||||
|  | ||||
| After entering a search or replacement text, you see a button "Okay" next to yout input. This is **not** a validation message,  | ||||
| but the save button for text. This is a rectriction from the UI library and can be seen in other addons as well.  | ||||
| Please click on "Okay" button to save the input permanently. | ||||
|  | ||||
| ### I get errors, what should I do? | ||||
|  | ||||
| Please report your errors here. Make a screenshot or copy both the error message as well as your recent mappings. | ||||
| You can bring up a small windows with your mapping by right-clicking the minimap icon or entering the "/gri mappings" command. | ||||
|  | ||||
| ### Why that strange name? | ||||
|  | ||||
| Grichelde is the name of the undead rogue without a jaw, that was played in RP session with my friend. | ||||
| She started replacing "s" and "t" letters manually for each line in the chat, which is cumbersome over time. | ||||
| (If you wondered how an Undead without a jaw sounds like, its really hilarious.) Without spelling errors,  | ||||
| "Griselde" in German would be a old-fashioned female first name. | ||||
|   | ||||
							
								
								
									
										6
									
								
								libs.xml
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								libs.xml
									
									
									
									
									
								
							| @@ -2,14 +2,16 @@ | ||||
| ..\FrameXML\UI.xsd"> | ||||
|  | ||||
|   <Script file="Libs\LibStub\LibStub.lua"/> | ||||
|   <Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua" /> | ||||
|   <Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua" /> | ||||
|   <Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/> | ||||
|   <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/> | ||||
|   <Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/> | ||||
|   <Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/> | ||||
|   <Include file="Libs\AceDB-3.0\AceDB-3.0.xml"/> | ||||
|   <Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/> | ||||
|   <Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/> | ||||
|   <Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml" /> | ||||
|   <Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" /> | ||||
|   <Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/> | ||||
|   <Include file="Libs\AceHook-3.0\AceHook-3.0.xml"/> | ||||
|   <Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" /> | ||||
| </Ui> | ||||
|   | ||||
| @@ -9,7 +9,9 @@ L.Upgrade_ToVersion = "Hebe Databank auf Version %s an." | ||||
| L.Upgrade_Successful = "Upgrade erfolgreich." | ||||
| L.Debug_Options = "Optionen" | ||||
| L.Debug_Mappings = "Ersetzungen" | ||||
| L.Debug_Mappings_Hint = "Der Inhalt der Textbox dient nur zur Fehlersuche und kann herauskopiert werden. Es werden keine Werte aus dieser Textbox eingelesen oder anderweitig verwertet." | ||||
| L.Debug_Mappings_Found = "%d Ersetzungen gefunden" | ||||
| L.Debug_Profile = "Profil" | ||||
|  | ||||
| -- profiles | ||||
| L.Profiles_Available = "Verf\195\188gbare Profile:" | ||||
| @@ -26,6 +28,12 @@ L.Profiles_DeleteError = "Das aktive Profil kann nicht gel\195\182scht werden!" | ||||
| L.Options_Title = "%s Einstellungen" | ||||
| L.Options_Enabled_Name = "Aktiv" | ||||
| L.Options_Enabled_Desc = "Aktiviert %s" | ||||
| L.Options_Minimap_Button_Name = "Zeige Minimap-Knopf" | ||||
| L.Options_Minimap_Button_Desc = "Zeigt oder versteckt den Knopf an der Miniaturkarte" | ||||
| L.Options_Minimap_Tooltip_Options_Left = "Linksklick" | ||||
| L.Options_Minimap_Tooltip_Options_Right = "\195\150ffnet oder schlie\195\159t die Einstellungen." | ||||
| L.Options_Minimap_Tooltip_Mappings_Left = "Rechtsklick" | ||||
| L.Options_Minimap_Tooltip_Mappings_Right = "\195\150ffnet das Debug-Fenster mit Ersetzungscode." | ||||
|  | ||||
| L.Options_Channels_Group_Name = "Kan\195\164le" | ||||
| L.Options_Channels_Group_Desc = "%s ist in folgenden Kan\195\164len aktiv." | ||||
| @@ -66,7 +74,7 @@ L.Options_Replacements_DeleteAll_Name = "Alle L\195\182schen" | ||||
| L.Options_Replacements_DeleteAll_Desc = "L\195\182scht alle Zuweisungen." | ||||
| L.Options_Replacements_DeleteAll_ConfirmText="Wirklich ALLE Zuweisungen l\195\182schen?" | ||||
| L.Options_Replacements_Header = "Die Vorkommen links vom Pfeil ( => ) werden in den aktivierten Kan\195\164len gesucht und durch den Text rechts vom Pfeil ersetzt." | ||||
|                                 .."|nWird die Gro\195\159- und Kleinschreibung ignoriert, wird die Gro\195\159schreibung jedes Zeichens wird bei der Ersetzung \195\188bernommen." | ||||
|                                 .."|nWird die Gro\195\159- und Kleinschreibung ignoriert, wird die Gro\195\159schreibung jedes Zeichens bei der Ersetzung \195\188bernommen." | ||||
|                                 .."|nDas Zusammenfassen aufeinanderfolgender Treffer vermeidet unsch\195\182ne Wiederholungen, die durch die Ersetzung entstehen k\195\182nnen." | ||||
|                                 .."|nMit den beiden Standard-Ersetzung wird so aus \"Tasse\" => \"Ckache\"." | ||||
| L.Options_Mapping_Group_Name = "%s => %s" | ||||
| @@ -76,9 +84,9 @@ L.Options_Mapping_SearchText_Name = "Suchtext:" | ||||
| L.Options_Mapping_SearchText_Desc = "Dieser Text wird in der Chateingabe gesucht." | ||||
| L.Options_Mapping_ReplaceText_Name = "Ersetzung:" | ||||
| L.Options_Mapping_ReplaceText_Desc = "Jeder Suchtreffer wird mit diesem Text ersetzt." | ||||
| L.Options_Mapping_ExactCase_Name = "exakte Gro\195\159- und Kleinschreibung" | ||||
| L.Options_Mapping_ExactCase_Name = "Exakte Gro\195\159- und Kleinschreibung" | ||||
| L.Options_Mapping_ExactCase_Desc = "Wenn gesetzt, muss die Gro\195\159- und Kleinschreibung des Suchtextes exakt \195\188berein stimmen. Anderfalls wird die Gro\195\159schreibung jedes Zeichens bei der Ersetzung \195\188bernommen." | ||||
| L.Options_Mapping_Consolidate_Name = "Fa\195\159e aufeinanderfolgende Treffer zusammen" | ||||
| L.Options_Mapping_Consolidate_Name = "Fasse aufeinanderfolgende Treffer zusammen" | ||||
| L.Options_Mapping_Consolidate_Desc = "Wenn durch die Ersetzung die Zeichenfolge mehrfach hintereinander steht,|nfasse sie zu einem Vorkommen zusammen." | ||||
| L.Options_Mapping_MoveUp_Name = "^" | ||||
| L.Options_Mapping_MoveUp_Desc = "nach oben verschieben" | ||||
|   | ||||
| @@ -7,9 +7,12 @@ L.VersionAbbr = "v" | ||||
| L.AddonLoaded = "%s now helps you with your spelling disabilities." | ||||
| L.Upgrade_ToVersion = "Upgrade database to version %s." | ||||
| L.Upgrade_Successful = "Upgrade successful." | ||||
| -- debug | ||||
| L.Debug_Options = "Options" | ||||
| L.Debug_Mappings = "Mappings" | ||||
| L.Debug_Mappings_Found = "%d Mappings found" | ||||
| L.Debug_Mappings_Hint = "The content of this input box is used for debugging purposes only and can be copied. No input from this box will be read or processed." | ||||
| L.Debug_Mappings_Found = "%d mappings found" | ||||
| L.Debug_Profile = "Profile" | ||||
|  | ||||
| -- profiles | ||||
| L.Profiles_Available = "Available profiles:" | ||||
| @@ -26,6 +29,13 @@ L.Profiles_DeleteError = "The active profile cannot be deleted!" | ||||
| L.Options_Title = "%s Options" | ||||
| L.Options_Enabled_Name = "Enabled" | ||||
| L.Options_Enabled_Desc = "Enables %s" | ||||
| L.Options_Minimap_Button_Name = "Show minimap button" | ||||
| L.Options_Minimap_Button_Desc = "Shows or hides the button on the minimap." | ||||
| L.Options_Minimap_Tooltip_Options_Left = "Left-Click" | ||||
| L.Options_Minimap_Tooltip_Options_Right = "Opens or closes the options UI." | ||||
| L.Options_Minimap_Tooltip_Mappings_Left = "Right-Click" | ||||
| L.Options_Minimap_Tooltip_Mappings_Right = "Opens the debug window with mapping code." | ||||
|  | ||||
|  | ||||
| L.Options_Channels_Group_Name = "Channels" | ||||
| L.Options_Channels_Group_Desc = "%s is active in the following channels." | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								twitch/minimap-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								twitch/minimap-icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
		Reference in New Issue
	
	Block a user