From 9cbd447881f30fc4422c07bd2547f1aff11e3144 Mon Sep 17 00:00:00 2001 From: rudaznoe Date: Sat, 4 Apr 2026 21:09:00 +0200 Subject: [PATCH 1/3] Add standalone InstanceJournal button with safe DFUI integration - Added standalone InstanceJournal button (non-intrusive) - Fixed micro menu stability issues - Restored correct icon behavior (PvP, EBC) - Removed redundant Reload Profile button - Improved overall UI consistency --- DragonflightUI-Reforged.toc | 2 + core/core.lua | 50 +- core/debug.lua | 146 +++ core/locale.lua | 848 ++++++++++++++++++ .../color_micro/instancejournal-faded.tga | Bin 0 -> 65580 bytes .../color_micro/instancejournal-highlight.tga | Bin 0 -> 65580 bytes .../color_micro/instancejournal-regular.tga | Bin 0 -> 65580 bytes modules/bars/bars.lua | 275 +++++- modules/gui/base.lua | 111 ++- modules/gui/elem.lua | 24 +- modules/gui/homeb.lua | 17 + modules/gui/info.lua | 4 +- modules/gui/mods.lua | 2 +- modules/gui/prof.lua | 75 +- modules/gui/shag.lua | 4 +- modules/gui/tools.lua | 158 +++- modules/micro/micro.lua | 71 ++ modules/track/track.lua | 31 + 18 files changed, 1701 insertions(+), 117 deletions(-) create mode 100644 core/debug.lua create mode 100644 core/locale.lua create mode 100644 media/tex/micromenu/color_micro/instancejournal-faded.tga create mode 100644 media/tex/micromenu/color_micro/instancejournal-highlight.tga create mode 100644 media/tex/micromenu/color_micro/instancejournal-regular.tga diff --git a/DragonflightUI-Reforged.toc b/DragonflightUI-Reforged.toc index 6e83475..4e6213d 100644 --- a/DragonflightUI-Reforged.toc +++ b/DragonflightUI-Reforged.toc @@ -9,6 +9,8 @@ # CORE core\error.lua core\core.lua +core\debug.lua +core\locale.lua core\tools.lua core\statusbar.lua core\compat.lua diff --git a/core/core.lua b/core/core.lua index 605bbc0..cde3958 100644 --- a/core/core.lua +++ b/core/core.lua @@ -18,6 +18,7 @@ DFRL.callbacks = {} DFRL.performance = {} DFRL.activeScripts = {} DFRL.gui = {} +DFRL.debug = {} -- db version DFRL.DBversion = "1.0" @@ -180,6 +181,9 @@ end function DFRL:SetTempDB(mod, key, value) self.tempDB[mod][key] = value + if self.DebugLog then + self:DebugLog('db', 'SetTempDB', mod, key, value) + end local cb = mod .. "_" .. key .. "_changed" self:TriggerCallback(cb, value) end @@ -234,6 +238,9 @@ end function DFRL:SwitchProfile(name) local char = UnitName("player") local old = DFRL_CUR_PROFILE[char] + if self.DebugLog then + self:DebugLog('profile', 'SwitchProfile', old or 'nil', '->', name or 'nil') + end DFRL_PROFILES[old] = self.tempDB DFRL_CUR_PROFILE[char] = name self:LoadProfile(name) @@ -256,6 +263,9 @@ function DFRL:CopyProfile(from, tbl) end function DFRL:LoadProfile(name) + if self.DebugLog then + self:DebugLog('profile', 'LoadProfile', name or 'nil') + end self.tempDB = {} for mod, data in pairs(DFRL_PROFILES[name]) do self.tempDB[mod] = {} @@ -278,6 +288,10 @@ function DFRL:NewCallbacks(mod, callbacks) self.callbacks[cb] = {} tinsert(self.callbacks[cb], func) + if self.DebugLog then + self:DebugLog('callback', 'Register', cb) + end + self:TriggerCallback(cb, self.tempDB[mod][key]) count = count + 1 @@ -285,19 +299,53 @@ function DFRL:NewCallbacks(mod, callbacks) end function DFRL:TriggerCallback(cb, value) + if not self.callbacks[cb] then return end + if self.DebugLog then + self:DebugLog('callback', 'Trigger', cb, value) + end for _, func in ipairs(self.callbacks[cb]) do func(value) end end function DFRL:TriggerAllCallbacks() - for cb, callbacks in pairs(self.callbacks) do + local ordered = {} + for cb in pairs(self.callbacks) do + tinsert(ordered, cb) + end + + table.sort(ordered, function(a, b) + local aGrid = string.find(a, 'Grid_changed$') ~= nil + local bGrid = string.find(b, 'Grid_changed$') ~= nil + if aGrid ~= bGrid then + return aGrid + end + + local aSpacing = string.find(a, 'Spacing_changed$') ~= nil + local bSpacing = string.find(b, 'Spacing_changed$') ~= nil + if aSpacing ~= bSpacing then + return not aSpacing + end + + return a < b + end) + + if self.DebugLog then + self:DebugLog('callback', 'TriggerAllCallbacks', table.getn(ordered)) + end + + for _, cb in ipairs(ordered) do + local callbacks = self.callbacks[cb] local name = string.gsub(cb, "_changed$", "") local pos = string.find(name, "_[^_]*$") local mod = string.sub(name, 1, pos - 1) local key = string.sub(name, pos + 1) local value = self.tempDB[mod] and self.tempDB[mod][key] + if self.DebugLog then + self:DebugLog('callback', 'TriggerAll', cb, value) + end + for _, func in ipairs(callbacks) do func(value) end diff --git a/core/debug.lua b/core/debug.lua new file mode 100644 index 0000000..3fd33d0 --- /dev/null +++ b/core/debug.lua @@ -0,0 +1,146 @@ +-- debug system +DFRL.debug.enabled = false +DFRL.debug.maxEntries = 250 +DFRL.debug.buffer = {} +DFRL.debug.categories = { + callback = true, + profile = true, + bars = true, + db = true, + gui = true +} + +local function dbg_tostring(value) + if value == nil then return 'nil' end + local kind = type(value) + if kind == 'boolean' then + return value and 'true' or 'false' + elseif kind == 'number' then + return string.format('%.3f', value) + elseif kind == 'string' then + return value + elseif kind == 'table' then + return '' + elseif kind == 'function' then + return '' + end + return tostring(value) +end + +local function dbg_echo(msg) + if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then + DEFAULT_CHAT_FRAME:AddMessage('|cff33ff99DFRL DEBUG:|r ' .. msg) + end +end + +function DFRL:DebugStatusText() + local state = self.debug.enabled and 'ON' or 'OFF' + return 'debug=' .. state .. ', entries=' .. table.getn(self.debug.buffer) +end + +function DFRL:SetDebugEnabled(enabled) + self.debug.enabled = enabled and true or false + if not DFRL_DB_SETUP then DFRL_DB_SETUP = {} end + DFRL_DB_SETUP.debugEnabled = self.debug.enabled + dbg_echo(self:DebugStatusText()) +end + +function DFRL:SetDebugCategory(category, enabled) + if not category or category == '' then return end + self.debug.categories[category] = enabled and true or false + dbg_echo(category .. '=' .. (enabled and 'ON' or 'OFF')) +end + +function DFRL:ClearDebugLog() + self.debug.buffer = {} + dbg_echo('buffer cleared') +end + +function DFRL:DumpDebugLog(limit, category) + local total = table.getn(self.debug.buffer) + if total == 0 then + dbg_echo('buffer empty') + return + end + + local count = tonumber(limit) or 20 + if count < 1 then count = 1 end + if count > total then count = total end + + local startIndex = total - count + 1 + for i = startIndex, total do + local entry = self.debug.buffer[i] + if not category or category == '' or entry.category == category then + dbg_echo(string.format('#%d [%s] %s', i, entry.category, entry.message)) + end + end +end + +function DFRL:DebugLog(category, ...) + category = category or 'misc' + if self.debug.categories[category] == false then + return + end + + local parts = {} + for i = 1, select('#', ...) do + parts[i] = dbg_tostring(select(i, ...)) + end + + local message = table.concat(parts, ' | ') + local stamp = date('%H:%M:%S') + local entry = { + time = stamp, + category = category, + message = stamp .. ' | ' .. message + } + + tinsert(self.debug.buffer, entry) + while table.getn(self.debug.buffer) > self.debug.maxEntries do + tremove(self.debug.buffer, 1) + end + + if self.debug.enabled then + dbg_echo('[' .. category .. '] ' .. entry.message) + end +end + +local function handle_debug_command(msg) + local _, _, command, arg1, arg2 = string.find(msg or '', '^(%S*)%s*(%S*)%s*(.-)$') + command = string.lower(command or '') + + if command == '' or command == 'help' then + dbg_echo('/dfrldebug on | off | status | clear') + dbg_echo('/dfrldebug dump [count] [category]') + dbg_echo('/dfrldebug cat ') + return + elseif command == 'on' then + DFRL:SetDebugEnabled(true) + elseif command == 'off' then + DFRL:SetDebugEnabled(false) + elseif command == 'status' then + dbg_echo(DFRL:DebugStatusText()) + elseif command == 'clear' then + DFRL:ClearDebugLog() + elseif command == 'dump' then + DFRL:DumpDebugLog(arg1, arg2) + elseif command == 'cat' then + DFRL:SetDebugCategory(arg1, string.lower(arg2 or '') == 'on') + else + dbg_echo('unknown command: ' .. command) + end +end + +_G['SLASH_DFRLDEBUG1'] = '/dfrldebug' +_G['SLASH_DFRLDEBUG2'] = '/dfdebug' +_G.SlashCmdList['DFRLDEBUG'] = handle_debug_command + +local debugBootstrap = CreateFrame('Frame') +debugBootstrap:RegisterEvent('PLAYER_LOGIN') +debugBootstrap:SetScript('OnEvent', function() + if DFRL_DB_SETUP and DFRL_DB_SETUP.debugEnabled then + DFRL.debug.enabled = true + dbg_echo(DFRL:DebugStatusText()) + end + DFRL:DebugLog('gui', 'Debug system ready') +end) diff --git a/core/locale.lua b/core/locale.lua new file mode 100644 index 0000000..067f929 --- /dev/null +++ b/core/locale.lua @@ -0,0 +1,848 @@ +DFRL.locale = DFRL.locale or {} +DFRL.locale.translations = DFRL.locale.translations or {} +DFRL.locale.configLabels = DFRL.locale.configLabels or {} +DFRL.locale.wordMap = DFRL.locale.wordMap or {} + +DFRL.locale.translations.frFR = { + ["5 = 2 columns x 5 rows"] = "5 = 2 colonnes x 5 lignes", + ["Actionbars"] = "Barres d'action", + ["Activate 2D class portrait icons"] = "Active les portraits de classe 2D", + ["Active Modules:"] = "Modules actifs :", + ["Active Scripts"] = "Scripts actifs", + ["Addon"] = "Addon", + ["Addon Manager"] = "Gestionnaire d'addons", + ["Addon Version:"] = "Version addon :", + ["Adjust dark mode intensity"] = "Ajuste l'intensite du mode sombre", + ["Adjust frame size"] = "Ajuste la taille du cadre", + ["Adjust party frame size"] = "Ajuste la taille du cadre de groupe", + ["Adjust pet frame size"] = "Ajuste la taille du cadre du familier", + ["Adjust range indicator opacity"] = "Ajuste l'opacite de l'indicateur de portee", + ["Adjust target of target frame size"] = "Ajuste la taille du cadre de la cible de la cible", + ["Adjust the maximum alpha of the combat pulsing"] = "Ajuste l'alpha maximal de la pulsation de combat", + ["Adjust the maximum alpha of the resting pulsing"] = "Ajuste l'alpha maximal de la pulsation de repos", + ["Adjust the speed of the combat pulsing"] = "Ajuste la vitesse de la pulsation de combat", + ["Adjust the speed of the resting pulsing"] = "Ajuste la vitesse de la pulsation de repos", + ["Adjust X offset of the tooltip"] = "Ajuste le decalage X de l'infobulle", + ["Adjust Y offset of the tooltip"] = "Ajuste le decalage Y de l'infobulle", + ["Adjusts background alpha of XP and reputation bars"] = "Adjusts background alpha of XP and reputation bars", + ["Adjusts font size of the time display"] = "Ajuste la taille de police de l'affichage de l'heure", + ["Adjusts font size of the zone text"] = "Ajuste la taille de police de le texte de zone", + ["Adjusts horizontal position of gryphon/wyvern decorations"] = "Ajuste la position horizontale de gryphon/wyvern decorations", + ["Adjusts horizontal position of keybind text"] = "Ajuste la position horizontale de keybind text", + ["Adjusts horizontal position of macro text"] = "Ajuste la position horizontale de macro text", + ["Adjusts horizontal position of paging buttons"] = "Ajuste la position horizontale de les boutons de pagination", + ["Adjusts horizontal position of the time display"] = "Ajuste la position horizontale de l'affichage de l'heure", + ["Adjusts horizontal position of the zone text"] = "Ajuste la position horizontale de le texte de zone", + ["Adjusts horizontal position of zoom buttons"] = "Ajuste la position horizontale de les boutons de zoom", + ["Adjusts scale of bottom left action bar"] = "Ajuste l'echelle de la barre d'action bas gauche", + ["Adjusts scale of bottom right action bar"] = "Ajuste l'echelle de la barre d'action bas droite", + ["Adjusts scale of left action bar"] = "Ajuste l'echelle de la barre d'action gauche", + ["Adjusts scale of right action bar"] = "Ajuste l'echelle de la barre d'action droite", + ["Adjusts size of zoom buttons"] = "Ajuste la taille de les boutons de zoom", + ["Adjusts spacing between bottom left action bar buttons"] = "Ajuste l'espacement entre bottom left action bar buttons", + ["Adjusts spacing between bottom right action bar buttons"] = "Ajuste l'espacement entre bottom right action bar buttons", + ["Adjusts spacing between left action bar buttons"] = "Ajuste l'espacement entre left action bar buttons", + ["Adjusts spacing between main action bar buttons"] = "Ajuste l'espacement entre main action bar buttons", + ["Adjusts spacing between micro menu buttons"] = "Ajuste l'espacement entre micro menu buttons", + ["Adjusts spacing between pet action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre du familier", + ["Adjusts spacing between right action bar buttons"] = "Ajuste l'espacement entre right action bar buttons", + ["Adjusts spacing between shapeshift buttons"] = "Ajuste l'espacement entre les boutons de metamorphose", + ["Adjusts the font size of the reputation bar text"] = "Ajuste la taille de police de the reputation bar text", + ["Adjusts the font size of the XP bar text"] = "Ajuste la taille de police de the XP bar text", + ["Adjusts the height of the reputation bar"] = "Ajuste la hauteur de la barre de reputation", + ["Adjusts the height of the top panel"] = "Ajuste la hauteur de le panneau superieur", + ["Adjusts the height of the XP bar"] = "Ajuste la hauteur de la barre d'XP", + ["Adjusts the overall size of the minimap"] = "Ajuste la taille generale de la mini-carte", + ["Adjusts the scale of the main action bar"] = "Ajuste l'echelle de la barre d'action principale", + ["Adjusts the scale of the main backpack"] = "Ajuste l'echelle de le sac principal", + ["Adjusts the scale of the micro menu"] = "Ajuste l'echelle de le micro-menu", + ["Adjusts the scale of the paging buttons"] = "Ajuste l'echelle de les boutons de pagination", + ["Adjusts the scale of the pet action bar"] = "Ajuste l'echelle de la barre d'actions du familier", + ["Adjusts the scale of the shapeshift bar"] = "Ajuste l'echelle de la barre de metamorphose", + ["Adjusts the size of keybind text on action buttons"] = "Ajuste la taille de le texte des raccourcis sur les boutons d'action", + ["Adjusts the size of macro text on action buttons"] = "Ajuste la taille de le texte des macros sur les boutons d'action", + ["Adjusts the size of the gryphon/wyvern decorations"] = "Ajuste la taille de les decorations gryphon/wyvern", + ["Adjusts the transparency of all bags"] = "Ajuste la transparence de tous les sacs", + ["Adjusts the transparency of the micro menu"] = "Ajuste la transparence de le micro-menu", + ["Adjusts the width of the reputation bar"] = "Ajuste la largeur de la barre de reputation", + ["Adjusts the width of the top panel"] = "Ajuste la largeur de le panneau superieur", + ["Adjusts the width of the XP bar"] = "Ajuste la largeur de la barre d'XP", + ["Adjusts transparency of bottom left action bar"] = "Ajuste la transparence de la barre d'action bas gauche", + ["Adjusts transparency of bottom right action bar"] = "Ajuste la transparence de la barre d'action bas droite", + ["Adjusts transparency of gryphon/wyvern decorations"] = "Ajuste la transparence de gryphon/wyvern decorations", + ["Adjusts transparency of left action bar"] = "Ajuste la transparence de la barre d'action gauche", + ["Adjusts transparency of main action bar"] = "Ajuste la transparence de la barre d'action principale", + ["Adjusts transparency of pet action bar"] = "Ajuste la transparence de la barre du familier", + ["Adjusts transparency of right action bar"] = "Ajuste la transparence de la barre d'action droite", + ["Adjusts transparency of shapeshift bar"] = "Ajuste la transparence de la barre de metamorphose", + ["Adjusts transparency of the entire minimap"] = "Ajuste la transparence de toute la mini-carte", + ["Adjusts transparency of the minimap shadow"] = "Ajuste la transparence de l'ombre de la mini-carte", + ["Adjusts transparency of the reputation bar"] = "Ajuste la transparence de la barre de reputation", + ["Adjusts transparency of the XP bar"] = "Ajuste la transparence de la barre d'XP", + ["Adjusts transparency of zoom buttons"] = "Ajuste la transparence de les boutons de zoom", + ["Adjusts vertical position of gryphon/wyvern decorations"] = "Ajuste la position verticale de gryphon/wyvern decorations", + ["Adjusts vertical position of keybind text"] = "Ajuste la position verticale de keybind text", + ["Adjusts vertical position of macro text"] = "Ajuste la position verticale de macro text", + ["Adjusts vertical position of the time display"] = "Ajuste la position verticale de l'affichage de l'heure", + ["Adjusts vertical position of the zone text"] = "Ajuste la position verticale de le texte de zone", + ["Adjusts vertical position of zoom buttons"] = "Ajuste la position verticale de les boutons de zoom", + ["appearance"] = "Apparence", + ["Appearance"] = "Apparence", + ["Automatically track reputation for factions you gain reputation with"] = "Suit automatiquement la reputation des factions avec lesquelles vous gagnez de la reputation", + ["bag basic"] = "Sacs", + ["Bags"] = "Sacs", + ["Bars"] = "Barres d'action", + ["boss"] = "boss", + ["BUG: blizzards highlight blinks at the wrong position - fix soon"] = "BUG : la surbrillance Blizzard clignote au mauvais endroit - correctif a venir", + ["Bug: move char after setting (unfixable)"] = "Bug : bouger le personnage apres reglage (non corrigible)", + ["BUG: slash commands not implemented yet - fix soon"] = "BUG : les commandes slash ne sont pas encore implementees - correctif a venir", + ["Build Number:"] = "Numero de build :", + ["Cast"] = "Barre de cast", + ["Castbar"] = "Barre de cast", + ["castbar Basic"] = "Castbar", + ["center"] = "centre", + ["CENTER"] = "CENTRE", + ["Change all fonts in the GUI"] = "Change toutes les polices de l'interface", + ["Change bag color"] = "Change la couleur des sacs", + ["Change bars color"] = "Change la couleur des barres", + ["Change cast color"] = "Change la couleur de la barre de cast", + ["Change castbar font size"] = "Change la taille de police de la barre de cast", + ["Change castbar font Y offset"] = "Change le decalage Y de la police de la barre de cast", + ["Change castbar height"] = "Change la hauteur de la barre de cast", + ["Change castbar width"] = "Change la largeur de la barre de cast", + ["Change casting time X offset"] = "Change le decalage X du temps d'incantation", + ["Change chat color"] = "Change la couleur du chat", + ["Change map color"] = "Change la couleur de la carte", + ["Change micro color"] = "Change la couleur du micro-menu", + ["Change mini color"] = "Change la couleur des mini-cadres", + ["Change player color"] = "Change la couleur du cadre joueur", + ["Change spell name X offset"] = "Change le decalage X du nom du sort", + ["Change spell text alignment"] = "Change l'alignement du texte du sort", + ["Change target color"] = "Change la couleur du cadre cible", + ["Change the font used for all smaller frames"] = "Change la police utilisee pour all smaller frames", + ["Change the font used for the castbar"] = "Change la police utilisee pour la barre de cast", + ["Change the font used for the experience and reputation bar"] = "Change la police utilisee pour les barres d'experience et de reputation", + ["Change the font used for the hotkeys and macros"] = "Change la police utilisee pour les raccourcis et macros", + ["Change the font used for the minimap"] = "Change la police utilisee pour la mini-carte", + ["Change the font used for the playerframe"] = "Change la police utilisee pour le cadre joueur", + ["Change the font used for the targetframe"] = "Change la police utilisee pour le cadre cible", + ["Change xprep color"] = "Change la couleur des barres XP/Reputation", + ["Changes take effect after reload:"] = "Les changements prennent effet apres rechargement :", + ["Changes the alpha of the side view"] = "Change la transparence du panneau lateral", + ["Changes the color of the close and min button"] = "Change la couleur des boutons Fermer/Mini", + ["Changes the color of the time on the home screen"] = "Change la couleur de l'heure sur l'ecran d'accueil", + ["Changes the colour of action button highlights"] = "Change la couleur de action button highlights", + ["Changes the colour of keybind text on action buttons"] = "Change la couleur de le texte des raccourcis sur les boutons d'action", + ["Changes the colour of macro text on action buttons"] = "Change la couleur de le texte des macros sur les boutons d'action", + ["Changes the colour of the resting glow animation"] = "Change la couleur de l'animation lumineuse de repos", + ["Changes the grid layout of bottom left action bar"] = "Change la disposition en grille de la barre d'action bas gauche", + ["Changes the grid layout of bottom right action bar"] = "Change la disposition en grille de la barre d'action bas droite", + ["Changes the grid layout of left action bar"] = "Change la disposition en grille de la barre d'action gauche", + ["Changes the grid layout of main action bar"] = "Change la disposition en grille de la barre d'action principale", + ["Changes the grid layout of pet action bar"] = "Change la disposition en grille de la barre du familier", + ["Changes the grid layout of right action bar"] = "Change la disposition en grille de la barre d'action droite", + ["Changes the scale of the mainframe"] = "Change l'echelle de la fenetre principale", + ["Changes the texture of the playerframe"] = "Change la texture de le cadre joueur", + ["Chat"] = "Chat", + ["chat basic"] = "Chat", + ["Client Version:"] = "Version client :", + ["close"] = "Fermer", + ["Collector"] = "Collecteur", + ["Color for cutout animation on all mini frames"] = "Couleur pour l'animation de decoupe sur tous les mini-cadres", + ["Color for damage cutout effect"] = "Couleur pour l'effet de decoupe des degats", + ["Color for pulse animation"] = "Couleur pour l'animation de pulsation", + ["Color for pulse animation on all mini frames"] = "Couleur pour l'animation de pulsation sur tous les mini-cadres", + ["Color health bar based on class"] = "Colore la barre de vie selon la classe", + ["Color health bar based on target class"] = "Colore la barre de vie selon la classe de la cible", + ["Color health bar based on target reaction"] = "Colore la barre de vie selon la reaction de la cible", + ["Color target of target and party health bars based on class"] = "Colore les barres de vie de la cible de la cible et du groupe selon la classe", + ["Color target of target health bars based on reaction"] = "Colore les barres de vie de la cible de la cible selon la reaction", + ["Color text based on health percentage"] = "Colore le texte selon le pourcentage de vie", + ["Color text based on health percentage from white to red"] = "Colore le texte selon le pourcentage de vie, du blanc au rouge", + ["Color text based on resource (mana/rage/energy) percentage"] = "Colore le texte selon le pourcentage de ressource (mana/rage/energie)", + ["Color text based on resource (mana/rage/energy) percentage from white to red"] = "Colore le texte selon le pourcentage de ressource (mana/rage/energie), du blanc au rouge", + ["Colorize the PizzaWorldBuffs Alliance/Horde text"] = "Colorise le texte Alliance/Horde de PizzaWorldBuffs", + ["Combat Effects"] = "Effets de combat", + ["Copy"] = "Copier", + ["Compact Horizontal"] = "Compact horizontal", + ["Compact Vertical"] = "Compact vertical", + ["Current profile reloaded"] = "Profil actuel recharge", + ["CURRENT PROFILE RELOADED"] = "PROFIL ACTUEL RECHARGE", + ["Custom"] = "Personnalise", + ["Choose how the pet bar grows when using a single row layout"] = "Choisit comment la barre du familier se deploie avec une disposition sur une seule ligne", + ["Default"] = "Defaut", + ["Grid 2x5"] = "Grille 2x5", + ["Horizontal"] = "Horizontal", + ["Reload Profile"] = "Recharger le profil", + ["Adjusts the size of pet action bar buttons"] = "Ajuste la taille des boutons de la barre du familier", + ["Adjusts the shine overlay of pet auto-cast visuals"] = "Ajuste la brillance de l'effet visuel d'auto-lancement du familier", + ["Adjusts the strength of the pet auto-cast glow"] = "Ajuste l'intensite de la lueur d'auto-lancement du familier", + ["Apply a quick preset for the pet bar"] = "Applique un preset rapide pour la barre du familier", + ["Vertical Down"] = "Vertical vers le bas", + ["Vertical Up"] = "Vertical vers le haut", + ["Vertical modes are especially useful for compact hunter layouts"] = "Les modes verticaux sont particulierement utiles pour les chasseurs avec une interface compacte", + ["Current"] = "Actuel", + ["CURRENT PROFILE RESET"] = "PROFIL ACTUEL REINITIALISE", + ["Dark Mode"] = "Mode sombre", + ["Database Version:"] = "Version base de donnees :", + ["Default"] = "Defaut", + ["Delete"] = "Supprimer", + ["deleted"] = "supprime", + ["dfrl evolved"] = "dfrl evolved", + ["dfrl nebula"] = "dfrl nebula", + ["Dragonflight Info"] = "Infos Dragonflight", + ["elite"] = "elite", + ["Enable combat pulse animation"] = "Active l'animation de pulsation en combat", + ["Enable cutout animation on bars"] = "Active cutout animation on bars", + ["Enable cutout animation on damage for all mini frames"] = "Active l'animation de decoupe sur les degats pour tous les mini-cadres", + ["Enable dark mode for the character panel"] = "Active le mode sombre pour la fiche du personnage", + ["Enable dark mode for the game menu"] = "Active le mode sombre pour le menu du jeu", + ["Enable dark mode for the questlog"] = "Active le mode sombre pour le journal de quetes", + ["Enable fade in/out animation"] = "Active l'animation de fondu entree/sortie", + ["Enable or disable addon modules. Changes require UI reload to take effect."] = "Active ou desactive les modules de l'addon. Rechargement de l'UI requis pour appliquer les changements.", + ["Enable pulse animation on bars"] = "Active l'animation de pulsation sur les barres", + ["Enable pulse animation on low health for all mini frames"] = "Active l'animation de pulsation a faible vie pour tous les mini-cadres", + ["Enable resting glow animation"] = "Active l'animation lumineuse de repos", + ["English"] = "Anglais", + ["enter profile name"] = "entrer le nom du profil", + ["Errors"] = "Erreurs", + ["Exit Game"] = "Quitter le jeu", + ["experience Bar"] = "Barre d'XP", + ["ext. PizzaWorldBuffs"] = "Ext. PizzaWorldBuffs", + ["Extended maximum camera distance"] = "Etend la distance maximale de la camera", + ["Fade out chat text after 10 seconds"] = "Fait disparaitre progressivement le texte du chat apres 10 secondes", + ["Flip the gryphon/wyvern textures"] = "Inverse les textures gryphon/wyvern", + ["font"] = "Police", + ["FPS:"] = "FPS :", + ["Francais"] = "Francais", + ["Français"] = "Francais", + ["GUI-Dragonflight"] = "Interface generale", + ["Health Bar"] = "Barre de vie", + ["Health Bars"] = "Barres de vie", + ["Health text font size"] = "Taille de police du texte de vie", + ["Health threshold for low HP warning"] = "Seuil de vie pour alerte de PV faibles", + ["Hide frame at full HP when not in combat"] = "Masque le cadre a PV pleins hors combat", + ["Hide party health and mana percent text"] = "Masque le pourcentage de vie et mana du groupe", + ["Hide pet health and mana percent text"] = "Masque le pourcentage de vie et mana du familier", + ["Hide target of target health and mana percent text"] = "Masque le pourcentage de vie et mana de la cible de la cible", + ["Hide the top UI error message (e.g. 'Spell is not ready')"] = "Masque le message d'erreur de l'UI en haut (ex. 'Le sort n'est pas pret')", + ["Home"] = "Accueil", + ["Home Screen"] = "Ecran d'accueil", + ["Info"] = "Infos", + ["Installed"] = "Installe", + ["Interface"] = "Interface", + ["Key Bindings"] = "Raccourcis clavier", + ["Last Update:"] = "Derniere mise a jour :", + ["left"] = "gauche", + ["LEFT"] = "GAUCHE", + ["Level text font size"] = "Taille de police du texte de niveau", + ["Light Mode"] = "Mode clair", + ["Locale:"] = "Langue :", + ["localization"] = "Langue", + ["Logout"] = "Deconnexion", + ["Macros"] = "Macros", + ["mainbar"] = "Barre principale", + ["mainbar deco"] = "Decors barre principale", + ["mainbar paging"] = "Pagination barre principale", + ["Mana text font size"] = "Taille de police du texte de mana", + ["Manage"] = "Gestion", + ["Map"] = "Mini-carte", + ["map basic"] = "Mini-carte", + ["map shadow"] = "Ombre mini-carte", + ["map zoom"] = "Zoom mini-carte", + ["MAX PROFILES REACHED"] = "LIMITE DE PROFILS ATTEINTE", + ["Memory (kb)"] = "Memoire (kb)", + ["Menu"] = "Menu", + ["Micro"] = "Micro-menu", + ["micro basic"] = "Micro-menu", + ["Micromenu"] = "Micro-menu", + ["min"] = "Mini", + ["Mini"] = "Mini-cadres", + ["mini text settings"] = "Texte mini-cadres", + ["Minimap"] = "Mini-carte", + ["Module"] = "Module", + ["Modules"] = "Modules", + ["multibar 1"] = "Multi-barre 1", + ["multibar 2"] = "Multi-barre 2", + ["multibar 3"] = "Multi-barre 3", + ["multibar 4"] = "Multi-barre 4", + ["Name text font size"] = "Taille de police du texte du nom", + ["Never"] = "Jamais", + ["New Profile"] = "Nouv. profil", + ["new profile created"] = "nouveau profil cree", + ["Not installed"] = "Non installe", + ["OFF"] = "OFF", + ["Okay"] = "OK", + ["ON"] = "ON", + ["Only for Blizzards version"] = "Uniquement pour la version Blizzard", + ["Options"] = "Options", + ["Party Text"] = "Texte groupe", + ["Performance"] = "Performance", + ["pet bar"] = "Barre du familier", + ["Pet Text"] = "Texte familier", + ["Player"] = "Joueur", + ["Profile"] = "Profil", + ["profile copied from"] = "profil copie depuis", + ["PROFILE RESET FAILED"] = "ECHEC DE LA REINITIALISATION", + ["profile saved"] = "profil sauvegarde", + ["Profiles"] = "Profils", + ["PVPIcon"] = "Icone JcJ", + ["RangeIndicator"] = "Indicateur de portee", + ["rare"] = "rare", + ["rare-elite"] = "rare-elite", + ["Realm:"] = "Royaume :", + ["Reload UI"] = "Recharger l'UI", + ["reputation Bar"] = "Barre de reputation", + ["Requires ShaguTweaks"] = "Necessite ShaguTweaks", + ["Reset"] = "Reinitialiser", + ["Resting Effects"] = "Effets de repos", + ["Resume Game"] = "Reprendre le jeu", + ["right"] = "droite", + ["RIGHT"] = "DROITE", + ["Save Profile"] = "Enregistrer le profil", + ["Script"] = "Script", + ["Select the language used in the configuration UI"] = "Choisit la langue utilisee dans l'interface de configuration", + ["Set fill direction"] = "Definit la direction de remplissage", + ["SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS"] = "SHAGU TWEAKS EXTRAS MANQUANT\nINSTALLE-LE POUR PLUS D'OPTIONS", + ["ShaguTweaks"] = "ShaguTweaks", + ["shapeshift bar"] = "Barre de metamorphose", + ["Show Blzzards sun/moon indicator"] = "Affiche l'indicateur soleil/lune de Blizzard", + ["Show casting spell icon"] = "Affiche l'icone du sort en cours d'incantation", + ["Show casting time"] = "Affiche le temps d'incantation", + ["Show drop shadow below the castbar"] = "Affiche l'ombre portee sous la barre de cast", + ["Show energy and mana tick indicators"] = "Affiche les indicateurs de ticks d'energie et de mana", + ["Show health and mana text"] = "Affiche le texte de vie et de mana", + ["Show max health and mana text"] = "Affiche le texte de vie et mana max", + ["Show nameplates only in combat"] = "Affiche les plaques de nom uniquement en combat", + ["Show only current values without percentages"] = "Affiche uniquement les valeurs actuelles sans pourcentages", + ["Show or hide bags on mouse hover"] = "Affiche ou masque les sacs au survol de la souris", + ["Show or hide bottom left action bar"] = "Affiche ou masque la barre d'action bas gauche", + ["Show or hide bottom right action bar"] = "Affiche ou masque la barre d'action bas droite", + ["Show or hide chat buttons"] = "Affiche ou masque les boutons du chat", + ["Show or hide free bag slots"] = "Affiche ou masque les emplacements de sac libres", + ["Show or hide keybind text on action buttons"] = "Affiche ou masque le texte des raccourcis sur les boutons d'action", + ["Show or hide left side action bar"] = "Affiche ou masque la barre d'action laterale gauche", + ["Show or hide macro text on action buttons"] = "Affiche ou masque le texte des macros sur les boutons d'action", + ["Show or hide main action bar background"] = "Affiche ou masque le fond de la barre d'action principale", + ["Show or hide reputation text on the reputation bar"] = "Affiche ou masque le texte de reputation sur la barre de reputation", + ["Show or hide right side action bar"] = "Affiche ou masque la barre d'action laterale droite", + ["Show or hide the action bar paging buttons"] = "Affiche ou masque les boutons de pagination de la barre d'action", + ["Show or hide the bag frame"] = "Affiche ou masque le cadre des sacs", + ["Show or hide the bag toggle button"] = "Affiche ou masque le bouton de bascule des sacs", + ["Show or hide the gryphon/wyvern decorations"] = "Affiche ou masque les decorations gryphon/wyvern", + ["Show or hide the shadow inside the minimap"] = "Affiche ou masque l'ombre a l'interieur de la mini-carte", + ["Show or hide the small bag slots"] = "Affiche ou masque les petits emplacements de sac", + ["Show or hide the time display on the minimap"] = "Affiche ou masque l'affichage de l'heure sur la mini-carte", + ["Show or hide the top information panel"] = "Affiche ou masque le panneau d'information superieur", + ["Show or hide the XP bar"] = "Affiche ou masque la barre d'XP", + ["Show or hide XP text on the XP bar"] = "Affiche ou masque le texte d'XP sur la barre d'XP", + ["Show or hide zoom buttons on the minimap"] = "Affiche ou masque les boutons de zoom sur la mini-carte", + ["Show party max health and mana text"] = "Affiche le texte de vie et mana max du groupe", + ["Show pet max health and mana text"] = "Affiche le texte de vie et mana max du familier", + ["Show pet/target of target/party health and mana text"] = "Affiche le texte de vie et mana du familier / cible de la cible / groupe", + ["Show red border when health is low"] = "Affiche la bordure rouge quand la vie est basse", + ["Show reputation text for 5 seconds when gaining reputation"] = "Affiche le texte de reputation pendant 5 secondes lors d'un gain de reputation", + ["Show reputation text when hovering over the reputation bar"] = "Affiche le texte de reputation au survol de la barre de reputation", + ["Show smaller FPS/MS watcher (CTRL+R)"] = "Affiche smaller FPS/MS watcher (CTRL+R)", + ["Show spell name text"] = "Affiche le texte du nom du sort", + ["Show target of target max health and mana text"] = "Affiche le texte de vie et mana max de la cible de la cible", + ["Show the Minimap Square design"] = "Affiche le design carre de la mini-carte", + ["Show the tooltip above your cursor"] = "Affiche l'infobulle au-dessus du curseur", + ["Show XP text for 5 seconds when gaining XP"] = "Affiche le texte d'XP pendant 5 secondes lors d'un gain d'XP", + ["Show XP text when hovering over the XP bar"] = "Affiche le texte d'XP au survol de la barre d'XP", + ["standard"] = "standard", + ["Status"] = "Statut", + ["Supported Addons"] = "Addons pris en charge", + ["Swap the anchorpoint of the paging buttons"] = "Inverse le point d'ancrage des boutons de pagination", + ["Switch"] = "Activer", + ["Switch between gray and colorfull micro menu"] = "Bascule entre le micro-menu gris ou colore", + ["switched to"] = "profil actif :", + ["System"] = "Systeme", + ["Target"] = "Cible", + ["Target level text font size"] = "Taille de police du texte de niveau de la cible", + ["Target name text font size"] = "Taille de police du nom de la cible", + ["Target of Target Text"] = "Texte cible de la cible", + ["Text"] = "Texte", + ["text settings"] = "Texte", + ["Third Party"] = "Tiers", + ["Time (ms)"] = "Temps (ms)", + ["Tooltip"] = "Infobulles", + ["top panel"] = "Panneau superieur", + ["top panel time"] = "Heure mini-carte", + ["top panel zone"] = "Texte de zone", + ["TOTAL:"] = "TOTAL :", + ["tweaks"] = "Ajustements", + ["Ui"] = "Interface", + ["ui tweaks"] = "Ajustements UI", + ["Unitframes"] = "Cadres d'unite", + ["UpdateNotifier"] = "Notifications de maj", + ["Usage:\n\n\n1) new profile: create and switch to a new profile\n\n2) switch: change active profile\n\n3) copy: copies all settings into active profile\n\n4) delete: delete profile and switch back to default\n\n5)reset: reset active profile to the default settings\n\n\ndoes not affect shagutweaks\n\nBUG: DOUBLE CLICK DELETE AFTER NEW PROFILE\n\nBUG: ENTER PROFILE NAME STAYS"] = "Utilisation :\n\n\n1) nouveau profil : cree et active un nouveau profil\n\n2) activer : change le profil actif\n\n3) copier : copie tous les reglages dans le profil actif\n\n4) supprimer : supprime le profil et revient sur Defaut\n\n5) reinitialiser : remet le profil actif aux reglages par defaut\n\n\nn'affecte pas ShaguTweaks\n\nBUG : double clic sur supprimer apres un nouveau profil\n\nBUG : le nom du profil reste affiche", + ["Use 12-hour AM/PM time format instead of 24-hour"] = "Utilise le format horaire 12h AM/PM au lieu du 24h", + ["Use dark color for PvP icons"] = "Utilise la couleur sombre pour les icones JcJ", + ["Use dark color instead of red"] = "Utilise la couleur sombre au lieu du rouge", + ["Use original Blizzard chat buttons"] = "Utilise les boutons de chat Blizzard d'origine", + ["Use simple X instead of texture"] = "Utilise un X simple au lieu d'une texture", + ["Use the alternative gryphon/wyvern textures"] = "Utilise les textures alternatives gryphon/wyvern", + ["Xprep"] = "XP/Reputation", + + ["Navigation"] = "Navigation", + ["Drag to move - ESC to close"] = "Glisser pour deplacer - ECHAP pour fermer", + ["Profiles help text"] = "Utilisation :\n\n1) Nouveau profil : creer et activer un nouveau profil\n2) Activer : changer le profil actif\n3) Copier : copier tous les reglages vers le profil actif\n4) Supprimer : supprimer le profil et revenir sur Defaut\n5) Reinitialiser : restaurer les reglages du profil actif\n\nRemarque : n'affecte pas ShaguTweaks.", + ["Quick Actions"] = "Actions rapides", + ["Save Profile"] = "Enregistrer le profil", + ["Reload Profile"] = "Recharger le profil", + ["New Profile"] = "Nouveau profil", + ["Delete"] = "Supprimer", + ["Switch"] = "Activer", + ["Copy"] = "Copier", + ["Reset"] = "Reinitialiser", + ["Adjusts background alpha of XP and reputation bars"] = "Ajuste l'alpha de fond des barres d'XP et de reputation", + ["Adjusts font size of the zone text"] = "Ajuste la taille de police du texte de zone", + ["Adjusts horizontal position of gryphon/wyvern decorations"] = "Ajuste la position horizontale des decorations gryphon/wyvern", + ["Adjusts horizontal position of keybind text"] = "Ajuste la position horizontale du texte des raccourcis", + ["Adjusts horizontal position of macro text"] = "Ajuste la position horizontale du texte des macros", + ["Adjusts horizontal position of paging buttons"] = "Ajuste la position horizontale des boutons de pagination", + ["Adjusts horizontal position of the zone text"] = "Ajuste la position horizontale du texte de zone", + ["Adjusts horizontal position of zoom buttons"] = "Ajuste la position horizontale des boutons de zoom", + ["Adjusts size of zoom buttons"] = "Ajuste la taille des boutons de zoom", + ["Adjusts spacing between bottom left action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action bas gauche", + ["Adjusts spacing between bottom right action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action bas droite", + ["Adjusts spacing between left action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action gauche", + ["Adjusts spacing between main action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action principale", + ["Adjusts spacing between micro menu buttons"] = "Ajuste l'espacement entre les boutons du micro-menu", + ["Adjusts spacing between right action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action droite", + ["Adjusts the font size of the reputation bar text"] = "Ajuste la taille de police du texte de la barre de reputation", + ["Adjusts the font size of the XP bar text"] = "Ajuste la taille de police du texte de la barre d'XP", + ["Adjusts the height of the top panel"] = "Ajuste la hauteur du panneau superieur", + ["Adjusts the scale of the main backpack"] = "Ajuste l'echelle du sac principal", + ["Adjusts the scale of the micro menu"] = "Ajuste l'echelle du micro-menu", + ["Adjusts the scale of the paging buttons"] = "Ajuste l'echelle des boutons de pagination", + ["Adjusts the size of keybind text on action buttons"] = "Ajuste la taille du texte des raccourcis sur les boutons d'action", + ["Adjusts the size of macro text on action buttons"] = "Ajuste la taille du texte des macros sur les boutons d'action", + ["Adjusts the size of the gryphon/wyvern decorations"] = "Ajuste la taille des decorations gryphon/wyvern", + ["Adjusts the transparency of the micro menu"] = "Ajuste la transparence du micro-menu", + ["Adjusts the width of the top panel"] = "Ajuste la largeur du panneau superieur", + ["Adjusts transparency of gryphon/wyvern decorations"] = "Ajuste la transparence des decorations gryphon/wyvern", + ["Adjusts transparency of zoom buttons"] = "Ajuste la transparence des boutons de zoom", + ["Adjusts vertical position of gryphon/wyvern decorations"] = "Ajuste la position verticale des decorations gryphon/wyvern", + ["Adjusts vertical position of keybind text"] = "Ajuste la position verticale du texte des raccourcis", + ["Adjusts vertical position of macro text"] = "Ajuste la position verticale du texte des macros", + ["Adjusts vertical position of the zone text"] = "Ajuste la position verticale du texte de zone", + ["Adjusts vertical position of zoom buttons"] = "Ajuste la position verticale des boutons de zoom", + ["Changes the colour of action button highlights"] = "Change la couleur de surbrillance des boutons d'action", + ["Changes the colour of keybind text on action buttons"] = "Change la couleur du texte des raccourcis sur les boutons d'action", + ["Changes the colour of macro text on action buttons"] = "Change la couleur du texte des macros sur les boutons d'action", + ["Changes the texture of the playerframe"] = "Change la texture du cadre joueur", + + ["Change the font used for all smaller frames"] = "Change la police utilisee pour tous les petits cadres", +} + +DFRL.locale.configLabels.frFR = { + ["Bags.bagAlpha"] = "Transparence sacs", + ["Bags.bagColor"] = "Couleur sacs", + ["Bags.bagDarkMode"] = "Mode sombre sacs", + ["Bags.bagScale"] = "Echelle sacs", + ["Bags.freeSlots"] = "Places libres", + ["Bags.hoverShow"] = "Afficher au survol", + ["Bags.showBags"] = "Afficher sacs", + ["Bags.showToggle"] = "Bouton sacs", + ["Bags.toggleBags"] = "Petits sacs", + ["barHeight"] = "Hauteur", + ["Bars.altGryphoon"] = "Textures alternatives gryphon", + ["Bars.barsColor"] = "Couleur des barres", + ["Bars.barsDarkMode"] = "Mode sombre barres", + ["Bars.flipGryphoon"] = "Inverser gryphon/wyvern", + ["Bars.gryphoonAlpha"] = "Transparence gryphon/wyvern", + ["Bars.gryphoonScale"] = "Taille gryphon/wyvern", + ["Bars.gryphoonX"] = "Position X gryphon/wyvern", + ["Bars.gryphoonY"] = "Position Y gryphon/wyvern", + ["Bars.highlightColor"] = "Couleur surbrillance", + ["Bars.hotkeyColour"] = "Couleur raccourcis", + ["Bars.hotkeyFont"] = "Police raccourcis", + ["Bars.hotkeyScale"] = "Taille raccourcis", + ["Bars.hotkeyShow"] = "Afficher raccourcis", + ["Bars.hotkeyX"] = "Position X raccourcis", + ["Bars.hotkeyY"] = "Position Y raccourcis", + ["Bars.macroColour"] = "Couleur macros", + ["Bars.macroScale"] = "Taille macros", + ["Bars.macroShow"] = "Afficher macros", + ["Bars.macroX"] = "Position X macros", + ["Bars.macroY"] = "Position Y macros", + ["Bars.mainBarAlpha"] = "Transparence barre principale", + ["Bars.mainBarBG"] = "Fond barre principale", + ["Bars.mainBarGrid"] = "Grille barre principale", + ["Bars.mainBarScale"] = "Echelle barre principale", + ["Bars.mainBarSpacing"] = "Espacement barre principale", + ["Bars.multiBarFourAlpha"] = "Transparence multi-barre 4", + ["Bars.multiBarFourGrid"] = "Grille multi-barre 4", + ["Bars.multiBarFourScale"] = "Echelle multi-barre 4", + ["Bars.multiBarFourShow"] = "Afficher multi-barre 4", + ["Bars.multiBarFourSpacing"] = "Espacement multi-barre 4", + ["Bars.multiBarOneAlpha"] = "Transparence multi-barre 1", + ["Bars.multiBarOneGrid"] = "Grille multi-barre 1", + ["Bars.multiBarOneScale"] = "Echelle multi-barre 1", + ["Bars.multiBarOneShow"] = "Afficher multi-barre 1", + ["Bars.multiBarOneSpacing"] = "Espacement multi-barre 1", + ["Bars.multiBarThreeAlpha"] = "Transparence multi-barre 3", + ["Bars.multiBarThreeGrid"] = "Grille multi-barre 3", + ["Bars.multiBarThreeScale"] = "Echelle multi-barre 3", + ["Bars.multiBarThreeShow"] = "Afficher multi-barre 3", + ["Bars.multiBarThreeSpacing"] = "Espacement multi-barre 3", + ["Bars.multiBarTwoAlpha"] = "Transparence multi-barre 2", + ["Bars.multiBarTwoGrid"] = "Grille multi-barre 2", + ["Bars.multiBarTwoScale"] = "Echelle multi-barre 2", + ["Bars.multiBarTwoShow"] = "Afficher multi-barre 2", + ["Bars.multiBarTwoSpacing"] = "Espacement multi-barre 2", + ["Bars.pagingScale"] = "Echelle pagination", + ["Bars.pagingShow"] = "Afficher pagination", + ["Bars.pagingSwap"] = "Inverser ancrage pagination", + ["Bars.pagingX"] = "Position X pagination", + ["Bars.petbarAlpha"] = "Transparence barre familier", + ["Bars.petbarGrid"] = "Grille barre familier", + ["Bars.petbarScale"] = "Echelle barre familier", + ["Bars.petbarSpacing"] = "Espacement barre familier", + ["Bars.petbarOrientation"] = "Orientation barre familier", + ["Bars.petbarButtonSize"] = "Taille boutons familier", + ["Bars.petbarPreset"] = "Preset barre familier", + ["Bars.petbarAutoCastAlpha"] = "Intensite glow auto-cast", + ["Bars.petbarShineAlpha"] = "Intensite shine auto-cast", + ["Bars.shapeshiftAlpha"] = "Transparence metamorphose", + ["Bars.shapeshiftScale"] = "Echelle metamorphose", + ["Bars.shapeshiftSpacing"] = "Espacement metamorphose", + ["Bars.showGryphoon"] = "Afficher gryphon/wyvern", + ["barWidth"] = "Largeur", + ["Cast.barHeight"] = "Hauteur castbar", + ["Cast.barWidth"] = "Largeur castbar", + ["Cast.castColor"] = "Couleur castbar", + ["Cast.castDarkMode"] = "Mode sombre castbar", + ["Cast.castFont"] = "Police castbar", + ["Cast.fontSize"] = "Taille police castbar", + ["Cast.fontY"] = "Position Y police", + ["Cast.setFillDirection"] = "Sens de remplissage", + ["Cast.showIcon"] = "Afficher icone", + ["Cast.showShadow"] = "Afficher ombre", + ["Cast.showSpell"] = "Afficher nom du sort", + ["Cast.showTime"] = "Afficher temps", + ["Cast.spellX"] = "Position X nom sort", + ["Cast.textAlign"] = "Alignement texte", + ["Cast.timeX"] = "Position X temps", + ["Chat.blizzardButtons"] = "Boutons Blizzard", + ["Chat.chatColor"] = "Couleur chat", + ["Chat.chatDarkMode"] = "Mode sombre chat", + ["Chat.fadeChat"] = "Fondu du chat", + ["Chat.showButtons"] = "Afficher boutons chat", + ["Collector.collectDarkMode"] = "Mode sombre collecte", + ["cutoutColor"] = "Couleur effet degats", + ["enableCutout"] = "Effet degats", + ["enablePulse"] = "Pulse", + ["Errors.hideErrors"] = "Masquer erreurs Lua", + ["fontSize"] = "Taille police", + ["frameScale"] = "Taille du cadre", + ["GUI-Dragonflight.globalFont"] = "Police globale", + ["GUI-Dragonflight.homeMinMaxColor"] = "Couleur Fermer/Mini", + ["GUI-Dragonflight.homeTimeColor"] = "Couleur horloge", + ["GUI-Dragonflight.language"] = "Langue", + ["GUI-Dragonflight.sideView"] = "Panneau lateral", + ["GUI-Dragonflight.smallerFrame"] = "Fenetre compacte", + ["Map.alphaShadow"] = "Transparence ombre", + ["Map.alphaZoom"] = "Transparence zoom", + ["Map.mapAlpha"] = "Transparence mini-carte", + ["Map.mapColor"] = "Couleur mini-carte", + ["Map.mapDarkMode"] = "Mode sombre mini-carte", + ["Map.mapShadow"] = "Afficher ombre", + ["Map.mapSize"] = "Taille mini-carte", + ["Map.mapSquare"] = "Style carre", + ["Map.mapTime"] = "Afficher heure", + ["Map.scaleZoom"] = "Taille zoom", + ["Map.showSunMoon"] = "Soleil/lune Blizzard", + ["Map.showTopPanel"] = "Afficher panneau haut", + ["Map.showZoom"] = "Afficher zoom", + ["Map.textColor"] = "Couleurs PizzaWB", + ["Map.timeFormat12h"] = "Format 12h", + ["Map.timeSize"] = "Taille heure", + ["Map.timeX"] = "Position X heure", + ["Map.timeY"] = "Position Y heure", + ["Map.topPanelFont"] = "Police mini-carte", + ["Map.topPanelHeight"] = "Hauteur panneau haut", + ["Map.topPanelWidth"] = "Largeur panneau haut", + ["Map.zoneTextSize"] = "Taille texte zone", + ["Map.zoneTextX"] = "Position X zone", + ["Map.zoneTextY"] = "Position Y zone", + ["Map.zoomX"] = "Position X zoom", + ["Map.zoomY"] = "Position Y zoom", + ["Micro.microAlpha"] = "Transparence micro-menu", + ["Micro.microColor"] = "Couleur micro-menu", + ["Micro.microDarkMode"] = "Mode sombre micro-menu", + ["Micro.microScale"] = "Echelle micro-menu", + ["Micro.microSpacing"] = "Espacement micro-menu", + ["Micro.smallFPS"] = "FPS/MS compacts", + ["Micro.switchColor"] = "Style gris/couleur", + ["Mini.colorClass"] = "Couleur par classe", + ["Mini.colorReaction"] = "Couleur par reaction", + ["Mini.cutoutColor"] = "Couleur effet degats", + ["Mini.enableCutout"] = "Effet degats", + ["Mini.enablePulse"] = "Pulse faible vie", + ["Mini.frameFont"] = "Police mini-cadres", + ["Mini.miniColor"] = "Couleur mini-cadres", + ["Mini.miniDarkMode"] = "Mode sombre mini-cadres", + ["Mini.miniPartyTextMaxShow"] = "Afficher max groupe", + ["Mini.miniPetTextMaxShow"] = "Afficher max familier", + ["Mini.miniTextShow"] = "Afficher texte vie/mana", + ["Mini.miniTotTextMaxShow"] = "Afficher max cible de cible", + ["Mini.noPartyPercent"] = "Masquer % groupe", + ["Mini.noPetPercent"] = "Masquer % familier", + ["Mini.noTotPercent"] = "Masquer % cible de cible", + ["Mini.partyFrameScale"] = "Taille cadre groupe", + ["Mini.petFrameScale"] = "Taille cadre familier", + ["Mini.pulseColor"] = "Couleur pulse", + ["Mini.totFrameScale"] = "Taille cadre cible de cible", + ["noPercent"] = "Masquer pourcentages", + ["Player.classColor"] = "Vie selon classe", + ["Player.classPortrait"] = "Portraits de classe 2D", + ["Player.combatGlow"] = "Pulse combat", + ["Player.cutoutColor"] = "Couleur effet degats", + ["Player.eliteBorder"] = "Texture du cadre", + ["Player.enableCutout"] = "Effet degats", + ["Player.enablePulse"] = "Pulse barres", + ["Player.energyTick"] = "Ticks energie/mana", + ["Player.frameFont"] = "Police joueur", + ["Player.frameHide"] = "Masquer a PV pleins", + ["Player.frameScale"] = "Taille du cadre", + ["Player.glowAlpha"] = "Alpha pulse combat", + ["Player.glowSpeed"] = "Vitesse pulse combat", + ["Player.healthSize"] = "Taille texte vie", + ["Player.levelSize"] = "Taille niveau", + ["Player.manaSize"] = "Taille texte mana", + ["Player.nameSize"] = "Taille nom", + ["Player.noPercent"] = "Masquer pourcentages", + ["Player.playerColor"] = "Couleur joueur", + ["Player.playerDarkMode"] = "Mode sombre joueur", + ["Player.pulseColor"] = "Couleur pulse", + ["Player.restingAlpha"] = "Alpha repos", + ["Player.restingColor"] = "Couleur repos", + ["Player.restingGlow"] = "Lueur repos", + ["Player.restingSpeed"] = "Vitesse repos", + ["Player.textColoringHealth"] = "Texte selon vie", + ["Player.textColoringResource"] = "Texte selon ressource", + ["Player.textMaxShow"] = "Afficher valeurs max", + ["Player.textShow"] = "Afficher texte vie/mana", + ["pulseColor"] = "Couleur pulse", + ["PVPIcon.pvpDark"] = "Icnes JcJ sombres", + ["RangeIndicator.indicatorAlpha"] = "Opacite indicateur", + ["RangeIndicator.indicatorDark"] = "Couleur sombre", + ["RangeIndicator.indicatorFade"] = "Fondu animation", + ["RangeIndicator.indicatorSimple"] = "X simple", + ["Target.colorClass"] = "Vie selon classe", + ["Target.colorReaction"] = "Vie selon reaction", + ["Target.cutoutColor"] = "Couleur effet degats", + ["Target.enableCutout"] = "Effet degats", + ["Target.enablePulse"] = "Pulse barres", + ["Target.frameFont"] = "Police cible", + ["Target.frameScale"] = "Taille du cadre", + ["Target.healthSize"] = "Taille texte vie", + ["Target.levelSize"] = "Taille niveau cible", + ["Target.manaSize"] = "Taille texte mana", + ["Target.nameSize"] = "Taille nom cible", + ["Target.noPercent"] = "Masquer pourcentages", + ["Target.pulseColor"] = "Couleur pulse", + ["Target.targetColor"] = "Couleur cible", + ["Target.targetDarkMode"] = "Mode sombre cible", + ["Target.textColoringHealth"] = "Texte selon vie", + ["Target.textColoringResource"] = "Texte selon ressource", + ["Target.textMaxShow"] = "Afficher valeurs max", + ["Target.textShow"] = "Afficher texte vie/mana", + ["textMaxShow"] = "Afficher valeurs max", + ["textShow"] = "Afficher texte", + ["Tooltip.toolTipMouse"] = "Infobulle au curseur", + ["Tooltip.toolTipX"] = "Decalage X infobulle", + ["Tooltip.toolTipY"] = "Decalage Y infobulle", + ["Ui.cameraDistanceFactor"] = "Distance camera max", + ["Ui.characterPanel"] = "Fiche personnage", + ["Ui.gameMenu"] = "Menu du jeu", + ["Ui.hideErrorMessage"] = "Masquer message d'erreur", + ["Ui.lowHpThreshold"] = "Seuil PV faibles", + ["Ui.lowHpWarn"] = "Alerte PV faibles", + ["Ui.questLog"] = "Journal de quetes", + ["Ui.showPlates"] = "Plaques de nom en combat", + ["Xprep.autoTrack"] = "Suivi auto reputation", + ["Xprep.barFont"] = "Police XP/Rep", + ["Xprep.bgAlpha"] = "Alpha du fond", + ["Xprep.hoverRep"] = "Texte rep au survol", + ["Xprep.hoverXP"] = "Texte XP au survol", + ["Xprep.repBarAlpha"] = "Transparence barre rep", + ["Xprep.repBarHeight"] = "Hauteur barre rep", + ["Xprep.repBarTextSize"] = "Taille texte rep", + ["Xprep.repBarWidth"] = "Largeur barre rep", + ["Xprep.showRepOnGain"] = "Texte rep au gain", + ["Xprep.showRepText"] = "Afficher texte reputation", + ["Xprep.showXpBar"] = "Afficher barre XP", + ["Xprep.showXpOnGain"] = "Texte XP au gain", + ["Xprep.showXpText"] = "Afficher texte XP", + ["Xprep.xpBarAlpha"] = "Transparence barre XP", + ["Xprep.xpBarHeight"] = "Hauteur barre XP", + ["Xprep.xpBarTextSize"] = "Taille texte XP", + ["Xprep.xpBarWidth"] = "Largeur barre XP", + ["Xprep.xprepColor"] = "Couleur XP/Rep", + ["Xprep.xprepDarkMode"] = "Mode sombre XP/Rep", +} + +DFRL.locale.wordMap.frFR = { + ["alpha"] = "alpha", + ["bag"] = "sac", + ["bags"] = "sacs", + ["bar"] = "barre", + ["bars"] = "barres", + ["bg"] = "fond", + ["camera"] = "camera", + ["cast"] = "cast", + ["chat"] = "chat", + ["class"] = "classe", + ["color"] = "couleur", + ["colour"] = "couleur", + ["combat"] = "combat", + ["cutout"] = "decoupe", + ["dark"] = "sombre", + ["distance"] = "distance", + ["energy"] = "energie", + ["error"] = "erreur", + ["fade"] = "fondu", + ["font"] = "police", + ["fps"] = "fps", + ["frame"] = "cadre", + ["free"] = "libres", + ["glow"] = "lueur", + ["grid"] = "grille", + ["health"] = "vie", + ["hide"] = "masquer", + ["hotkey"] = "raccourcis", + ["icon"] = "icone", + ["indicator"] = "indicateur", + ["language"] = "langue", + ["level"] = "niveau", + ["macro"] = "macro", + ["mana"] = "mana", + ["map"] = "carte", + ["micro"] = "micro", + ["mini"] = "mini", + ["mode"] = "mode", + ["name"] = "nom", + ["panel"] = "panneau", + ["party"] = "groupe", + ["pet"] = "familier", + ["player"] = "joueur", + ["profile"] = "profil", + ["profiles"] = "profils", + ["pulse"] = "pulse", + ["pvp"] = "jcj", + ["quest"] = "quete", + ["reaction"] = "reaction", + ["rep"] = "rep", + ["resting"] = "repos", + ["scale"] = "echelle", + ["shadow"] = "ombre", + ["show"] = "afficher", + ["size"] = "taille", + ["slots"] = "emplacements", + ["spacing"] = "espacement", + ["target"] = "cible", + ["text"] = "texte", + ["threshold"] = "seuil", + ["time"] = "temps", + ["toggle"] = "bascule", + ["tooltip"] = "infobulle", + ["tot"] = "cible", + ["transparency"] = "transparence", + ["ui"] = "ui", + ["warn"] = "alerte", + ["width"] = "largeur", + ["x"] = "X", + ["xp"] = "XP", + ["y"] = "Y", + ["zoom"] = "zoom", +} + +function DFRL:GetLanguage() + local language = nil + if self.tempDB and self.tempDB["GUI-Dragonflight"] and self.tempDB["GUI-Dragonflight"].language then + language = self.tempDB["GUI-Dragonflight"].language + end + + if not language or language == "" then + if GetLocale and GetLocale() == "frFR" then + return "Francais" + end + return "English" + end + + return language +end + +function DFRL:IsFrench() + local language = self:GetLanguage() + return language == "Francais" or language == "Français" or language == "frFR" or language == "fr" +end + +function DFRL:TR(text) + if text == nil then return text end + if not self:IsFrench() then return text end + + local tbl = self.locale and self.locale.translations and self.locale.translations.frFR + if not tbl then return text end + return tbl[text] or text +end + +function DFRL:HumanizeKey(key) + if not key then return "" end + local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") + displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + return displayTxt +end + +function DFRL:TranslateWords(text) + if not text or text == "" then return text end + local map = self.locale and self.locale.wordMap and self.locale.wordMap.frFR + if not map then return text end + + local result = {} + for token in string.gfind(text, "%S+") do + local core = string.gsub(token, "([%.,:;!%?])$", "") + local _, _, punct = string.find(token, "([%.,:;!%?])$") + local lookup = string.lower(core or token) + local translated = map[lookup] or core + table.insert(result, translated .. (punct or "")) + end + return table.concat(result, " ") +end + +function DFRL:GetOptionLabel(moduleName, key) + local fallback = self:HumanizeKey(key) + if not self:IsFrench() then + return fallback + end + + local tbl = self.locale and self.locale.configLabels and self.locale.configLabels.frFR + if tbl then + local exactKey = (moduleName and key) and (moduleName .. "." .. key) or nil + if exactKey and tbl[exactKey] then + return tbl[exactKey] + end + if tbl[key] then + return tbl[key] + end + end + + local translated = self:TR(fallback) + if translated ~= fallback then + return translated + end + + return self:TranslateWords(fallback) +end + +function DFRL:DisplayProfileName(name) + if not name then return "" end + if name == "Default" then + return self:TR("Default") + end + return name +end diff --git a/media/tex/micromenu/color_micro/instancejournal-faded.tga b/media/tex/micromenu/color_micro/instancejournal-faded.tga new file mode 100644 index 0000000000000000000000000000000000000000..4c4489c21b419d838e2a05eda1e8c1ea6235a0fa GIT binary patch literal 65580 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 VcH6qG`u}qwPD=m) literal 0 HcmV?d00001 diff --git a/media/tex/micromenu/color_micro/instancejournal-highlight.tga b/media/tex/micromenu/color_micro/instancejournal-highlight.tga new file mode 100644 index 0000000000000000000000000000000000000000..639bd52be6e3176e10321d8b179b79022f053f42 GIT binary patch literal 65580 zcmeHQ2UJzZ+P&Ng(h(8C4%mB3)YxL|U2IXKSWr|zDHc=|6|q-TRK(a~?>)w+i7{%5 z`s^|4izU81yT%e@%KrC9I9cbJi(d1;^<3*Qv({cS_uMn*%-Q>!Z@!s17YqiYK}$)7 zBtv0m?UTwC1BwB~fMP%~pcqgLCzkg%Cwv6M}i)0OEzo-t*~?y|8i)_)^b>R({E2 z%TJg?iBuwkNPA64=Y8i9VT75mo3v-jF1K4L2OYG>%L^XgiQmN$`-t7dW@5{K8C$dN z_W|=2#5N*~u$$~XpZ=KLN;&ADo(rw~g2(U2@0Jh~h%v-iVq8`(xbs*f5ktI9)FSE-b+aJlm%-k-a_nXG zwC}ZZYqL%bq7^ZVSWmo9tRW%@EAdCN_k8+ef1H>@3wkcJ@^e&(_K8F+A-dNmM3cHY zXrJ|3W%s@QxRkZJ`s4cR=*!yq(uSH@n894Mmsn&6(TDgWY0s2h{>OoGj*BiV zOS~sOw<%GT5bnhWUMDK@{(=TXT|(Nngb*8epIA$@Bb>Bn$}Z3>a#7DOweInkI9|196tCB$~5k5(t%B&rco|Nm=0nhnT(q%94J z*@VP|s|cAJ`rCUx{V|@Cqm!NstxQ646Kx66Ui_?RrS4R+uu?;z2t|#^)cVs#4g1K1e%YEW_c$ug9xnC9eUJ7O}Fy=OMm`N`;%|1v*+!mw*AzuQc#AQs4ZL^6?>1N) zLE;Ya9es&#LhLO}2eFTiL_4AdA!CWe9pWdXT}pqF;7HQzu9aEudHp4B6Mm&nN}nA} ztTtOp-?ce~!8Laj-0}~Ev#l?zhEA{;+7Qi&hOijxJ+oM<-#1%JUpHBbo;Mo3k8`>H z0PBm5d_XKBW)ZWAiNqKpfslJ>{zJ>fUbM21V>VaGqwi6o2e&h=q5_2;}eC3;BBWfp5zQc)v9OUX`NY5ki{?h=QwEBwQ?! za5fBp%@6^bQ+HTR?O-)GfW=bvso7HY0k3t-WG?tmqbbh?C!^~zUVjgz?uFrYCUjJ(RT$gA^NFSSIF}?BF*(DnJx7^uTcO@?^NT<(_W^LR(mo7Pw2OYUi*6iC+QVXM{hQ6D5p1qC zf3Z4OeL}nVl5LV0G>VY%NqmFSpCmYv^tx+h*3;`RaerMx##o8Z)2-IGk;|(ud}{PU zp89>^Rk1fbgSu0*j>zTF0iH#=!nbB0Y$Ada#vo*PGKvkG zfD(g=xD*tR;b$Twb{vA@#vph|676F&iVjUc!I)SCM2NrXhrq7Ak*8K)-fIZkFp{YA zE88@WkhnzCU-f^I;YiZ!u9aCYJN?D~FSgj)!0a*`W?KTRE*!gEBVchJ3Zrd2kxYz% z*?9yk);RiXen%UzIEBLI*$!?&9pPQAJN#Qlp-><31LII^#AK8hHJv_UIzr;7AY{-4 z1V@iYaO7A7^`mbHk4OHf5eOKQihL7hqCor@`kA4ySx3RQC_a27AgU2Fx^i;-@Q&E_Hp&<1S z8ZZilW5&Zjej);AeSp9rX>iV!0B0B4pL6i{Y_G(C(*I@6QjPy4!O^7GT`RM0cKS>I zpJsM${K)LJ3?^6V?-oN0fW>tfKPMC8vvMhGm;j?IZNYU4F*UQCX(#3c+CntZopD`T z`iItV4QdCk+TGyWE)xFzha&%w5wwY6C>}qWv1S?qW-Nn$)Etg8!{OpS6c$^dt89~K zuJk7fubMQ?^*OJh*S{)1%i3RCLi8VFw$-|2_FheWC$jIe|8p*9aZTXo6k#&WzE$+;gjb&7!1+6k_HZQ)tAJv?f6 zLEg^&5j-v(h32kBo}M!}rVQs85YIY+U$afJ<|q0~jH2d$B*D?7*Ig^K?(_O<^M8r| zhM3G{zA<~Rp{_Hje;oCXqW&YO6!U)EgJ>cpSjsmgi2wJiMzMW_@hLOnS zIf&=vJIOZ5+)wnEIf~MsBsiKh&Gk9!>h-U}&ozlwgzVEqIhhK4Y4u$Li)T8=|H0IM zAS`Z)Fu767KQNWr&VZA74xBiD_iGS=0)5B8w|xwJTJ}TkI^AJ*>ji^xGS8cpRc{8& z9;v+Ue3)qiW}gpW@!LgPm=70oI0E|3L#g#U;n#5LO?ElmtS`ae-k90ET{?z8T3Krj$nd81KQ~y!aapvz@O71b2+NZIf zkD&jKL8S?+@b>IIsFAWB<%ca{TsIkc+eR~9On{Sh{_l0&X0To=%+%lFl};>xCC?_> z)@N1!0=lXrvPPx!Ckc)wO>=$Dx-Zn;@5@}5Uzz{#0oxgYlj8bzYg#C2%1?j#y6IfOcC`%rKG$EcmQA8j_CLd~hW z5EwQJE`bsY&dxY$@t+e@!fLoDc^wkqMJ~IaN>7y>s3clYQ%ER{fAJ`p>T3tLEY0c zuOrtITeA3V;aH!7yp<=S>XHMfzUd(HwOr5hr*Q4}J@9=4S?kgCmpO{+|0KcDq}N?5 zv+ncySL3n9L{~z%PPcgW``JDC9LMMx)IXj+fa^Y- z{QeO%Tlxi>>d<)cVYJ_L28|beh60hZxj!g#g0Y+ftjp9rb3E``oaz6?*XOG_12tA2 z!CPAnA)w_}o;!a2jn`ZoQi2_2Gf&SNLSXcO$Qrhyo4L(PY%Uzjm`Qa~+Y#?;_#CkBC0-J-Tc-Pa8Oo-n*|M;_NMyAHIb1#uWPfZLsE9Pi%rUujoGl z!J(_r;oxPo+I<$jZ|&kS&JoQue_~rQ2w9hucFFr+g9)WSNpK`-n(K4cdtU!aJSOh| zv?GLP#@H^0y^DVgkDvpL{l@d1jA^hIONLMKHZ)sy65TeP!+`zYVffK|7<%Lm;y$~D zA~740`<*GMJai>`e)uiozr2mUA6`f2J(mzNX&DSIG1PSvZ29-F-;4INgUtRv3?;g( zMVBwHBXsvS@U6NhQ-71W;zPD2jgWl_v4NI^(w`(an)JGBW!7~-f5XRK!JFY#>?qf3 zxsEUExW%TU^WjTKJpB}d58uJS!w*nq5&iyw3s`U)2#J_Z-MSKk;ol(@F&FM4>F7f= zO#cjqHZ$PWb{d=mxo@0nD{bH-SOe%={5NNwUm<)m!q44C$K4m4T%2ngzEn!!I7kCuFqM|p8oP~y^OCC|HlwpJqj;}cZsvqe>$vQsf^vHpjE~` zB;WWMv415?v0p#N*l(U;_@Ucql=cO3 z$FGHFw=r<`9m&1H-L!%Iu;r7v-e6RV+<~ZXAE49Di|{J*5sz`L$W-DM+adbPy0p@t zB)n?U>#mh~4SV{_Z);=^NVt~$w&mW1CjC;d>US`ErNPB_7ByJ~?^+q?dG<2OjN1W2 z{t0~NV=0esf>+f=NV@a@W&6)TuD+8n@Z67hW9C;Vp1cNe=k8$2`Crj<#}!nXycPbf z`L4JZ<4M0S;2f}<^%GDdb~grIxsP`lM|g%%f74?2|KJ;JM`~7^l>Q{*Rgt;T z$R2>K0gL|A-TgY>tlaD&T>Mwl|IdUia3{6eiTtfsqUMqP7@1Id)|7a-UkNly9uAvV=&g9#`g=i^1a`K{GRKHN&Ap+ z>k&Gw`3BAf_QJ_!5%mwaz;+}NVTAlHttp}OCkc)wO>=$Dy7v0N=r8=r8ldPu$;Gq& zlJE;Lzvl>2|jF^FS#%HQu}%Gsx= zHHm9D6~bZ3D}I9UylEkZ96X0+AKikX|2o);q;fs!D7=C{<@ck|WWuKyeg6qMF24Ya z|2~*q8ULB`iT-1WFhcYf`&9aq1V@uzcdg92_VkxMAlUk zi~;7r7O)jgUMFBEyZ{|{9!A>tz_`PCUS5t_!|BgK>U` z;V@So4TEJ8N)OwJkS!FzoP6Bz|!VqdDInMT|Id0~60YqD}mauni{>oVW^s(P=0&buU~7 ztj^r`HTiRGvDj(kF7dnmEvJ2f@lT#2G~)uyz6W6QNTdJvJ;rv(yPu-Jj7zdd8B3_~ zpCmYv^tx+h*0b0DMgRIldtv|~>#RE~HavuU6)({5&!_+2&VKw6+G%&A ze&jZ_zl||p-ND$e?y`J`HgJbFKzrcYQ0k?hG4ALcjQjE?sw_VTLp|;xx$T9y&>6TE zJI8&08UK^fdgd`q{OL!uU3d}3+y~(7F^7Bq-k-A#vfd;5%eW-|N$F1#98H?$`kZy` z_5Uh7{x;E$koT>G_sw|pz_m!FKRNhINw2$B=7sF_|H?dGmyk6e*=vx1T< zH~w0?0pI%O~$+6#c+RLUKVOk;FZL z`4=9c+~SikG~nFN>k}9YoabKPCHR))8j>j$otK@*v}Zq}^_*{E@HoW&FZ)EsPuK?W zL#qFigujwB&Gk92lb!yu1}J+hvfn1Zy-)AjchyfFqWMSUElasxzn1f|Jt!Qu4*kBp zhW9T&!@_eM=g<6rRATa}`xr|fFq%F=G#5yD9Oncpu02D84VPhPG?)87n_(_|72f5p zAWx|yw5Z*chY2&Nzmfa(dAJS~a1vgDAEV@ijp+034J`b}Q!Kmi7<11)#8mou ziT%eOzn`hO=suQ6p^sSc-OuQ?k8{5cX|VaPK(3(g;aBN8e2X9EyWtt=z40oh|MVCw zrcr;_6C5MrMgJ{CG$FCS>`hC2s`MubjwVfWea^bs=`Zhr%N$$$t?U6LhrT=h#>P*m zzZd88HolXQ{~!uhxQQC|51`tNE$DvfIu>7lhKz3>VbsN$- z^e-49xd%{T1w4veMS&VO;Tu9<&)9cEAENoB?|7dR{O!O1(SI$W^d|{_HR*NN z%Dh%~`pbL3GRKnsCi*A%1=c^c=>X6s{2$!^N#mOBZn%}YjK&@Ap?-r;P&H{AQXW6V zswcpLi;s}TJ)fCpA7MH%>+2_&^UaUUA9F5n3tc|DfjX-`g-^NFa4mWbh3no%K$#<4 zTV9Ir?N>4F(S5X>{5|h+n)>(omG@sk$XbNV{bXMH4x#!#NpLi2n(K4c%}#%r1Bj2+ z)_^1i+|{uCe$3khw2uOs^Z>#VfJVI@p;Vn)@GW=*Rr~M6=riY$`s00!x%~siUVDrQ zm!4qEnR^&@<}L=ExsA}zFQWCXgQ(VH1J@Ie!K2J~C{p((@|OA%Hs4j~vy1vaxPumx zIoGg0=6hztr2j7^A_>u7-c3>ZlZ01Edfl}$>u0CG%mE|@lr?~UL_9H>e{%hc;+2w~ z)@ruq*V>JyKMCu<{+H3SfYh}>_c)FX?nhxL_#ujSK7`6idr@QYUesE*A63?Ug32rR zqvDip2zqZDyvy(4J3mK}yCVI5#mgvC=O(<1973)F>k)nU7G^wrh8E*?KW4ah%gI{) z4)48$5dCHDFKv?fsp|hE!O^5?uFqNbMfz9g_Ywn!5i<6Q4agd-^u;yA5@LDYeC3Y! zA2jdjn(YrksnIhYFnV2JpWV;70^jKm+6ZU9$73qZJ%ila`I~`b{5`=<KI6iU=1l>Q{a(WKX1E3@v4 z^w-7!>2F#bIGAM_3&a+Lf6-(#kzuyvIn*;^%A*at?qT;4U|RQv{57s2;Eijj)aE{lR6YuqLYsf9GhxmBuJ5mTR<1?YA9&q~ zL@z?_D{GPM2$`3PZ&Lb`1V@vmxjtvz7wIo!fW(2a)~eZntOtn>5{t>&pyXl$f&^j# z_X_qkZ8`92#)=b2TlE`arvP=k{KUR~4bCMl^Y4FMK|X3;sMdEVT>Con>!{Z82b8FD zj=u+4$G;m_^Bk|UhuBPvA;j;C4T$e=N=SQZ5lVlO;Aqn8u9aC=^cQVqJw^1cl$A?a zLp7FVylp{*5)yyO99-&&KkiA0Eyx(5jT55VDsSJQV+~tPdXzl(31+VZqUaOeY%<+`VnFSnome%c`5%q|B3Q%Cfo}j{56u& zfS9SAL&W}u>YeVQM3WnMr_Yb5(vtIiSN@*F$xqW?`h9Og`n|l5R+A`CNZ(iblZ01E zdfl}$>pQByW(SgsEoi9Day>%qpba5*5Jt%FbY#6&>_GbPcw#QG$G^zC*P3?P{&W1q zCm6MWK7r#y-wD859XQ{2=DXnr579rK5Fa4dlXWP$humA~PZIu0(lpoSyv|?IUvCRq zxhk(EeNy~_HcoV9Ih+t32WI7(Eu@<)0iP5t+51N0&Zm%+0W=Ng{Lws}`e**mOYBC| zU&bEoK1zR*@mG>wcdg9p{HOHS^wGu%>95U+c7*uv9)$P=%@)Kr$bRlLVxMo}fe!*I zJ>>7gWv?%Dtxv`fi78~V|CX^qV#e--W(U&81qsA5gQ4(6CriHbEYHb0F6V_3GTv+VF2}O?8G+Q@Psq5E zNB>;*$~-4Wr))Tp{v_+^690?#6$y>&|3ohSK<1F5p*A+OXSp*WJ|U729kp>m;)Ice z_y_sE1@Q)Fe0JyUl1A1CI}f<0bz zREQ@3Z5xn#iXWH0EV_y<2(C>5u)}$vNFju?dM$WX>SI;!jC?rtI=RRmfon?D1lU0vY@Den9-M z@c%j>{a@A`MSEHIPaKK(Jfm2%KQJr`Ozo5vR$=txLBAanTF2^kMs5fT@O z4P=|NXUZMCVS7PKlZ}PIp9k@7h3rx zkL}Oz^AUMp6XgDZgq3({(w-^1{G}K8A3q^GUUJIu|8aR=`gl1-=j@*Ir39%H6a$I@ z#eiZ!F`yVw3@8Q^1BwB~fMP%~pcqgLCGy|Fe&46Y=GoTsJ3}^;4 z1DXNNfM!55pc&8%Xa+O`ngPv#WGy|Fe&46Y= zGoTsJ3}^;41DXNF002{chT@^V=FYUQBNxFuuNBek7eY(kH;lM#a`t}4y4yCc2M3K@ zsPY|NTmFPOjaWx)BOdvMu!Z;CNE8q@!f8_PR9o(}Q9Y`3#>;J9-^^o`#LL8s#B;>K z|1h4fzTcC~pCAqq1%%V&?EQ>&P8-#uN+TDle4E!F$79=xMZ{cU9`SH>F6G-n&a3OW z&aR`{R#o3;C-bL>$Ex#e=Kqq^JJpu|OM`k=;fxn26nL|40#QK>Ao>vfh?r_f`A%?l zuGHPBojR`0?aMaNL=v%v*iSr8JWY%xT!^2Nv-dOB{d8hIEf~2_LQXXsUpRm??unTs4DN{FA5dZ*g*pH8f&1!ue% zsIagseO@5i4zjT zMGng{-xHr3M|2~Ed$9q5{O(DJ24Wx5C!+|d?@Fli{@r;eURyAjh#}8|hb_t09~V$D&gaA-ap+vxyDF4q^o{lbB3Y5^`Lf zC%M>$=p*(qo)|~Se7(3D%09%0hoDOzpAZd2-xX%F{Vj{B*$u0y-4AAS;3c!!YJ%~*x$h<>*#~5NXA@){afY?VCkxnEMGM31^L;S=fLhDZw>XMAQ zt1{cw)L-Up!msp6@#mu5Q&ww}8+OzEaP>}tTR;lzws_b~F|e9?5j}`5u$nvkV70dS zqt({rON%w+6SKwZtjT1hjX2`QPcYv~tRdDBONhCIvJYqeL)D3mi2o4V5I-UID$gi( zsr4rbbxBHdW6pLp^%vhN{YD5)d#X7JftH;T@F#&$dbMXqf`{ zuw=OTC&Se<2`<(o*iFNT1Y$63=031lJKwZgTmRK+ZT5}T8gb2H4Z32n_+B)d-Dn@C zW5hGWW5fnxC9!}I`&dlOA|?}ROp!4}o-LV}N@)E_LS2$kcU5M)n)>%)T?!$-xWa7l zIAb@*Qr|c(UA7V@qt7d;em0NrvCxM1x z!O6@ArlaAIOoXJ5Kv-@*!t?SGHar)>8N(4o8wpHJN8m6bHUs|s(|)vz_K9$B9S^sr zv2YI`3b!EIm2U!E-G^2Cjbw-4u+eW=&3$iLEzvh^E?sZhUEBWM=FjRJA zf$(O3_v@32!1yeLWYG>r6e2WZB*M}Q5R#ThpOK4@;rR$1F%lu!c?izRK||V2U{V(R zhoqxHzf^d4ONM8gVQ_Coge1eg0pXQG-;e>jYZg3w3gP0`9ek!o37MD3yimr5qlE7N zB;ig;X>QEfrl$V=Stq_#*6=%QE>Yw?gT8tI(ch6<>AS7gR9NZL9c5Er*lf{o@$U_f z)`Q{OGYJ7hv*-&(Qu88&=8Q)8h_Q$mJ{IAbV-TKEg0PIyw2@+jWERmji0lFc56?kh z8vR8=D#wyU_zxHg-^c`5EZKa9T%z4S_)HrJnU^U2b^j+BbxB6uRhjK>r~hMCd+(bT z`vb7pb76Byg3UD%R+kYl+e(PhtRF?>!D`E-&*m}OiPh8_c8}h03+)Tfdj_LH&r}4( zv)@ziu-sCF=a(Torwn146A+p{7NM!5Ij0zfkVN{5xGV&u{}L73M}F)xK6ZltZ)tDc+pb)Ln;E|I0j^mLTEm1 zAa4R1(k}!JqyEVSXqYhu4YJ0;zkC7wv!}zwB^P!(ZNMIOmCq(~K+#`fmU{dr33W|I z-Bp=wYtvume=Dr^9)Gra%!b8P^yfI>MxXCGg1_1KT}!HSDJzU&nYQ3Mo|xb$JM6@g zLpw;LJ={+}5l#Ql6Rx4X;Mr~veEM>JIV>9iS$PP`%;6Zpc|*Z;_?OK?gS08PY-aKO z!>ND6%X}u$T=*<4^ z$fYcxJ-AVO+XT+jMiXOTGEaorWfG5-(H_c}m(qU}bN(=ra|yADVf5|&;OZLa~EnRxP_;~HJJW_b9inc5v4pn z(Q&@nwE||hsSv+n^?C?4_sO(}G1OUXVhG&4;yCWlLddM;@EK4}pOMcwKpOS;zrbgj zNQnM2M(OoGNvLa5nj3Srt*L)6)+G_LPg7>L1ifSPUI?q_%xe8P?{^#dqn2*$&kj&m z_Xl9MR#N9A_;gC-_+AL_UTN^^o&c}*^!aYF4%@J}S5&vKaxu$?MNz|4%?rP8FIg+JXi#GkM)n)IXl< zK+n^BCbgF+F)FP;NvLa5nj3Sry`BCOxPNop?pp<0gVhedZ*xzF)xFTscP$>1Vey*!j^Le!XB;jt7(%hKyIyL*heEShgTWlWbKe&e+qL1bpz>P5=cdqq4 z*!NxMQ=5ErnzI$@FMfe8v+466+K+B?pLIZVmvWam`_O0QaUS1`fMMl~^Cz=iG1mY~ zXh)1K@LCp+IS&6XzTQ8w0{1?=7xyiHn)~5R`dT_1gn6oe9oPIhynvcT$+h4_iwXdVwyn~2Z zco;nv)WG~h7_i|D+*ke>{NhX5M#h1O^!tl>ttw(3^aNPXPR;(`m31-~ko{HBf04!B{)$(`i*RYMfOG#G>dzPs z*Mt`L71V?_V2VZKlu9J*`xw2Jo<#KGW9YTy1j{ElCY(St%h8KjUj8y|;4~U#FNS|& zA-@qA!F2<#>BaS>*CNv0mcqqW^rewfQBlh$CJ<8|c!l=x5(aNLgZ`^tLFZME!KadJA%Yc2cza$;4r z{v#0De<}KGe;ZL7UxrWQMu+|uYn$)+EZYc)OUZM|_g_;8tv^YqOH!H}bGECge`nUo zHvs8`@XQ#C{Y}sCo&45gmt*c{vvAxF9|O;#_2@D082k7sBt3o}Bc8p4?7hE1=I)CK z&Rh$hE)Sqp;R+1hb_QAde}nkV7cgMcn+P2@4<@UO|0`h+*h1Y`6YB{X|A!-D$V&9z z{XTkacpX0XY_8V7#kYKxM+n)MlGyYxLhDZw>Y9wYt1{c(Nq<>mz2X_V0Ulw`Fiyuk zAFjvDp=B7b`)%YMxrWTAeuLCKU!duX6BxYnZA?D;nh;~r@yf@xxwdH zLlh8V1ET+ALic}?P?w}MH|A{TOn>>dUdC7PwH3rc_uwV)3_rqo`b5tEDyhjh^qjvN zMQ`6g#-1+`Qt>QI5xH;;&qvO_4`>tb!V)-?^Scy8OjwOVjsu0qzedhepP}oFgYZgQ z1or_POMD8r4%|c=*iIXexn4T%$=-_O6JH=^<7s#{-NHJ?i7bt-@j2EK5|`HclZ2m} zjJm5bui;Gp-mI5BAjcj6^POG|EB_JH>NT#{r@@8sK$B@9_wHxo{)6wLX~`y-8p!^g z!~<5sl81)}KWD+@v%&=Ddb8{bdhO_JBqb z6NyK>1M|LX+UY#!YgL^8m2u9#jk?UiJu`QpQK9V7WpUqsH*?Xj7~K}`N7D9pk+SVH z;&*=zQ$Pvpv-!RF0_42BlEwWgzN!G3|RDE>E0mz zT8nPKhKt`4*gP4J^M8a|J&M4XC1^8y9bE27gsE{3Oiid|(;PIL@CYWo`5mUd`8PBw zTE=r_zITL}j&`%wq3pt+k-q&RydF3Rb0pW3mi2HC-oxX$=saOJvfsXfm}Rf?n^Nj; zpGp1wFY-C6hyp_XE-jAG`jdpZCZ)MCXIp3eU-TD#B?c(^FLv?leyL^mU$H-~qyCHo z`>p4=eGsOg8R)%YH{w^nh{&m1(4BGq=!Hj-x%nNG9R4jzIp#->XACcb--Y^$pP-)f z=UGp`iKxvV!IZEJ_Tb6fUw)3?m5cw#Mfb{QkpKQy=(p%J{mkQBYs&cVC;C536cD1n z*r(Q?B-Aw-bysD!b*8`U0m&XfHX-`Ywb&Y;Z`u7_c!llY9AFY`{_9}&V1M?XhW;C$ zL*+Yv$Ec%MQF`Jll%KkRaW7s)-rkESIdTQ1hyDv4%h$uwGZW_K1=M&f8W*fa=rXo% z!EXqxTi_DrWDXZc>^Xb6&%l z|Cc?0!9*4@ftY17xxL<^>q+=FK0w_k)BiIrXWb8Tn+FlI{RI>szKY>o`;XZ78?N&{ zL*aqX9mwDRDaIcA3X@L#2}4(%;J3aD;h#JeLF2c@TbKjt??c%q?+-tUYpZ)PU9Qw<+Bzu&T2tEFjgt{c7?yAgo&icRTKaj{E#uE|) zIMSjs_hXvB43qm*&eb=tA8&)}&?*c)a0X+kfA0RzsQo1rJ$DJk&wb%27tjv!82c$W zco`M1eZzVld-hYbp3CdB<9A;!kHZ>t0&Zb1vHw5CYZjvSgU3js??03M zmTPr>6BIFdBSswl9HlQ@MG5`DRP_w_tL60xll>cG&DHe+w$#dujbi z!rdgJ?yAh|IP3qi2M|L@3`q9dq@O(*HE74p$bOgU_vi3C-jy)>EkeKT$546xFDRp~ z<6rm^4;;IKiW9%1J$%VN{{`~t2P7AaB#LMwQ%_w-i#adA)RAjH_uViDo`QSCX@2*^ z7!vpT1}%Tfp?~y@cR2TdlHYz6vEKYDpF#YP)}JKYO;Va0b6%%5{Urt{dn~fwR!(fW zKl!mA`lWqGE%?p0?^62Ytq6)+fy7tOWA;1WV*1P1G5MvhPoVGa z{|oT&-i5GntB~;ON0{-}A2ILs8<=wP_n3J6D#pBUh1!3K;v+v|6mzMoI`bV8xb`>o zW_+;0Vz>mKgHMa|@DAgA(mo6E8_#3>#or^U@;%0n5AeIQY|;M!@c#L<(sJ}b+X{`JvBVZ4Lntg&UQ2y%ID182N4A}K+L@w9^uO>_QZRuGwYukUKPMS=S7o-ZO@CPf^d%$)Am7`G{!58>B3e!PJ~C?4f4A>m_1Czx9e*#X z_!gD4iJ{p)P%p-WeK#Q@b}w3v+krN7ccAUEU1+)Z2{eCr2bz~{L`dvLcs1R`eZRx- zZvHXxF7^KeoX<|FE(?8(evl%&SzF)ll24s9l$iBs~;dR== z4uWyQ;MK6V+6r?c#*923<*_5&NB9svEk8zsR%hYc@+=y4{T#l*9RC9r+)UZ~$*oy` z0D6p_@kd@?{QhcU2_fT<_@gwUKcV#}33W|I-Bp=wZ>PT+1EjyHd7#9CDhaU#;a@bV zBDPtqzNeEj7XEqJ#_L$S6UZC~gtYk`*Kl0NnckrG?=jBv5&QcG@M(S)ey!g}V4L&s zyXPF5M_)$67Kh=|aK+8`6IWgz^zg>NHIGUDme&>CM-g&giAAOpvMv?hr1d8Wbxlfh zW6rj>(_h8_nFmU&RoQ^VgG2|Ji%D!yaYm16zDMc zI{W&0*uu`htueK~=RAVi{t68vKVbd=TJ^nxh<2|q-oJ?R!N?DJonypv#9TuBzSw~H z{y0LOrw^g^Ckb^;M%`7JZAE|4R^ln5cjxL{$_m|Cmhm=`NF!waC2MeLC;qsI5L=Kj zLNJ98-S+r2XmYk&--o^%J^2qPn+v3r0QdI&4E}9?1)o+I5YXlWgm(A{k%Odu!;7v))#%{T4Hl@&saj%rPB8$KB4s|33W|Mb7Ri7ck2Jj24pM{?)wok_m;JR zgN4$%Xl|UMOLf?$?`_aXlTa0{d&s@D{v_dUlG5Cm^E!885hAh5m%H1-Z9cKT2Fd>_KwTUhJgi*e^b1 z2qD*)Ps9+8HoOTNxWt39*BGBConEbrR=M zeP8UdJ0aSOoz5fVoS%|!oi>pA(3G_`inCJ7lgP&md)W zKha)nL~KIlD6(b{U-2(Vy;E)Zzci?470!5ZLV=9^Mn53_SNQ)WApKurj-tK9{i_IB zPdZJ`-p^R)v{5~(G;*QJwYYZxK?|6a#=O@(0OMR*Te=hGGU$4ICT-$rzksy77WGy|Fe&46Y=GoTsJ3}^;41DXNNfM!55pc&8%Xa+O`ngPv#WGy|Fe&46Y=GoTsJ4Ag4|(o-`AXU3+*CJk#h{QlU4!R<}|1N9TW Af&c&j literal 0 HcmV?d00001 diff --git a/modules/bars/bars.lua b/modules/bars/bars.lua index e0b6441..236c982 100644 --- a/modules/bars/bars.lua +++ b/modules/bars/bars.lua @@ -54,9 +54,15 @@ DFRL:NewDefaults("Bars", { petbarScale = {0.8, "slider", {0.2, 2}, nil, "pet bar", 51, "Adjusts the scale of the pet action bar", nil, nil}, petbarSpacing = {6, "slider", {0.1, 20}, nil, "pet bar", 52, "Adjusts spacing between pet action bar buttons", nil, nil}, petbarAlpha = {1, "slider", {0.1, 1}, nil, "pet bar", 53, "Adjusts transparency of pet action bar", nil, nil}, - shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 54, "Adjusts the scale of the shapeshift bar", nil, nil}, - shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 55, "Adjusts spacing between shapeshift buttons", nil, nil}, - shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 56, "Adjusts transparency of shapeshift bar", nil, nil}, + petbarGrid = {1, "slider", {1, 6}, nil, "pet bar", 54, "Changes the grid layout of pet action bar", "5 = 2 columns x 5 rows", nil}, + petbarOrientation = {"Horizontal", "dropdown", {"Horizontal", "Vertical Down", "Vertical Up"}, nil, "pet bar", 55, "Choose how the pet bar grows when using a single row layout", "Vertical modes are especially useful for compact hunter layouts", nil}, + petbarButtonSize = {30, "slider", {20, 40}, nil, "pet bar", 56, "Adjusts the size of pet action bar buttons", nil, nil}, + petbarPreset = {"Custom", "dropdown", {"Custom", "Default", "Compact Vertical", "Compact Horizontal", "Grid 2x5"}, nil, "pet bar", 57, "Apply a quick preset for the pet bar", nil, nil}, + petbarAutoCastAlpha = {0.40, "slider", {0.1, 1}, nil, "pet bar", 58, "Adjusts the strength of the pet auto-cast glow", nil, nil}, + petbarShineAlpha = {0.28, "slider", {0.1, 1}, nil, "pet bar", 59, "Adjusts the shine overlay of pet auto-cast visuals", nil, nil}, + shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 60, "Adjusts the scale of the shapeshift bar", nil, nil}, + shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 61, "Adjusts spacing between shapeshift buttons", nil, nil}, + shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 62, "Adjusts transparency of shapeshift bar", nil, nil}, }) DFRL:NewMod("Bars", 1, function() @@ -342,6 +348,62 @@ DFRL:NewMod("Bars", 1, function() button:ClearAllPoints() button:SetPoint("LEFT", self.newPetBar, "LEFT", (i-1)*36, 0) end + + self:PetBarAutoCastVisuals() + end + + function Setup:PetBarAutoCastVisuals() + if self.petBarAutoCastFrame then return end + + local function softenTexture(tex, alpha) + if tex and tex.SetAlpha then + tex:SetAlpha(alpha) + end + end + + local function applyPetAutoCastLook() + for i = 1, 10 do + local button = _G["PetActionButton" .. i] + if button then + local name = button:GetName() + local shine = button.Shine or _G[name .. "Shine"] + local autoCast = button.AutoCastable or _G[name .. "AutoCastable"] + local autoCast2 = button.AutoCast or _G[name .. "AutoCast"] + + local shineAlpha = DFRL:GetTempDB('Bars', 'petbarShineAlpha') or 0.28 + local autoCastAlpha = DFRL:GetTempDB('Bars', 'petbarAutoCastAlpha') or 0.40 + + softenTexture(shine, shineAlpha) + softenTexture(autoCast, autoCastAlpha) + softenTexture(autoCast2, autoCastAlpha) + end + end + end + + self.petBarAutoCastFrame = CreateFrame("Frame") + self.petBarAutoCastFrame:RegisterEvent("PLAYER_ENTERING_WORLD") + self.petBarAutoCastFrame:RegisterEvent("UNIT_PET") + self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE") + self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE_USABLE") + self.petBarAutoCastFrame:RegisterEvent("PET_UI_UPDATE") + self.petBarAutoCastFrame:SetScript("OnEvent", function() + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'PetBarAutoCastEvent', event or 'nil', arg1 or 'nil') + end + applyPetAutoCastLook() + end) + + local refreshFrame = CreateFrame('Frame') + local elapsed = 0 + refreshFrame:SetScript('OnUpdate', function() + elapsed = elapsed + (arg1 or 0) + if elapsed > 1 then + this:SetScript('OnUpdate', nil) + applyPetAutoCastLook() + end + end) + + applyPetAutoCastLook() end function Setup:ShapeshiftBar() @@ -547,7 +609,8 @@ DFRL:NewMod("Bars", 1, function() -- callbacks local callbacks = {} - local helpers = { + local helpers = {} + helpers = { getFontPath = function(fontName) if fontName == 'Expressway' then return 'Interface\\AddOns\\DragonflightUI-Reforged\\media\\fnt\\Expressway.ttf' @@ -576,30 +639,124 @@ DFRL:NewMod("Bars", 1, function() end end, - setGridLayout = function(barFrame, buttonPrefix, value, spacingKey) - local layoutIndex = math.floor(value + 0.5) + normalizeLayoutIndex = function(value) + local layoutIndex = math.floor((value or 1) + 0.5) if layoutIndex < 1 then layoutIndex = 1 end if layoutIndex > 6 then layoutIndex = 6 end + return layoutIndex + end, + + setGridLayout = function(barFrame, buttonPrefix, value, spacingKey, maxButtons) + maxButtons = maxButtons or 12 + local layoutIndex = helpers.normalizeLayoutIndex(value) local layout = Setup.layouts[layoutIndex] if not layout then return end local spacing = DFRL:GetTempDB('Bars', spacingKey) - local buttonSize = _G[buttonPrefix .. '1']:GetWidth() + local firstButton = _G[buttonPrefix .. '1'] + if not firstButton then + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'GridLayoutSkipped', buttonPrefix, 'button 1 missing') + end + return + end + local buttonSize = firstButton:GetWidth() local isReversed = buttonPrefix == 'MultiBarLeftButton' or buttonPrefix == 'MultiBarRightButton' + local effectiveCols = math.min(layout.cols, maxButtons) + local effectiveRows = math.ceil(maxButtons / effectiveCols) + + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'GridLayout', buttonPrefix, 'layout', layoutIndex, 'cols', effectiveCols, 'rows', effectiveRows, 'spacing', spacing) + end - for i = (isReversed and 12 or 1), (isReversed and 1 or 12), (isReversed and -1 or 1) do + for i = (isReversed and maxButtons or 1), (isReversed and 1 or maxButtons), (isReversed and -1 or 1) do local button = _G[buttonPrefix .. i] if button then button:ClearAllPoints() - local index = isReversed and (13 - i) or i - local row = math.floor((index - 1) / layout.cols) - local col = (index - 1) - (row * layout.cols) + local index = isReversed and (maxButtons + 1 - i) or i + local row = math.floor((index - 1) / effectiveCols) + local col = (index - 1) - (row * effectiveCols) button:SetPoint('BOTTOMLEFT', barFrame, 'BOTTOMLEFT', col * (buttonSize + spacing), row * (buttonSize + spacing)) end end - barFrame:SetHeight((buttonSize + spacing) * layout.rows - spacing) - barFrame:SetWidth((buttonSize + spacing) * layout.cols - spacing) + barFrame:SetHeight((buttonSize + spacing) * effectiveRows - spacing) + barFrame:SetWidth((buttonSize + spacing) * effectiveCols - spacing) + end, + + applyPetBarButtonSize = function(size) + local buttonSize = tonumber(size) or 30 + for i = 1, 10 do + local button = _G['PetActionButton' .. i] + if button then + button:SetWidth(buttonSize) + button:SetHeight(buttonSize) + end + end + end, + + applyPetBarLayout = function() + if not DFRL.newPetBar then return end + local firstButton = _G['PetActionButton1'] + if not firstButton then return end + + local spacing = DFRL:GetTempDB('Bars', 'petbarSpacing') or 6 + local layoutIndex = helpers.normalizeLayoutIndex(DFRL:GetTempDB('Bars', 'petbarGrid') or 1) + local orientation = DFRL:GetTempDB('Bars', 'petbarOrientation') or 'Horizontal' + local buttonSize = tonumber(DFRL:GetTempDB('Bars', 'petbarButtonSize')) or firstButton:GetWidth() or 30 + local layout = Setup.layouts[layoutIndex] + if not layout then return end + + helpers.applyPetBarButtonSize(buttonSize) + + local cols = math.min(layout.cols, 10) + local rows = math.ceil(10 / cols) + local anchor = 'BOTTOMLEFT' + local verticalDirection = 1 + + if layoutIndex == 1 then + if orientation == 'Vertical Down' then + cols = 1 + rows = 10 + anchor = 'TOPLEFT' + verticalDirection = -1 + elseif orientation == 'Vertical Up' then + cols = 1 + rows = 10 + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + else + cols = 10 + rows = 1 + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + end + else + if orientation == 'Vertical Up' then + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + else + anchor = 'TOPLEFT' + verticalDirection = -1 + end + end + + for i = 1, 10 do + local button = _G['PetActionButton' .. i] + if button then + local row = math.floor((i - 1) / cols) + local col = (i - 1) - (row * cols) + button:ClearAllPoints() + button:SetPoint(anchor, DFRL.newPetBar, anchor, col * (buttonSize + spacing), row * (buttonSize + spacing) * verticalDirection) + end + end + + DFRL.newPetBar:SetWidth((buttonSize + spacing) * cols - spacing) + DFRL.newPetBar:SetHeight((buttonSize + spacing) * rows - spacing) + + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'PetBarLayout', 'grid', layoutIndex, 'orientation', orientation, 'cols', cols, 'rows', rows, 'size', buttonSize, 'spacing', spacing) + end end, iterateButtons = function(callback) @@ -637,6 +794,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarOneSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarOneGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarBottomLeftButton', value) end helpers.setSpacing('MultiBarBottomLeftButton', value) end @@ -651,6 +811,7 @@ DFRL:NewMod("Bars", 1, function() callbacks.multiBarTwoSpacing = function(value) local gridLayout = DFRL:GetTempDB('Bars', 'multiBarTwoGrid') if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarBottomRightButton', value) end helpers.setSpacing('MultiBarBottomRightButton', value) end @@ -663,6 +824,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarThreeSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarThreeGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarLeftButton', value) end helpers.setSpacing('MultiBarLeftButton', value, 'vertical') end @@ -675,6 +839,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarFourSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarFourGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarRightButton', value) end helpers.setSpacing('MultiBarRightButton', value, 'vertical') end @@ -963,7 +1130,7 @@ DFRL:NewMod("Bars", 1, function() end callbacks.petbarSpacing = function(value) - helpers.setSpacing('PetActionButton', value, 'horizontal', 10) + helpers.applyPetBarLayout() end callbacks.petbarAlpha = function(value) @@ -972,6 +1139,80 @@ DFRL:NewMod("Bars", 1, function() end end + callbacks.petbarOrientation = function(value) + helpers.applyPetBarLayout() + end + + callbacks.petbarButtonSize = function(value) + helpers.applyPetBarLayout() + end + + callbacks.petbarPreset = function(value) + if value == 'Custom' then return end + + local preset = { + ['Default'] = { + petbarGrid = 1, + petbarOrientation = 'Horizontal', + petbarButtonSize = 30, + petbarSpacing = 6, + petbarScale = 0.8, + }, + ['Compact Vertical'] = { + petbarGrid = 6, + petbarOrientation = 'Vertical Down', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + ['Compact Horizontal'] = { + petbarGrid = 1, + petbarOrientation = 'Horizontal', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + ['Grid 2x5'] = { + petbarGrid = 5, + petbarOrientation = 'Vertical Down', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + } + + local cfg = preset[value] + if not cfg then return end + + for key, setting in pairs(cfg) do + DFRL:SetTempDBNoCallback('Bars', key, setting) + end + + callbacks.petbarScale(DFRL:GetTempDB('Bars', 'petbarScale')) + callbacks.petbarGrid(DFRL:GetTempDB('Bars', 'petbarGrid')) + callbacks.petbarOrientation(DFRL:GetTempDB('Bars', 'petbarOrientation')) + callbacks.petbarButtonSize(DFRL:GetTempDB('Bars', 'petbarButtonSize')) + callbacks.petbarSpacing(DFRL:GetTempDB('Bars', 'petbarSpacing')) + + if DFRL.gui and DFRL.gui.Base and DFRL.gui.Base.UpdateHandler then + DFRL.gui.Base:UpdateHandler() + end + end + + callbacks.petbarAutoCastAlpha = function(value) + if Setup and Setup.petBarAutoCastFrame and Setup.petBarAutoCastFrame:GetScript('OnEvent') then + local fn = Setup.petBarAutoCastFrame:GetScript('OnEvent') + fn() + end + end + + callbacks.petbarShineAlpha = function(value) + if Setup and Setup.petBarAutoCastFrame and Setup.petBarAutoCastFrame:GetScript('OnEvent') then + local fn = Setup.petBarAutoCastFrame:GetScript('OnEvent') + fn() + end + end + callbacks.shapeshiftSpacing = function(value) helpers.setSpacing('ShapeshiftButton', value, 'horizontal', 10) end @@ -1072,6 +1313,11 @@ DFRL:NewMod("Bars", 1, function() helpers.setGridLayout(MultiBarRight, 'MultiBarRightButton', value, 'multiBarFourSpacing') end + callbacks.petbarGrid = function(value) + if not DFRL.newPetBar then return end + helpers.applyPetBarLayout() + end + callbacks.mainBarScale = function(value) DFRL.mainBar:SetScale(value) DFRL.actionBarFrame:SetScale(value) @@ -1096,6 +1342,7 @@ DFRL:NewMod("Bars", 1, function() callbacks.mainBarSpacing = function(value) local gridLayout = DFRL:GetTempDB('Bars', 'mainBarGrid') if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'ActionButton', value) end local buttonSize = ActionButton1:GetWidth() diff --git a/modules/gui/base.lua b/modules/gui/base.lua index 8f8e152..65f497f 100644 --- a/modules/gui/base.lua +++ b/modules/gui/base.lua @@ -11,21 +11,21 @@ DFRL:NewMod("Gui-base", 2, function() path = DFRL:GetInfoOrCons("media"), CONSTANTS = { - MAIN_FRAME_WIDTH = 900, - MAIN_FRAME_HEIGHT = 600, - TAB_FRAME_WIDTH = 130, + MAIN_FRAME_WIDTH = 980, + MAIN_FRAME_HEIGHT = 640, + TAB_FRAME_WIDTH = 150, TITLE_FRAME_HEIGHT = 30, SUB_FRAME_HEIGHT = 30, - SUB_FRAME_WIDTH = 400, - TAB_BUTTON_HEIGHT = 30, - TAB_BUTTON_WIDTH = 120, + SUB_FRAME_WIDTH = 460, + TAB_BUTTON_HEIGHT = 32, + TAB_BUTTON_WIDTH = 136, LEFT_PANEL_RATIO = 1.5, RIGHT_PANEL_RATIO = 3, - BACKGROUND_ALPHA = 0.8, - RIGHT_TEX_DIMMED_ALPHA = 0.4, + BACKGROUND_ALPHA = 0.9, + RIGHT_TEX_DIMMED_ALPHA = 0.55, - TAB_VERTICAL_SPACING = 35, + TAB_VERTICAL_SPACING = 33, TAB_GROUP_SEPARATOR = 20, TITLE_FRAME_OFFSET = 200, SUB_FRAME_OFFSET = 20, @@ -35,8 +35,8 @@ DFRL:NewMod("Gui-base", 2, function() PULSE_MIN_ALPHA = 0.1, PULSE_ALPHA_STEP = 0.02, - TITLE_FONT_SIZE = 16, - TAB_FONT_SIZE = 14, + TITLE_FONT_SIZE = 18, + TAB_FONT_SIZE = 15, SCROLL_SPEED = 15, SCROLL_STEP_SIZE = 250, @@ -89,6 +89,31 @@ DFRL:NewMod("Gui-base", 2, function() } } + function Setup:ApplyPanelStyle(frame, alpha) + if not frame then return end + frame:SetBackdrop({ + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } + }) + frame:SetBackdropColor(0, 0, 0, alpha or self.CONSTANTS.BACKGROUND_ALPHA) + frame:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end + + function Setup:StyleTabButton(tab, active) + if not tab then return end + if active then + tab.bg:SetVertexColor(0.14, 0.14, 0.14, 0.95) + tab.border:SetVertexColor(1, 0.82, 0, 0.75) + tab:GetFontString():SetTextColor(1, 0.95, 0.75, 1) + else + tab.bg:SetVertexColor(0.05, 0.05, 0.05, 0.75) + tab.border:SetVertexColor(1, 0.82, 0, 0.18) + tab:GetFontString():SetTextColor(0.82, 0.82, 0.82, 1) + end + end + function Setup:MainFrame() if not self.mainFrame then self.mainFrame = CreateFrame("Frame", "DFRLMainFrame", UIParent) @@ -102,6 +127,7 @@ DFRL:NewMod("Gui-base", 2, function() self.mainFrame:SetMovable(true) self.mainFrame:SetScript("OnMouseDown", function() this:StartMoving() end) self.mainFrame:SetScript("OnMouseUp", function() this:StopMovingOrSizing() end) + self:ApplyPanelStyle(self.mainFrame, self.CONSTANTS.BACKGROUND_ALPHA) tinsert(UISpecialFrames, self.mainFrame:GetName()) -- shagutweaks buggs this out, disable when debugging @@ -110,14 +136,14 @@ DFRL:NewMod("Gui-base", 2, function() leftTex:SetPoint("TOPLEFT", self.mainFrame, "TOPLEFT", 0, 0) leftTex:SetWidth(self.mainFrame:GetWidth() / self.CONSTANTS.LEFT_PANEL_RATIO) leftTex:SetHeight(self.mainFrame:GetHeight()) - leftTex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + leftTex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) self.rightTex = self.mainFrame:CreateTexture(nil, "BACKGROUND") self.rightTex:SetTexture("Interface\\Buttons\\WHITE8X8") self.rightTex:SetPoint("TOPRIGHT", self.mainFrame, "TOPRIGHT", 0, 0) self.rightTex:SetWidth(self.mainFrame:GetWidth() / self.CONSTANTS.RIGHT_PANEL_RATIO) self.rightTex:SetHeight(self.mainFrame:GetHeight()) - self.rightTex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + self.rightTex:SetVertexColor(0.04, 0.04, 0.04, self.CONSTANTS.BACKGROUND_ALPHA) T.GradientLine(self.mainFrame, "TOP", 3) T.GradientLine(self.mainFrame, "BOTTOM", -3) @@ -131,10 +157,18 @@ DFRL:NewMod("Gui-base", 2, function() self.tabFrame:SetHeight(self.mainFrame:GetHeight() - self.CONSTANTS.TITLE_FRAME_HEIGHT) self.tabFrame:SetWidth(self.CONSTANTS.TAB_FRAME_WIDTH) + self:ApplyPanelStyle(self.tabFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.tabFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.tabFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.01, 0.01, 0.01, self.CONSTANTS.BACKGROUND_ALPHA) + + self.tabHeader = self.tabFrame:CreateFontString(nil, "OVERLAY") + self.tabHeader:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") + self.tabHeader:SetTextColor(1, .82, 0, 1) + self.tabHeader:SetPoint("TOP", self.tabFrame, "TOP", 0, -8) + self.tabHeader:SetText(DFRL:TR("Navigation")) end end @@ -147,10 +181,12 @@ DFRL:NewMod("Gui-base", 2, function() self.titleFrame:SetFrameStrata("DIALOG") self.titleFrame:SetClampedToScreen(true) self.titleFrame:SetToplevel(true) + self:ApplyPanelStyle(self.titleFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.titleFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.titleFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) tinsert(UISpecialFrames, self.titleFrame:GetName()) @@ -213,10 +249,12 @@ DFRL:NewMod("Gui-base", 2, function() self.subFrame:SetHeight(self.CONSTANTS.SUB_FRAME_HEIGHT) self.subFrame:SetWidth(self.CONSTANTS.SUB_FRAME_WIDTH) + self:ApplyPanelStyle(self.subFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.subFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.subFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) self.profileText = self.subFrame:CreateFontString(nil, "OVERLAY") self.profileText:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") @@ -225,19 +263,25 @@ DFRL:NewMod("Gui-base", 2, function() local charName = UnitName("player") local profileName = DFRL_CUR_PROFILE[charName] or "Default" - self.profileText:SetText("Profile: |cffffffff" .. profileName .. "|r") + self.profileText:SetText(DFRL:TR("Profile") .. ": |cffffffff" .. DFRL:DisplayProfileName(profileName) .. "|r") self.fpsText = self.subFrame:CreateFontString(nil, "OVERLAY") self.fpsText:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") self.fpsText:SetTextColor(1, .82, 0, 1) self.fpsText:SetPoint("RIGHT", self.subFrame, "RIGHT", -10, 0) + self.helpText = self.subFrame:CreateFontString(nil, "OVERLAY") + self.helpText:SetFont(self.font.. "BigNoodleTitling.ttf", 11, "OUTLINE") + self.helpText:SetTextColor(0.75, 0.75, 0.75, 1) + self.helpText:SetPoint("CENTER", self.subFrame, "CENTER", 0, 0) + self.helpText:SetText(DFRL:TR("Drag to move - ESC to close")) + self.subFrame:SetScript("OnUpdate", function() if (this.fpsTimer or 0) > GetTime() then return end this.fpsTimer = GetTime() + 0.5 DFRL.activeScripts["GUI SubFrame"] = true - self.fpsText:SetText("FPS: |cffffffff" .. format("%.1f", GetFramerate()) .. "|r") - self.profileText:SetText("Profile: |cffffffff" .. (DFRL_CUR_PROFILE[UnitName("player")] or "Default") .. "|r") + self.fpsText:SetText(DFRL:TR("FPS:") .. " |cffffffff" .. format("%.1f", GetFramerate()) .. "|r") + self.profileText:SetText(DFRL:TR("Profile") .. ": |cffffffff" .. DFRL:DisplayProfileName(DFRL_CUR_PROFILE[UnitName("player")] or "Default") .. "|r") end) self.subFrame:SetScript("OnShow", function() @@ -257,12 +301,23 @@ DFRL:NewMod("Gui-base", 2, function() tab:SetHeight(self.CONSTANTS.TAB_BUTTON_HEIGHT) tab:SetWidth(self.CONSTANTS.TAB_BUTTON_WIDTH) - local yOffset = -10 - (i - 1) * self.CONSTANTS.TAB_VERTICAL_SPACING + local yOffset = -30 - (i - 1) * self.CONSTANTS.TAB_VERTICAL_SPACING if i > 5 then yOffset = yOffset - self.CONSTANTS.TAB_GROUP_SEPARATOR end tab:SetPoint("TOP", self.tabFrame, "TOP", 0, yOffset) + local bg = tab:CreateTexture(nil, "BACKGROUND") + bg:SetTexture("Interface\\Buttons\\WHITE8X8") + bg:SetAllPoints(tab) + tab.bg = bg + + local border = tab:CreateTexture(nil, "BORDER") + border:SetTexture("Interface\\Buttons\\WHITE8X8") + border:SetPoint("TOPLEFT", tab, "TOPLEFT", 2, -2) + border:SetPoint("BOTTOMRIGHT", tab, "BOTTOMRIGHT", -2, 2) + tab.border = border + local highlight = tab:CreateTexture(nil, "OVERLAY") highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") highlight:SetAllPoints(tab) @@ -275,7 +330,7 @@ DFRL:NewMod("Gui-base", 2, function() text:SetTextColor(.7, .7, .7, 1) text:SetPoint("CENTER", tab, "CENTER") tab:SetFontString(text) - tab:SetText(Setup.tabs[i]) + tab:SetText(DFRL:TR(Setup.tabs[i])) local tabIndex = i tab:SetScript("OnClick", function() @@ -285,19 +340,24 @@ DFRL:NewMod("Gui-base", 2, function() tab:SetScript("OnEnter", function() if tabIndex ~= self.selectedTab then tab.highlight:Show() + tab.bg:SetVertexColor(0.10, 0.10, 0.10, 0.92) + tab.border:SetVertexColor(1, 0.82, 0, 0.45) end end) tab:SetScript("OnLeave", function() if tabIndex ~= self.selectedTab then tab.highlight:Hide() + self:StyleTabButton(tab, false) end end) + self:StyleTabButton(tab, false) self.tabButtons[i] = tab end self.tabButtons[13]:Disable() self.tabButtons[13]:GetFontString():SetTextColor(.4, .4, .4, 1) + if self.tabButtons[13].border then self.tabButtons[13].border:SetVertexColor(0.4, 0.4, 0.4, 0.1) end self.tabsCreated = true end end @@ -305,10 +365,11 @@ DFRL:NewMod("Gui-base", 2, function() function Setup:SelectTab(tabIndex) for i = 1, table.getn(self.tabs) do self.tabButtons[i].highlight:Hide() + self:StyleTabButton(self.tabButtons[i], false) end - self.tabButtons[tabIndex].highlight:Show() + self:StyleTabButton(self.tabButtons[tabIndex], true) self.selectedTab = tabIndex @@ -346,7 +407,7 @@ DFRL:NewMod("Gui-base", 2, function() self.slider:Show() end if tabIndex ~= 1 then - self.panelTitle:SetText(self.tabs[tabIndex]) + self.panelTitle:SetText(DFRL:TR(self.tabs[tabIndex])) else self.panelTitle:SetText("") end @@ -468,9 +529,9 @@ DFRL:NewMod("Gui-base", 2, function() function Setup:PanelTitles() if not self.panelTitle then self.panelTitle = self.mainFrame:CreateFontString(nil, "OVERLAY") - self.panelTitle:SetFont(self.font.. "BigNoodleTitling.ttf", 18, "OUTLINE") + self.panelTitle:SetFont(self.font.. "BigNoodleTitling.ttf", 22, "OUTLINE") self.panelTitle:SetTextColor(1, .82, 0, 1) - self.panelTitle:SetPoint("TOP", self.scrollFrame, "TOP", -20, 25) + self.panelTitle:SetPoint("TOP", self.scrollFrame, "TOP", -20, 28) end end diff --git a/modules/gui/elem.lua b/modules/gui/elem.lua index c3fba1e..04cb7e0 100644 --- a/modules/gui/elem.lua +++ b/modules/gui/elem.lua @@ -31,11 +31,11 @@ DFRL:NewMod("Gui-elem", 3, function() tabPositions = {}, configCache = {}, - DESCRIPTION_FONT_SIZE = 15, - EXTRA_DESCRIPTION_FONT_SIZE = 11, - VALUE_FONT_SIZE = 14, + DESCRIPTION_FONT_SIZE = 16, + EXTRA_DESCRIPTION_FONT_SIZE = 12, + VALUE_FONT_SIZE = 15, - MODULE_TOP_SPACING = 40, + MODULE_TOP_SPACING = 44, MODULE_BOTTOM_SPACING = 40, HEADER_TOP_SPACING = 40, HEADER_BOTTOM_SPACING = 25, @@ -287,14 +287,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 3) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementName] = extraDescLabel end @@ -348,14 +348,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 6) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end @@ -434,14 +434,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 10) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end @@ -495,14 +495,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 6) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end diff --git a/modules/gui/homeb.lua b/modules/gui/homeb.lua index 6735658..02c067b 100644 --- a/modules/gui/homeb.lua +++ b/modules/gui/homeb.lua @@ -18,6 +18,7 @@ DFRL:NewDefaults("GUI-Dragonflight", { sideView = {.3, "slider", {.1, .8}, nil, "Home Screen", 3, "Changes the alpha of the side view", "", nil}, homeMinMaxColor = {{1, .82, 0}, "colour", nil, nil, "Home Screen", 4, "Changes the color of the close and min button", nil, nil}, homeTimeColor = {{1, .82, 0}, "colour", nil, nil, "Home Screen", 5, "Changes the color of the time on the home screen", nil, nil}, + language = {(GetLocale() == "frFR" and "Francais" or "English"), "dropdown", {"English", "Francais"}, nil, "localization", 6, "Select the language used in the configuration UI", nil, nil}, }) DFRL:NewMod("GUI-Dragonflight", 4, function() @@ -313,6 +314,7 @@ DFRL:NewMod("GUI-Dragonflight", 4, function() -- callbacks local callbacks = {} + local lastAppliedLanguage = nil callbacks.homeTimeColor = function (value) Setup.timeText:SetTextColor(value[1], value[2], value[3]) @@ -351,6 +353,21 @@ DFRL:NewMod("GUI-Dragonflight", 4, function() end end + callbacks.language = function(value) + if not lastAppliedLanguage then + lastAppliedLanguage = value + return + end + + if lastAppliedLanguage == value then + return + end + + lastAppliedLanguage = value + DFRL:SaveTempDB() + ReloadUI() + end + callbacks.globalFont = function(value) local fontPath if value == 'Expressway' then diff --git a/modules/gui/info.lua b/modules/gui/info.lua index f32dc9b..a3ddcc1 100644 --- a/modules/gui/info.lua +++ b/modules/gui/info.lua @@ -264,7 +264,7 @@ self.grid:AddElement(6, 8, scriptText:SetText(scriptName) scriptText:SetTextColor(1, 1, 1) - statusText:SetText(DFRL.activeScripts[scriptName] and "ON" or "OFF") + statusText:SetText(DFRL:TR(DFRL.activeScripts[scriptName] and "ON" or "OFF")) statusText:SetTextColor(DFRL.activeScripts[scriptName] and 0 or 0.5, DFRL.activeScripts[scriptName] and 1 or 0.5, DFRL.activeScripts[scriptName] and 0 or 0.5) index = index + 1 @@ -294,7 +294,7 @@ self.grid:AddElement(6, 8, scriptText:SetText(scriptName) scriptText:SetTextColor(1, 1, 1) - statusText:SetText(DFRL.activeScripts[scriptName] and "ON" or "OFF") + statusText:SetText(DFRL:TR(DFRL.activeScripts[scriptName] and "ON" or "OFF")) statusText:SetTextColor(DFRL.activeScripts[scriptName] and 0 or 0.5, DFRL.activeScripts[scriptName] and 1 or 0.5, DFRL.activeScripts[scriptName] and 0 or 0.5) index = index + 1 diff --git a/modules/gui/mods.lua b/modules/gui/mods.lua index bae809d..7a951f1 100644 --- a/modules/gui/mods.lua +++ b/modules/gui/mods.lua @@ -49,7 +49,7 @@ DFRL:NewMod("Gui-mods", 3, function() local moduleName = modules[i] local checkbox = DFRL.tools.CreateCheckbox(nil, nil, moduleName, "enabled", true) - checkbox.label:SetText(moduleName) + checkbox.label:SetText(DFRL:TR(moduleName)) self.grid:AddElement(row, line, checkbox) line = line + 1 diff --git a/modules/gui/prof.lua b/modules/gui/prof.lua index 8427693..2f9ce2f 100644 --- a/modules/gui/prof.lua +++ b/modules/gui/prof.lua @@ -44,11 +44,11 @@ DFRL:NewMod("Gui-prof", 4, function() switchBtns = {}, newProfileBtn = nil, resetBtn = nil, + saveBtn = nil, warner = nil } } - function Setup:ListFrame() if not self.headers then self.grid:AddElement(2, 1, DFRL.tools.CreateCategoryHeader(nil, "Manage")) @@ -56,13 +56,13 @@ DFRL:NewMod("Gui-prof", 4, function() end if not self.ui.usageText then - self.ui.usageText = DFRL.tools.CreateFont(panel, 14, "Usage:\n\n\n1) new profile: create and switch to a new profile\n\n2) switch: change active profile\n\n3) copy: copies all settings into active profile\n\n4) delete: delete profile and switch back to default\n\n5)reset: reset active profile to the default settings\n\n\ndoes not affect shagutweaks\n\nBUG: DOUBLE CLICK DELETE AFTER NEW PROFILE\n\nBUG: ENTER PROFILE NAME STAYS", {.5, .5, .5}, "LEFT") + self.ui.usageText = DFRL.tools.CreateFont(panel, 14, "Profiles help text", {.65, .65, .65}, "LEFT") self.grid:AddElement(5, 4, self.ui.usageText) end if not self.ui.frame then self.ui.frame = CreateFrame("Frame", nil, panel) - self.ui.frame:SetWidth(300) - self.ui.frame:SetHeight(400) + self.ui.frame:SetWidth(320) + self.ui.frame:SetHeight(420) self.grid:AddElement(2, 3, self.ui.frame) T.GradientLine(self.ui.frame, "TOP", 20, 2) T.GradientLine(self.ui.frame, "TOP", 60, 2) @@ -76,7 +76,7 @@ DFRL:NewMod("Gui-prof", 4, function() self.ui.curText:SetFont(self.font .. "BigNoodleTitling.ttf", self.TEXT_SIZE, "OUTLINE") self.ui.curText:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 10, -10) end - self.ui.curText:SetText("Current: |cff80ff80" .. curProf .. "|r") + self.ui.curText:SetText(DFRL:TR("Current") .. ": |cff80ff80" .. DFRL:DisplayProfileName(curProf) .. "|r") for _, text in pairs(self.ui.texts) do text:Hide() end @@ -113,12 +113,12 @@ DFRL:NewMod("Gui-prof", 4, function() local text = self.ui.frame:CreateFontString(nil, "OVERLAY") text:SetFont(self.font .. "BigNoodleTitling.ttf", self.TEXT_SIZE, "OUTLINE") text:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 10, yOffset) - text:SetText(name) + text:SetText(DFRL:DisplayProfileName(name)) table.insert(self.ui.texts, text) if name ~= "Default" then local profName = name - local switchBtn = DFRL.tools.CreateButton(self.ui.frame, "Switch", 50, 20, true, {0.5, 1, 0.5}) - switchBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 125, yOffset) + local switchBtn = DFRL.tools.CreateButton(self.ui.frame, "Switch", 55, 20, true, {0.5, 1, 0.5}) + switchBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 135, yOffset) switchBtn.profName = profName switchBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -132,13 +132,17 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("switched to " .. clickedName) + if DFRL:IsFrench() then + Setup.ui.warner:SetText(DFRL:TR("switched to") .. " " .. clickedName) + else + Setup.ui.warner:SetText("switched to " .. clickedName) + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) table.insert(self.ui.switchBtns, switchBtn) - local copyBtn = DFRL.tools.CreateButton(self.ui.frame, "Copy", 50, 20, true) - copyBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 180, yOffset) + local copyBtn = DFRL.tools.CreateButton(self.ui.frame, "Copy", 55, 20, true) + copyBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 195, yOffset) copyBtn.profName = profName copyBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -152,13 +156,17 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 1, 0) - Setup.ui.warner:SetText("profile copied from " .. clickedName) + if DFRL:IsFrench() then + Setup.ui.warner:SetText(DFRL:TR("profile copied from") .. " " .. clickedName) + else + Setup.ui.warner:SetText("profile copied from " .. clickedName) + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) table.insert(self.ui.copyBtns, copyBtn) - local delBtn = DFRL.tools.CreateButton(self.ui.frame, "Delete", 50, 20, true, {1, 0.5, 0.5}) - delBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 235, yOffset) + local delBtn = DFRL.tools.CreateButton(self.ui.frame, "Delete", 55, 20, true, {1, 0.5, 0.5}) + delBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 255, yOffset) delBtn.profName = profName delBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -171,7 +179,11 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText(clickedName .. " deleted") + if DFRL:IsFrench() then + Setup.ui.warner:SetText(clickedName .. " " .. DFRL:TR("deleted")) + else + Setup.ui.warner:SetText(clickedName .. " deleted") + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) @@ -181,7 +193,6 @@ DFRL:NewMod("Gui-prof", 4, function() yOffset = yOffset - 20 end - end function Setup:RestartWarnerPulse() @@ -219,8 +230,13 @@ DFRL:NewMod("Gui-prof", 4, function() end function Setup:ExtraButtons() + if not self.ui.actionsHeader then + self.ui.actionsHeader = DFRL.tools.CreateCategoryHeader(panel, "Quick Actions", false, 150, 24, 14) + self.ui.actionsHeader:SetPoint("BOTTOMLEFT", self.ui.frame, "TOPRIGHT", 10, -22) + end + if not self.ui.newProfileBtn then - self.ui.newProfileBtn = DFRL.tools.CreateButton(panel, "New Profile", 100, 30, true) + self.ui.newProfileBtn = DFRL.tools.CreateButton(panel, "New Profile", 130, 30, true) self.ui.newProfileBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPRIGHT", 20, -25) self.ui.newProfileBtn:SetScript("OnClick", function() local count = 0 @@ -233,7 +249,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText("MAX PROFILES REACHED") + Setup.ui.warner:SetText(DFRL:TR("MAX PROFILES REACHED")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() return @@ -259,7 +275,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("new profile created") + Setup.ui.warner:SetText(DFRL:TR("new profile created")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() end @@ -275,7 +291,7 @@ DFRL:NewMod("Gui-prof", 4, function() end if not self.ui.resetBtn then - self.ui.resetBtn = DFRL.tools.CreateButton(panel, "Reset", 100, 30, true, {1, 0.5, 0.5}) + self.ui.resetBtn = DFRL.tools.CreateButton(panel, "Reset", 130, 30, true, {1, 0.5, 0.5}) self.ui.resetBtn:SetPoint("TOPLEFT", self.ui.newProfileBtn, "BOTTOMLEFT", 0, -10) self.ui.resetBtn:SetScript("OnClick", function() local success, _ = pcall(function() @@ -288,7 +304,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("CURRENT PROFILE RESET") + Setup.ui.warner:SetText(DFRL:TR("CURRENT PROFILE RESET")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() else @@ -297,13 +313,28 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText("PROFILE RESET FAILED") + Setup.ui.warner:SetText(DFRL:TR("PROFILE RESET FAILED")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() end end) end + if not self.ui.saveBtn then + self.ui.saveBtn = DFRL.tools.CreateButton(panel, "Save Profile", 130, 30, true, {0.5, 1, 0.5}) + self.ui.saveBtn:SetPoint("TOPLEFT", self.ui.resetBtn, "BOTTOMLEFT", 0, -10) + self.ui.saveBtn:SetScript("OnClick", function() + DFRL:SaveTempDB() + if not Setup.ui.warner then + Setup.ui.warner = DFRL.tools.CreateFontWarner(panel, 14, "", {0, 1, 0}, true, 3) + Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) + end + Setup.ui.warner:SetTextColor(0, 1, 0) + Setup.ui.warner:SetText(DFRL:TR("profile saved")) + Setup.ui.warner:Show() + Setup:RestartWarnerPulse() + end) + end end --================= diff --git a/modules/gui/shag.lua b/modules/gui/shag.lua index f4ade38..9f1a959 100644 --- a/modules/gui/shag.lua +++ b/modules/gui/shag.lua @@ -133,7 +133,7 @@ DFRL:NewMod("Gui-shag", 3, function() local desc = panel:CreateFontString(nil, "OVERLAY", "GameFontNormal") desc:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") desc:SetPoint("TOPLEFT", panel, "TOPLEFT", 10, -yPos) - desc:SetText(element.data.description or element.key) + desc:SetText(DFRL:TR(element.data.description or element.key)) desc:SetTextColor(.9, .9, .9) self.descriptionLabels[element.key] = desc @@ -150,7 +150,7 @@ DFRL:NewMod("Gui-shag", 3, function() local txt = panel:CreateFontString(nil, "OVERLAY") txt:SetFont(self.font .. "BigNoodleTitling.ttf", 30, "OUTLINE") txt:SetPoint("TOP", panel, "TOP", 10, -yPos-50) - txt:SetText("SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS") + txt:SetText(DFRL:TR("SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS")) txt:SetTextColor(1, 0.5, 0.5) local f3 = CreateFrame("Frame") f3.t = 0 diff --git a/modules/gui/tools.lua b/modules/gui/tools.lua index 02b5cfd..bea2bb6 100644 --- a/modules/gui/tools.lua +++ b/modules/gui/tools.lua @@ -98,8 +98,15 @@ function DFRL.tools.CreateFont(parent, size, text, colour, align) font:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", size or 14, "OUTLINE") colour = colour or {1, 1, 1} font:SetTextColor(colour[1], colour[2], colour[3]) - font:SetText(text) + font.rawText = text + font:SetText(DFRL:TR(text or "")) font.align = align or "CENTER" + + function font:SetLocalizedText(newText) + self.rawText = newText + self:SetText(DFRL:TR(newText or "")) + end + return font end @@ -107,21 +114,37 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo local btn = CreateFrame("Button", nil, parent or UIParent) btn:SetWidth(width or 140) btn:SetHeight(height or 30) + if not noBackdrop then btn:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, tileSize = 16, edgeSize = 16, + tile = true, tileSize = 16, edgeSize = 14, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) - btn:SetBackdropColor(0, 0, 0, .5) - btn:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) + btn:SetBackdropColor(0.04, 0.04, 0.04, .88) + btn:SetBackdropBorderColor(1, 0.82, 0, 0.35) + else + local bg = btn:CreateTexture(nil, "BACKGROUND") + bg:SetTexture("Interface\\Buttons\\WHITE8X8") + bg:SetPoint("TOPLEFT", btn, "TOPLEFT", 1, -1) + bg:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -1, 1) + bg:SetVertexColor(0.08, 0.08, 0.08, 0.28) + btn._bg = bg + + local border = btn:CreateTexture(nil, "BORDER") + border:SetTexture("Interface\\Buttons\\WHITE8X8") + border:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0) + border:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0) + border:SetVertexColor(1, 0.82, 0, 0.16) + btn._border = border end local btnTxt = btn:CreateFontString(nil, "OVERLAY") btnTxt:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") btnTxt:SetPoint("CENTER", btn, "CENTER", 0, 0) - btnTxt:SetText(text) + btn.rawText = text + btnTxt:SetText(DFRL:TR(text or "")) if textColor then btnTxt:SetTextColor(textColor[1], textColor[2], textColor[3]) @@ -131,6 +154,11 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo btn.text = btnTxt + function btn:SetLocalizedText(newText) + self.rawText = newText + self.text:SetText(DFRL:TR(newText or "")) + end + local origEnable = btn.Enable local origDisable = btn.Disable @@ -141,11 +169,17 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo else btnTxt:SetTextColor(1, 1, 1) end + if self.SetBackdropBorderColor and not noBackdrop then + self:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end end btn.Disable = function(self) origDisable(self) btnTxt:SetTextColor(0.5, 0.5, 0.5) + if self.SetBackdropBorderColor and not noBackdrop then + self:SetBackdropBorderColor(0.4, 0.4, 0.4, 0.2) + end end local highlight = btn:CreateTexture(nil, "HIGHLIGHT") @@ -154,6 +188,24 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo highlight:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -2, 4) highlight:SetBlendMode("ADD") + btn:SetScript("OnEnter", function() + if noBackdrop then + if this._bg then this._bg:SetVertexColor(0.12, 0.12, 0.12, 0.45) end + if this._border then this._border:SetVertexColor(1, 0.82, 0, 0.45) end + else + this:SetBackdropBorderColor(1, 0.82, 0, 0.65) + end + end) + + btn:SetScript("OnLeave", function() + if noBackdrop then + if this._bg then this._bg:SetVertexColor(0.08, 0.08, 0.08, 0.28) end + if this._border then this._border:SetVertexColor(1, 0.82, 0, 0.16) end + else + this:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end + end) + return btn end @@ -165,7 +217,7 @@ function DFRL.tools.CreateIndiCheckbox(parent, name, text) local label = checkbox:CreateFontString(nil, "BACKGROUND") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - label:SetText(text or "Checkbox") + label:SetText(DFRL:TR(text or "Checkbox")) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -194,18 +246,20 @@ function DFRL.tools.CreateIndiSlider(parent, name, text, minVal, maxVal, step) slider:SetOrientation("HORIZONTAL") slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") slider:SetBackdrop({ - bgFile = "Interface\\Buttons\\UI-SliderBar-Background", - edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", - tile = true, tileSize = 8, edgeSize = 8, + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 10, insets = { left = 3, right = 3, top = 6, bottom = 6 } }) + slider:SetBackdropColor(0.03, 0.03, 0.03, 0.85) + slider:SetBackdropBorderColor(1, 0.82, 0, 0.18) slider:SetMinMaxValues(minVal or 0, maxVal or 5) slider:SetValueStep(step or 0.1) local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - label:SetText(text or "Slider") + label:SetText(DFRL:TR(text or "Slider")) label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetTextColor(.9,.9,.9) slider.label = label @@ -279,13 +333,15 @@ function DFRL.tools.CreateIndiDropDown(parent, text, items, width, height) btn.popup = popup btn.selectedValue = items[1] + btn.text:SetText(DFRL:TR(btn.selectedValue)) for i = 1, table.getn(items) do local itemBtn = DFRL.tools.CreateButton(popup, items[i], popup:GetWidth() - 4, 20, true) + itemBtn.itemValue = items[i] itemBtn:SetPoint("TOP", popup, "TOP", 0, -(i - 1) * 22 - 5) itemBtn:SetScript("OnClick", function() - btn.text:SetText(this.text:GetText()) - btn.selectedValue = this.text:GetText() + btn.text:SetText(DFRL:TR(this.itemValue)) + btn.selectedValue = this.itemValue popup:Hide() end) end @@ -320,10 +376,12 @@ function DFRL.tools.CreateEditBox(parent, width, height, letters, numbers, max) box:SetHeight(height or 20) box:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", - insets = { left = -5, right = -5, top = 0, bottom = 0 } + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } }) - box:SetBackdropColor(0, 0, 0, 0.8) - box:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) + box:SetBackdropColor(0.02, 0.02, 0.02, 0.9) + box:SetBackdropBorderColor(1, 0.82, 0, 0.25) box:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 14, "OUTLINE") box:SetTextColor(1, 1, 1) box:SetTextInsets(5, 5, 5, 5) @@ -390,19 +448,31 @@ function DFRL.tools.CreateCategoryHeader(parent, categoryName, noBG, width, heig tile = true, tileSize = 16, edgeSize = 16, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) - categoryBg:SetBackdropColor(0.1, 0.1, 0.1, 0.6) - categoryBg:SetBackdropBorderColor(0.1, 0.1, 0.1, 0.5) + categoryBg:SetBackdropColor(0.05, 0.05, 0.05, 0.78) + categoryBg:SetBackdropBorderColor(1, 0.82, 0, 0.22) end local categoryTitle = categoryBg:CreateFontString(nil, "OVERLAY") categoryTitle:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", txtSize or 14, "OUTLINE") categoryTitle:SetPoint("CENTER", categoryBg, "CENTER", 0, 1) - local words = string.gfind(categoryName, "%S+") - local capitalizedWords = {} - for word in words do - table.insert(capitalizedWords, string.upper(string.sub(word, 1, 1)) .. string.sub(word, 2)) + categoryBg.title = categoryTitle + categoryBg.rawCategoryName = categoryName + + function categoryBg:RefreshText() + local localizedName = DFRL:TR(self.rawCategoryName or "") + if DFRL:IsFrench() then + self.title:SetText(localizedName) + else + local words = string.gfind(localizedName, "%S+") + local capitalizedWords = {} + for word in words do + table.insert(capitalizedWords, string.upper(string.sub(word, 1, 1)) .. string.sub(word, 2)) + end + self.title:SetText(table.concat(capitalizedWords, " ")) + end end - categoryTitle:SetText(table.concat(capitalizedWords, " ")) + + categoryBg:RefreshText() categoryTitle:SetTextColor(1, 0.82, 0) return categoryBg @@ -416,8 +486,7 @@ function DFRL.tools.CreateCheckbox(parent, name, moduleName, key, noCall) local label = checkbox:CreateFontString(nil, "BACKGROUND") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayTxt) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -445,7 +514,7 @@ function DFRL.tools.CreateShaguCheckbox(parent, name, key) local label = checkbox:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 14, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - label:SetText(key) + label:SetText(DFRL:TR(key)) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -490,8 +559,7 @@ function DFRL.tools.CreateSlider(parent, name, moduleName, key, minVal, maxVal, local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayTxt) label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetTextColor(.9,.9,.9) @@ -591,19 +659,20 @@ function DFRL.tools.CreateColour(parent, name, moduleName, key) slider:SetOrientation("HORIZONTAL") slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") slider:SetBackdrop({ - bgFile = "Interface\\Buttons\\UI-SliderBar-Background", - edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", - tile = true, tileSize = 8, edgeSize = 8, + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 10, insets = { left = 3, right = 3, top = 6, bottom = 6 } }) + slider:SetBackdropColor(0.03, 0.03, 0.03, 0.85) + slider:SetBackdropBorderColor(1, 0.82, 0, 0.18) slider:SetMinMaxValues(1, COLOR_COUNT) slider:SetValueStep(1) local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - local displayText = string.gsub(key, "(%l)(%u)", "%1 %2") - displayText = string.upper(string.sub(displayText, 1, 1)) .. string.sub(displayText, 2) + local displayText = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayText) label:SetFont("Fonts\\FRIZQT__.TTF", 11, "") label:SetTextColor(.9,.9,.9) @@ -680,8 +749,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, local btnTxt = btn:CreateFontString(nil, "OVERLAY") btnTxt:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") btnTxt:SetPoint("CENTER", btn, "CENTER", 0, 0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) btnTxt:SetText(displayTxt) btnTxt:SetTextColor(1, 1, 1) btn.text = btnTxt @@ -693,7 +761,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, local currentValue = DFRL:GetTempDB(moduleName, key) if currentValue then - btnTxt:SetText(currentValue) + btnTxt:SetText(DFRL:TR(currentValue)) end if not btn.popup then @@ -705,12 +773,20 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, popup:SetFrameStrata("DIALOG") popup:SetToplevel(true) popup:EnableMouse(true) + popup:SetBackdrop({ + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } + }) + popup:SetBackdropColor(0.02, 0.02, 0.02, 0.95) + popup:SetBackdropBorderColor(1, 0.82, 0, 0.25) DFRL.tools.GradientLine(popup, "TOP", 2) local bg = popup:CreateTexture(nil, "BACKGROUND") bg:SetTexture("Interface\\Buttons\\WHITE8X8") bg:SetAllPoints(popup) - bg:SetVertexColor(0, 0, 0, .8) + bg:SetVertexColor(0.02, 0.02, 0.02, .92) popup:Hide() btn.popup = popup @@ -724,7 +800,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, itemBtn.itemText = items[i] itemBtn:SetScript("OnClick", function() - btn.text:SetText(this.itemText) + btn.text:SetText(DFRL:TR(this.itemText)) if noCall then DFRL:SetTempDBNoCallback(moduleName, key, this.itemText) else @@ -841,7 +917,13 @@ function DFRL.tools.CreateFontWarner(parent, size, text, colour, pulse, time) fontString:SetTextColor(1, 1, 1) end - fontString:SetText(text) + fontString.rawText = text + fontString:SetText(DFRL:TR(text or "")) + + function fontString:SetLocalizedText(newText) + self.rawText = newText + self:SetText(DFRL:TR(newText or "")) + end if pulse or time then local frame = CreateFrame("Frame") diff --git a/modules/micro/micro.lua b/modules/micro/micro.lua index 5b83a06..32bc0b2 100644 --- a/modules/micro/micro.lua +++ b/modules/micro/micro.lua @@ -20,6 +20,7 @@ DFRL:NewMod("Micro", 1, function() pvpButton = nil, lftButton = nil, ebcButton = nil, + ijStandaloneButton = nil, msText = nil, bwText = nil, @@ -137,6 +138,71 @@ DFRL:NewMod("Micro", 1, function() end) end + + function Setup:CreateInstanceJournalStandaloneButton() + if self.ijStandaloneButton then return end + + self.ijStandaloneButton = CreateFrame("Button", "DFRLIJStandaloneButton", self.microMenuContainer) + self.ijStandaloneButton:SetWidth(self.buttonWidth) + self.ijStandaloneButton:SetHeight(self.buttonHeight) + self.ijStandaloneButton:SetHitRectInsets(0, 0, 0, 0) + self.ijStandaloneButton:Show() + self.ijStandaloneButton:Enable() + + self.ijStandaloneButton:SetScript("OnClick", function() + if _G["InstanceJournal"] and InstanceJournal.ToggleInstanceJournal then + InstanceJournal:ToggleInstanceJournal() + elseif _G["ToggleInstanceJournal"] then + ToggleInstanceJournal() + end + end) + + self.ijStandaloneButton:SetScript("OnEnter", function() + GameTooltip:SetOwner(self.ijStandaloneButton, "ANCHOR_RIGHT") + GameTooltip:SetText("Instance Journal", 1, 1, 1) + GameTooltip:AddLine("Open the Instance Journal.") + GameTooltip:Show() + end) + + self.ijStandaloneButton:SetScript("OnLeave", function() + GameTooltip:Hide() + end) + end + + function Setup:PositionInstanceJournalStandaloneButton(spacing) + if not self.ijStandaloneButton or not self.buttons or not self.buttons[table.getn(self.buttons)] then return end + local lastButton = self.buttons[table.getn(self.buttons)] + self.ijStandaloneButton:ClearAllPoints() + self.ijStandaloneButton:SetPoint("TOPLEFT", lastButton, "TOPRIGHT", spacing or self.buttonSpacing, 0) + self.ijStandaloneButton:SetParent(self.microMenuContainer) + self.ijStandaloneButton:SetFrameStrata(lastButton:GetFrameStrata()) + self.ijStandaloneButton:SetFrameLevel(lastButton:GetFrameLevel()) + end + + function Setup:ApplyInstanceJournalStandaloneStyle(useColor) + if not self.ijStandaloneButton then return end + local colorpath = self.texpath .. "color_micro\\" + if useColor then + self.ijStandaloneButton:SetNormalTexture(colorpath .. "instancejournal-regular.tga") + self.ijStandaloneButton:SetPushedTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetHighlightTexture(colorpath .. "instancejournal-highlight.tga") + else + self.ijStandaloneButton:SetNormalTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetPushedTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetHighlightTexture(colorpath .. "instancejournal-highlight.tga") + end + if self.ijStandaloneButton:GetNormalTexture() then + self.ijStandaloneButton:GetNormalTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + self.ijStandaloneButton:GetNormalTexture():Show() + end + if self.ijStandaloneButton:GetPushedTexture() then + self.ijStandaloneButton:GetPushedTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + end + if self.ijStandaloneButton:GetHighlightTexture() then + self.ijStandaloneButton:GetHighlightTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + end + end + function Setup:LowLevelTalentButton() if not DFRL.lowLevelTalentsButton then local lowLevelTalentsButton = CreateFrame("Button", "DFRLLowLevelTalentsButton", Setup.microMenuContainer) @@ -345,6 +411,9 @@ DFRL:NewMod("Micro", 1, function() self:LFTButton() self:EBCButton() self:ArrangeButtons() + self:CreateInstanceJournalStandaloneButton() + self:PositionInstanceJournalStandaloneButton(self.buttonSpacing) + self:ApplyInstanceJournalStandaloneStyle(DFRL:GetTempDB("Micro", "switchColor")) self:HideOtherUI() self:DisableBlizzardFPS() @@ -423,6 +492,7 @@ DFRL:NewMod("Micro", 1, function() end DFRL.microMenuContainer:SetWidth((Setup.buttonWidth + value) * table.getn(Setup.buttons)) + Setup:PositionInstanceJournalStandaloneButton(value) end end @@ -615,6 +685,7 @@ DFRL:NewMod("Micro", 1, function() end end + Setup:ApplyInstanceJournalStandaloneStyle(value) callbacks.microColor(DFRL:GetTempDB("Micro", "microColor")) end diff --git a/modules/track/track.lua b/modules/track/track.lua index 9a9d472..1dc3e44 100644 --- a/modules/track/track.lua +++ b/modules/track/track.lua @@ -13,6 +13,7 @@ DFRL:NewMod("UpdateNotifier", 1, function() txt2 = nil, dd = nil, btn = nil, + closeBtn = nil, } function Setup:ParseDate(dateStr) @@ -102,6 +103,36 @@ DFRL:NewMod("UpdateNotifier", 1, function() DFRL.tools.MoveFrame(self.frame, 0, 1, .3, 120) end) end + + if not self.closeBtn then + self.closeBtn = CreateFrame("Button", nil, self.frame) + self.closeBtn:SetWidth(18) + self.closeBtn:SetHeight(18) + self.closeBtn:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -6, -6) + self.closeBtn:SetFrameStrata(self.frame:GetFrameStrata()) + + self.closeBtn.text = self.closeBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal") + self.closeBtn.text:SetAllPoints() + self.closeBtn.text:SetText("X") + + self.closeBtn:SetScript("OnEnter", function() + if self.closeBtn.text then + self.closeBtn.text:SetTextColor(1, 0.2, 0.2) + end + end) + + self.closeBtn:SetScript("OnLeave", function() + if self.closeBtn.text then + self.closeBtn.text:SetTextColor(1, 0.82, 0) + end + end) + + self.closeBtn:SetScript("OnClick", function() + DFRL.tools.MoveFrame(self.frame, 0, 1, .3, 120) + end) + + self.closeBtn.text:SetTextColor(1, 0.82, 0) + end end function Setup:Run() From 5a999e3cc4744f2b3c95e06ac708e3a8c4bd6591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rudaz=20No=C3=A9?= Date: Mon, 30 Mar 2026 02:23:03 +0200 Subject: [PATCH 2/3] Improve pet bar layout, add profile save, and expand French localization --- DragonflightUI-Reforged.toc | 3 ++ core/locale.lua | 33 ++++++++++++++++++ modules/bars/bars.lua | 68 +++++++++++++++++++++++++++++++++++++ modules/gui/prof.lua | 4 +++ 4 files changed, 108 insertions(+) diff --git a/DragonflightUI-Reforged.toc b/DragonflightUI-Reforged.toc index 4e6213d..2a167b6 100644 --- a/DragonflightUI-Reforged.toc +++ b/DragonflightUI-Reforged.toc @@ -9,7 +9,10 @@ # CORE core\error.lua core\core.lua +<<<<<<< HEAD core\debug.lua +======= +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) core\locale.lua core\tools.lua core\statusbar.lua diff --git a/core/locale.lua b/core/locale.lua index 067f929..84fc2b9 100644 --- a/core/locale.lua +++ b/core/locale.lua @@ -163,6 +163,7 @@ DFRL.locale.translations.frFR = { ["Color text based on resource (mana/rage/energy) percentage from white to red"] = "Colore le texte selon le pourcentage de ressource (mana/rage/energie), du blanc au rouge", ["Colorize the PizzaWorldBuffs Alliance/Horde text"] = "Colorise le texte Alliance/Horde de PizzaWorldBuffs", ["Combat Effects"] = "Effets de combat", +<<<<<<< HEAD ["Copy"] = "Copier", ["Compact Horizontal"] = "Compact horizontal", ["Compact Vertical"] = "Compact vertical", @@ -181,12 +182,19 @@ DFRL.locale.translations.frFR = { ["Vertical Down"] = "Vertical vers le bas", ["Vertical Up"] = "Vertical vers le haut", ["Vertical modes are especially useful for compact hunter layouts"] = "Les modes verticaux sont particulierement utiles pour les chasseurs avec une interface compacte", +======= + ["Copy"] = "Copie", +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Current"] = "Actuel", ["CURRENT PROFILE RESET"] = "PROFIL ACTUEL REINITIALISE", ["Dark Mode"] = "Mode sombre", ["Database Version:"] = "Version base de donnees :", ["Default"] = "Defaut", +<<<<<<< HEAD ["Delete"] = "Supprimer", +======= + ["Delete"] = "Supp.", +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["deleted"] = "supprime", ["dfrl evolved"] = "dfrl evolved", ["dfrl nebula"] = "dfrl nebula", @@ -215,7 +223,10 @@ DFRL.locale.translations.frFR = { ["font"] = "Police", ["FPS:"] = "FPS :", ["Francais"] = "Francais", +<<<<<<< HEAD ["Français"] = "Francais", +======= +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["GUI-Dragonflight"] = "Interface generale", ["Health Bar"] = "Barre de vie", ["Health Bars"] = "Barres de vie", @@ -294,12 +305,20 @@ DFRL.locale.translations.frFR = { ["Reload UI"] = "Recharger l'UI", ["reputation Bar"] = "Barre de reputation", ["Requires ShaguTweaks"] = "Necessite ShaguTweaks", +<<<<<<< HEAD ["Reset"] = "Reinitialiser", +======= + ["Reset"] = "Reinit.", +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Resting Effects"] = "Effets de repos", ["Resume Game"] = "Reprendre le jeu", ["right"] = "droite", ["RIGHT"] = "DROITE", +<<<<<<< HEAD ["Save Profile"] = "Enregistrer le profil", +======= + ["Save Profile"] = "Sauver profil", +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Script"] = "Script", ["Select the language used in the configuration UI"] = "Choisit la langue utilisee dans l'interface de configuration", ["Set fill direction"] = "Definit la direction de remplissage", @@ -354,7 +373,11 @@ DFRL.locale.translations.frFR = { ["Status"] = "Statut", ["Supported Addons"] = "Addons pris en charge", ["Swap the anchorpoint of the paging buttons"] = "Inverse le point d'ancrage des boutons de pagination", +<<<<<<< HEAD ["Switch"] = "Activer", +======= + ["Switch"] = "Act.", +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Switch between gray and colorfull micro menu"] = "Bascule entre le micro-menu gris ou colore", ["switched to"] = "profil actif :", ["System"] = "Systeme", @@ -385,6 +408,7 @@ DFRL.locale.translations.frFR = { ["Use the alternative gryphon/wyvern textures"] = "Utilise les textures alternatives gryphon/wyvern", ["Xprep"] = "XP/Reputation", +<<<<<<< HEAD ["Navigation"] = "Navigation", ["Drag to move - ESC to close"] = "Glisser pour deplacer - ECHAP pour fermer", ["Profiles help text"] = "Utilisation :\n\n1) Nouveau profil : creer et activer un nouveau profil\n2) Activer : changer le profil actif\n3) Copier : copier tous les reglages vers le profil actif\n4) Supprimer : supprimer le profil et revenir sur Defaut\n5) Reinitialiser : restaurer les reglages du profil actif\n\nRemarque : n'affecte pas ShaguTweaks.", @@ -396,6 +420,8 @@ DFRL.locale.translations.frFR = { ["Switch"] = "Activer", ["Copy"] = "Copier", ["Reset"] = "Reinitialiser", +======= +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Adjusts background alpha of XP and reputation bars"] = "Ajuste l'alpha de fond des barres d'XP et de reputation", ["Adjusts font size of the zone text"] = "Ajuste la taille de police du texte de zone", ["Adjusts horizontal position of gryphon/wyvern decorations"] = "Ajuste la position horizontale des decorations gryphon/wyvern", @@ -501,11 +527,14 @@ DFRL.locale.configLabels.frFR = { ["Bars.petbarGrid"] = "Grille barre familier", ["Bars.petbarScale"] = "Echelle barre familier", ["Bars.petbarSpacing"] = "Espacement barre familier", +<<<<<<< HEAD ["Bars.petbarOrientation"] = "Orientation barre familier", ["Bars.petbarButtonSize"] = "Taille boutons familier", ["Bars.petbarPreset"] = "Preset barre familier", ["Bars.petbarAutoCastAlpha"] = "Intensite glow auto-cast", ["Bars.petbarShineAlpha"] = "Intensite shine auto-cast", +======= +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) ["Bars.shapeshiftAlpha"] = "Transparence metamorphose", ["Bars.shapeshiftScale"] = "Echelle metamorphose", ["Bars.shapeshiftSpacing"] = "Espacement metamorphose", @@ -805,8 +834,12 @@ function DFRL:TranslateWords(text) local result = {} for token in string.gfind(text, "%S+") do +<<<<<<< HEAD local core = string.gsub(token, "([%.,:;!%?])$", "") local _, _, punct = string.find(token, "([%.,:;!%?])$") +======= + local core, punct = string.gsub(token, "([%.,:;!%?])$", ""), string.match(token, "([%.,:;!%?])$") +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) local lookup = string.lower(core or token) local translated = map[lookup] or core table.insert(result, translated .. (punct or "")) diff --git a/modules/bars/bars.lua b/modules/bars/bars.lua index 236c982..59575cc 100644 --- a/modules/bars/bars.lua +++ b/modules/bars/bars.lua @@ -55,6 +55,7 @@ DFRL:NewDefaults("Bars", { petbarSpacing = {6, "slider", {0.1, 20}, nil, "pet bar", 52, "Adjusts spacing between pet action bar buttons", nil, nil}, petbarAlpha = {1, "slider", {0.1, 1}, nil, "pet bar", 53, "Adjusts transparency of pet action bar", nil, nil}, petbarGrid = {1, "slider", {1, 6}, nil, "pet bar", 54, "Changes the grid layout of pet action bar", "5 = 2 columns x 5 rows", nil}, +<<<<<<< HEAD petbarOrientation = {"Horizontal", "dropdown", {"Horizontal", "Vertical Down", "Vertical Up"}, nil, "pet bar", 55, "Choose how the pet bar grows when using a single row layout", "Vertical modes are especially useful for compact hunter layouts", nil}, petbarButtonSize = {30, "slider", {20, 40}, nil, "pet bar", 56, "Adjusts the size of pet action bar buttons", nil, nil}, petbarPreset = {"Custom", "dropdown", {"Custom", "Default", "Compact Vertical", "Compact Horizontal", "Grid 2x5"}, nil, "pet bar", 57, "Apply a quick preset for the pet bar", nil, nil}, @@ -63,6 +64,11 @@ DFRL:NewDefaults("Bars", { shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 60, "Adjusts the scale of the shapeshift bar", nil, nil}, shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 61, "Adjusts spacing between shapeshift buttons", nil, nil}, shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 62, "Adjusts transparency of shapeshift bar", nil, nil}, +======= + shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 55, "Adjusts the scale of the shapeshift bar", nil, nil}, + shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 56, "Adjusts spacing between shapeshift buttons", nil, nil}, + shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 57, "Adjusts transparency of shapeshift bar", nil, nil}, +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) }) DFRL:NewMod("Bars", 1, function() @@ -370,12 +376,18 @@ DFRL:NewMod("Bars", 1, function() local autoCast = button.AutoCastable or _G[name .. "AutoCastable"] local autoCast2 = button.AutoCast or _G[name .. "AutoCast"] +<<<<<<< HEAD local shineAlpha = DFRL:GetTempDB('Bars', 'petbarShineAlpha') or 0.28 local autoCastAlpha = DFRL:GetTempDB('Bars', 'petbarAutoCastAlpha') or 0.40 softenTexture(shine, shineAlpha) softenTexture(autoCast, autoCastAlpha) softenTexture(autoCast2, autoCastAlpha) +======= + softenTexture(shine, 0.28) + softenTexture(autoCast, 0.40) + softenTexture(autoCast2, 0.40) +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) end end end @@ -386,6 +398,7 @@ DFRL:NewMod("Bars", 1, function() self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE") self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE_USABLE") self.petBarAutoCastFrame:RegisterEvent("PET_UI_UPDATE") +<<<<<<< HEAD self.petBarAutoCastFrame:SetScript("OnEvent", function() if DFRL.DebugLog then DFRL:DebugLog('bars', 'PetBarAutoCastEvent', event or 'nil', arg1 or 'nil') @@ -399,6 +412,15 @@ DFRL:NewMod("Bars", 1, function() elapsed = elapsed + (arg1 or 0) if elapsed > 1 then this:SetScript('OnUpdate', nil) +======= + self.petBarAutoCastFrame:SetScript("OnEvent", applyPetAutoCastLook) + + local elapsed = 0 + self.petBarAutoCastFrame:SetScript("OnUpdate", function() + elapsed = elapsed + arg1 + if elapsed > 0.25 then + elapsed = 0 +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) applyPetAutoCastLook() end end) @@ -639,8 +661,14 @@ DFRL:NewMod("Bars", 1, function() end end, +<<<<<<< HEAD normalizeLayoutIndex = function(value) local layoutIndex = math.floor((value or 1) + 0.5) +======= + setGridLayout = function(barFrame, buttonPrefix, value, spacingKey, maxButtons) + maxButtons = maxButtons or 12 + local layoutIndex = math.floor(value + 0.5) +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) if layoutIndex < 1 then layoutIndex = 1 end if layoutIndex > 6 then layoutIndex = 6 end return layoutIndex @@ -654,6 +682,7 @@ DFRL:NewMod("Bars", 1, function() local spacing = DFRL:GetTempDB('Bars', spacingKey) local firstButton = _G[buttonPrefix .. '1'] +<<<<<<< HEAD if not firstButton then if DFRL.DebugLog then DFRL:DebugLog('bars', 'GridLayoutSkipped', buttonPrefix, 'button 1 missing') @@ -669,6 +698,15 @@ DFRL:NewMod("Bars", 1, function() DFRL:DebugLog('bars', 'GridLayout', buttonPrefix, 'layout', layoutIndex, 'cols', effectiveCols, 'rows', effectiveRows, 'spacing', spacing) end +======= + if not firstButton then return end + local buttonSize = firstButton:GetWidth() + local isReversed = buttonPrefix == 'MultiBarLeftButton' or buttonPrefix == 'MultiBarRightButton' + local isPetBar = buttonPrefix == 'PetActionButton' + local effectiveCols = math.min(layout.cols, maxButtons) + local effectiveRows = math.ceil(maxButtons / effectiveCols) + +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) for i = (isReversed and maxButtons or 1), (isReversed and 1 or maxButtons), (isReversed and -1 or 1) do local button = _G[buttonPrefix .. i] if button then @@ -676,12 +714,22 @@ DFRL:NewMod("Bars", 1, function() local index = isReversed and (maxButtons + 1 - i) or i local row = math.floor((index - 1) / effectiveCols) local col = (index - 1) - (row * effectiveCols) +<<<<<<< HEAD button:SetPoint('BOTTOMLEFT', barFrame, 'BOTTOMLEFT', col * (buttonSize + spacing), row * (buttonSize + spacing)) +======= + + if isPetBar and effectiveRows > 1 then + button:SetPoint('TOPLEFT', barFrame, 'TOPLEFT', col * (buttonSize + spacing), -row * (buttonSize + spacing)) + else + button:SetPoint('BOTTOMLEFT', barFrame, 'BOTTOMLEFT', col * (buttonSize + spacing), row * (buttonSize + spacing)) + end +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) end end barFrame:SetHeight((buttonSize + spacing) * effectiveRows - spacing) barFrame:SetWidth((buttonSize + spacing) * effectiveCols - spacing) +<<<<<<< HEAD end, applyPetBarButtonSize = function(size) @@ -757,6 +805,8 @@ DFRL:NewMod("Bars", 1, function() if DFRL.DebugLog then DFRL:DebugLog('bars', 'PetBarLayout', 'grid', layoutIndex, 'orientation', orientation, 'cols', cols, 'rows', rows, 'size', buttonSize, 'spacing', spacing) end +======= +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) end, iterateButtons = function(callback) @@ -1130,7 +1180,21 @@ DFRL:NewMod("Bars", 1, function() end callbacks.petbarSpacing = function(value) +<<<<<<< HEAD helpers.applyPetBarLayout() +======= + local gridLayout = DFRL:GetTempDB('Bars', 'petbarGrid') + if math.floor(gridLayout + 0.5) ~= 1 then + helpers.setGridLayout(DFRL.newPetBar, 'PetActionButton', gridLayout, 'petbarSpacing', 10) + return + end + helpers.setSpacing('PetActionButton', value, 'horizontal', 10) + if DFRL.newPetBar and PetActionButton1 then + local buttonSize = PetActionButton1:GetWidth() + DFRL.newPetBar:SetWidth((buttonSize + value) * 10 - value) + DFRL.newPetBar:SetHeight(buttonSize) + end +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) end callbacks.petbarAlpha = function(value) @@ -1315,7 +1379,11 @@ DFRL:NewMod("Bars", 1, function() callbacks.petbarGrid = function(value) if not DFRL.newPetBar then return end +<<<<<<< HEAD helpers.applyPetBarLayout() +======= + helpers.setGridLayout(DFRL.newPetBar, 'PetActionButton', value, 'petbarSpacing', 10) +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) end callbacks.mainBarScale = function(value) diff --git a/modules/gui/prof.lua b/modules/gui/prof.lua index 2f9ce2f..eecc579 100644 --- a/modules/gui/prof.lua +++ b/modules/gui/prof.lua @@ -321,7 +321,11 @@ DFRL:NewMod("Gui-prof", 4, function() end if not self.ui.saveBtn then +<<<<<<< HEAD self.ui.saveBtn = DFRL.tools.CreateButton(panel, "Save Profile", 130, 30, true, {0.5, 1, 0.5}) +======= + self.ui.saveBtn = DFRL.tools.CreateButton(panel, "Save Profile", 120, 30, true, {0.5, 1, 0.5}) +>>>>>>> 1129cc9 (Add pet bar improvements + FR + profile save) self.ui.saveBtn:SetPoint("TOPLEFT", self.ui.resetBtn, "BOTTOMLEFT", 0, -10) self.ui.saveBtn:SetScript("OnClick", function() DFRL:SaveTempDB() From 8185c54c6bf418ce5dd6d454a2d5911f9607019d Mon Sep 17 00:00:00 2001 From: rudaznoe Date: Sat, 4 Apr 2026 23:08:56 +0200 Subject: [PATCH 3/3] Fix PvP micro menu icon (was using wrong fallback icon) fix(ui): correct PvP micro menu icon The PvP button was using a fallback icon (Instance Journal), causing visual inconsistency in the micro menu. This change assigns a proper PvP icon while keeping the original button styling and behavior intact (no texture override). --- DragonflightUI-Reforged.toc | 2 + core/core.lua | 50 +- core/debug.lua | 146 +++ core/locale.lua | 848 ++++++++++++++++++ .../color_micro/instancejournal-faded.tga | Bin 0 -> 65580 bytes .../color_micro/instancejournal-highlight.tga | Bin 0 -> 65580 bytes .../color_micro/instancejournal-regular.tga | Bin 0 -> 65580 bytes modules/bars/bars.lua | 275 +++++- modules/gui/base.lua | 111 ++- modules/gui/elem.lua | 24 +- modules/gui/homeb.lua | 17 + modules/gui/info.lua | 4 +- modules/gui/mods.lua | 2 +- modules/gui/prof.lua | 75 +- modules/gui/shag.lua | 4 +- modules/gui/tools.lua | 158 +++- modules/micro/micro.lua | 71 ++ modules/track/track.lua | 31 + 18 files changed, 1701 insertions(+), 117 deletions(-) create mode 100644 core/debug.lua create mode 100644 core/locale.lua create mode 100644 media/tex/micromenu/color_micro/instancejournal-faded.tga create mode 100644 media/tex/micromenu/color_micro/instancejournal-highlight.tga create mode 100644 media/tex/micromenu/color_micro/instancejournal-regular.tga diff --git a/DragonflightUI-Reforged.toc b/DragonflightUI-Reforged.toc index 297e12d..7e7d5c4 100644 --- a/DragonflightUI-Reforged.toc +++ b/DragonflightUI-Reforged.toc @@ -9,6 +9,8 @@ # CORE core\error.lua core\core.lua +core\debug.lua +core\locale.lua core\tools.lua core\statusbar.lua core\compat.lua diff --git a/core/core.lua b/core/core.lua index 605bbc0..cde3958 100644 --- a/core/core.lua +++ b/core/core.lua @@ -18,6 +18,7 @@ DFRL.callbacks = {} DFRL.performance = {} DFRL.activeScripts = {} DFRL.gui = {} +DFRL.debug = {} -- db version DFRL.DBversion = "1.0" @@ -180,6 +181,9 @@ end function DFRL:SetTempDB(mod, key, value) self.tempDB[mod][key] = value + if self.DebugLog then + self:DebugLog('db', 'SetTempDB', mod, key, value) + end local cb = mod .. "_" .. key .. "_changed" self:TriggerCallback(cb, value) end @@ -234,6 +238,9 @@ end function DFRL:SwitchProfile(name) local char = UnitName("player") local old = DFRL_CUR_PROFILE[char] + if self.DebugLog then + self:DebugLog('profile', 'SwitchProfile', old or 'nil', '->', name or 'nil') + end DFRL_PROFILES[old] = self.tempDB DFRL_CUR_PROFILE[char] = name self:LoadProfile(name) @@ -256,6 +263,9 @@ function DFRL:CopyProfile(from, tbl) end function DFRL:LoadProfile(name) + if self.DebugLog then + self:DebugLog('profile', 'LoadProfile', name or 'nil') + end self.tempDB = {} for mod, data in pairs(DFRL_PROFILES[name]) do self.tempDB[mod] = {} @@ -278,6 +288,10 @@ function DFRL:NewCallbacks(mod, callbacks) self.callbacks[cb] = {} tinsert(self.callbacks[cb], func) + if self.DebugLog then + self:DebugLog('callback', 'Register', cb) + end + self:TriggerCallback(cb, self.tempDB[mod][key]) count = count + 1 @@ -285,19 +299,53 @@ function DFRL:NewCallbacks(mod, callbacks) end function DFRL:TriggerCallback(cb, value) + if not self.callbacks[cb] then return end + if self.DebugLog then + self:DebugLog('callback', 'Trigger', cb, value) + end for _, func in ipairs(self.callbacks[cb]) do func(value) end end function DFRL:TriggerAllCallbacks() - for cb, callbacks in pairs(self.callbacks) do + local ordered = {} + for cb in pairs(self.callbacks) do + tinsert(ordered, cb) + end + + table.sort(ordered, function(a, b) + local aGrid = string.find(a, 'Grid_changed$') ~= nil + local bGrid = string.find(b, 'Grid_changed$') ~= nil + if aGrid ~= bGrid then + return aGrid + end + + local aSpacing = string.find(a, 'Spacing_changed$') ~= nil + local bSpacing = string.find(b, 'Spacing_changed$') ~= nil + if aSpacing ~= bSpacing then + return not aSpacing + end + + return a < b + end) + + if self.DebugLog then + self:DebugLog('callback', 'TriggerAllCallbacks', table.getn(ordered)) + end + + for _, cb in ipairs(ordered) do + local callbacks = self.callbacks[cb] local name = string.gsub(cb, "_changed$", "") local pos = string.find(name, "_[^_]*$") local mod = string.sub(name, 1, pos - 1) local key = string.sub(name, pos + 1) local value = self.tempDB[mod] and self.tempDB[mod][key] + if self.DebugLog then + self:DebugLog('callback', 'TriggerAll', cb, value) + end + for _, func in ipairs(callbacks) do func(value) end diff --git a/core/debug.lua b/core/debug.lua new file mode 100644 index 0000000..3fd33d0 --- /dev/null +++ b/core/debug.lua @@ -0,0 +1,146 @@ +-- debug system +DFRL.debug.enabled = false +DFRL.debug.maxEntries = 250 +DFRL.debug.buffer = {} +DFRL.debug.categories = { + callback = true, + profile = true, + bars = true, + db = true, + gui = true +} + +local function dbg_tostring(value) + if value == nil then return 'nil' end + local kind = type(value) + if kind == 'boolean' then + return value and 'true' or 'false' + elseif kind == 'number' then + return string.format('%.3f', value) + elseif kind == 'string' then + return value + elseif kind == 'table' then + return '
' + elseif kind == 'function' then + return '' + end + return tostring(value) +end + +local function dbg_echo(msg) + if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then + DEFAULT_CHAT_FRAME:AddMessage('|cff33ff99DFRL DEBUG:|r ' .. msg) + end +end + +function DFRL:DebugStatusText() + local state = self.debug.enabled and 'ON' or 'OFF' + return 'debug=' .. state .. ', entries=' .. table.getn(self.debug.buffer) +end + +function DFRL:SetDebugEnabled(enabled) + self.debug.enabled = enabled and true or false + if not DFRL_DB_SETUP then DFRL_DB_SETUP = {} end + DFRL_DB_SETUP.debugEnabled = self.debug.enabled + dbg_echo(self:DebugStatusText()) +end + +function DFRL:SetDebugCategory(category, enabled) + if not category or category == '' then return end + self.debug.categories[category] = enabled and true or false + dbg_echo(category .. '=' .. (enabled and 'ON' or 'OFF')) +end + +function DFRL:ClearDebugLog() + self.debug.buffer = {} + dbg_echo('buffer cleared') +end + +function DFRL:DumpDebugLog(limit, category) + local total = table.getn(self.debug.buffer) + if total == 0 then + dbg_echo('buffer empty') + return + end + + local count = tonumber(limit) or 20 + if count < 1 then count = 1 end + if count > total then count = total end + + local startIndex = total - count + 1 + for i = startIndex, total do + local entry = self.debug.buffer[i] + if not category or category == '' or entry.category == category then + dbg_echo(string.format('#%d [%s] %s', i, entry.category, entry.message)) + end + end +end + +function DFRL:DebugLog(category, ...) + category = category or 'misc' + if self.debug.categories[category] == false then + return + end + + local parts = {} + for i = 1, select('#', ...) do + parts[i] = dbg_tostring(select(i, ...)) + end + + local message = table.concat(parts, ' | ') + local stamp = date('%H:%M:%S') + local entry = { + time = stamp, + category = category, + message = stamp .. ' | ' .. message + } + + tinsert(self.debug.buffer, entry) + while table.getn(self.debug.buffer) > self.debug.maxEntries do + tremove(self.debug.buffer, 1) + end + + if self.debug.enabled then + dbg_echo('[' .. category .. '] ' .. entry.message) + end +end + +local function handle_debug_command(msg) + local _, _, command, arg1, arg2 = string.find(msg or '', '^(%S*)%s*(%S*)%s*(.-)$') + command = string.lower(command or '') + + if command == '' or command == 'help' then + dbg_echo('/dfrldebug on | off | status | clear') + dbg_echo('/dfrldebug dump [count] [category]') + dbg_echo('/dfrldebug cat ') + return + elseif command == 'on' then + DFRL:SetDebugEnabled(true) + elseif command == 'off' then + DFRL:SetDebugEnabled(false) + elseif command == 'status' then + dbg_echo(DFRL:DebugStatusText()) + elseif command == 'clear' then + DFRL:ClearDebugLog() + elseif command == 'dump' then + DFRL:DumpDebugLog(arg1, arg2) + elseif command == 'cat' then + DFRL:SetDebugCategory(arg1, string.lower(arg2 or '') == 'on') + else + dbg_echo('unknown command: ' .. command) + end +end + +_G['SLASH_DFRLDEBUG1'] = '/dfrldebug' +_G['SLASH_DFRLDEBUG2'] = '/dfdebug' +_G.SlashCmdList['DFRLDEBUG'] = handle_debug_command + +local debugBootstrap = CreateFrame('Frame') +debugBootstrap:RegisterEvent('PLAYER_LOGIN') +debugBootstrap:SetScript('OnEvent', function() + if DFRL_DB_SETUP and DFRL_DB_SETUP.debugEnabled then + DFRL.debug.enabled = true + dbg_echo(DFRL:DebugStatusText()) + end + DFRL:DebugLog('gui', 'Debug system ready') +end) diff --git a/core/locale.lua b/core/locale.lua new file mode 100644 index 0000000..067f929 --- /dev/null +++ b/core/locale.lua @@ -0,0 +1,848 @@ +DFRL.locale = DFRL.locale or {} +DFRL.locale.translations = DFRL.locale.translations or {} +DFRL.locale.configLabels = DFRL.locale.configLabels or {} +DFRL.locale.wordMap = DFRL.locale.wordMap or {} + +DFRL.locale.translations.frFR = { + ["5 = 2 columns x 5 rows"] = "5 = 2 colonnes x 5 lignes", + ["Actionbars"] = "Barres d'action", + ["Activate 2D class portrait icons"] = "Active les portraits de classe 2D", + ["Active Modules:"] = "Modules actifs :", + ["Active Scripts"] = "Scripts actifs", + ["Addon"] = "Addon", + ["Addon Manager"] = "Gestionnaire d'addons", + ["Addon Version:"] = "Version addon :", + ["Adjust dark mode intensity"] = "Ajuste l'intensite du mode sombre", + ["Adjust frame size"] = "Ajuste la taille du cadre", + ["Adjust party frame size"] = "Ajuste la taille du cadre de groupe", + ["Adjust pet frame size"] = "Ajuste la taille du cadre du familier", + ["Adjust range indicator opacity"] = "Ajuste l'opacite de l'indicateur de portee", + ["Adjust target of target frame size"] = "Ajuste la taille du cadre de la cible de la cible", + ["Adjust the maximum alpha of the combat pulsing"] = "Ajuste l'alpha maximal de la pulsation de combat", + ["Adjust the maximum alpha of the resting pulsing"] = "Ajuste l'alpha maximal de la pulsation de repos", + ["Adjust the speed of the combat pulsing"] = "Ajuste la vitesse de la pulsation de combat", + ["Adjust the speed of the resting pulsing"] = "Ajuste la vitesse de la pulsation de repos", + ["Adjust X offset of the tooltip"] = "Ajuste le decalage X de l'infobulle", + ["Adjust Y offset of the tooltip"] = "Ajuste le decalage Y de l'infobulle", + ["Adjusts background alpha of XP and reputation bars"] = "Adjusts background alpha of XP and reputation bars", + ["Adjusts font size of the time display"] = "Ajuste la taille de police de l'affichage de l'heure", + ["Adjusts font size of the zone text"] = "Ajuste la taille de police de le texte de zone", + ["Adjusts horizontal position of gryphon/wyvern decorations"] = "Ajuste la position horizontale de gryphon/wyvern decorations", + ["Adjusts horizontal position of keybind text"] = "Ajuste la position horizontale de keybind text", + ["Adjusts horizontal position of macro text"] = "Ajuste la position horizontale de macro text", + ["Adjusts horizontal position of paging buttons"] = "Ajuste la position horizontale de les boutons de pagination", + ["Adjusts horizontal position of the time display"] = "Ajuste la position horizontale de l'affichage de l'heure", + ["Adjusts horizontal position of the zone text"] = "Ajuste la position horizontale de le texte de zone", + ["Adjusts horizontal position of zoom buttons"] = "Ajuste la position horizontale de les boutons de zoom", + ["Adjusts scale of bottom left action bar"] = "Ajuste l'echelle de la barre d'action bas gauche", + ["Adjusts scale of bottom right action bar"] = "Ajuste l'echelle de la barre d'action bas droite", + ["Adjusts scale of left action bar"] = "Ajuste l'echelle de la barre d'action gauche", + ["Adjusts scale of right action bar"] = "Ajuste l'echelle de la barre d'action droite", + ["Adjusts size of zoom buttons"] = "Ajuste la taille de les boutons de zoom", + ["Adjusts spacing between bottom left action bar buttons"] = "Ajuste l'espacement entre bottom left action bar buttons", + ["Adjusts spacing between bottom right action bar buttons"] = "Ajuste l'espacement entre bottom right action bar buttons", + ["Adjusts spacing between left action bar buttons"] = "Ajuste l'espacement entre left action bar buttons", + ["Adjusts spacing between main action bar buttons"] = "Ajuste l'espacement entre main action bar buttons", + ["Adjusts spacing between micro menu buttons"] = "Ajuste l'espacement entre micro menu buttons", + ["Adjusts spacing between pet action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre du familier", + ["Adjusts spacing between right action bar buttons"] = "Ajuste l'espacement entre right action bar buttons", + ["Adjusts spacing between shapeshift buttons"] = "Ajuste l'espacement entre les boutons de metamorphose", + ["Adjusts the font size of the reputation bar text"] = "Ajuste la taille de police de the reputation bar text", + ["Adjusts the font size of the XP bar text"] = "Ajuste la taille de police de the XP bar text", + ["Adjusts the height of the reputation bar"] = "Ajuste la hauteur de la barre de reputation", + ["Adjusts the height of the top panel"] = "Ajuste la hauteur de le panneau superieur", + ["Adjusts the height of the XP bar"] = "Ajuste la hauteur de la barre d'XP", + ["Adjusts the overall size of the minimap"] = "Ajuste la taille generale de la mini-carte", + ["Adjusts the scale of the main action bar"] = "Ajuste l'echelle de la barre d'action principale", + ["Adjusts the scale of the main backpack"] = "Ajuste l'echelle de le sac principal", + ["Adjusts the scale of the micro menu"] = "Ajuste l'echelle de le micro-menu", + ["Adjusts the scale of the paging buttons"] = "Ajuste l'echelle de les boutons de pagination", + ["Adjusts the scale of the pet action bar"] = "Ajuste l'echelle de la barre d'actions du familier", + ["Adjusts the scale of the shapeshift bar"] = "Ajuste l'echelle de la barre de metamorphose", + ["Adjusts the size of keybind text on action buttons"] = "Ajuste la taille de le texte des raccourcis sur les boutons d'action", + ["Adjusts the size of macro text on action buttons"] = "Ajuste la taille de le texte des macros sur les boutons d'action", + ["Adjusts the size of the gryphon/wyvern decorations"] = "Ajuste la taille de les decorations gryphon/wyvern", + ["Adjusts the transparency of all bags"] = "Ajuste la transparence de tous les sacs", + ["Adjusts the transparency of the micro menu"] = "Ajuste la transparence de le micro-menu", + ["Adjusts the width of the reputation bar"] = "Ajuste la largeur de la barre de reputation", + ["Adjusts the width of the top panel"] = "Ajuste la largeur de le panneau superieur", + ["Adjusts the width of the XP bar"] = "Ajuste la largeur de la barre d'XP", + ["Adjusts transparency of bottom left action bar"] = "Ajuste la transparence de la barre d'action bas gauche", + ["Adjusts transparency of bottom right action bar"] = "Ajuste la transparence de la barre d'action bas droite", + ["Adjusts transparency of gryphon/wyvern decorations"] = "Ajuste la transparence de gryphon/wyvern decorations", + ["Adjusts transparency of left action bar"] = "Ajuste la transparence de la barre d'action gauche", + ["Adjusts transparency of main action bar"] = "Ajuste la transparence de la barre d'action principale", + ["Adjusts transparency of pet action bar"] = "Ajuste la transparence de la barre du familier", + ["Adjusts transparency of right action bar"] = "Ajuste la transparence de la barre d'action droite", + ["Adjusts transparency of shapeshift bar"] = "Ajuste la transparence de la barre de metamorphose", + ["Adjusts transparency of the entire minimap"] = "Ajuste la transparence de toute la mini-carte", + ["Adjusts transparency of the minimap shadow"] = "Ajuste la transparence de l'ombre de la mini-carte", + ["Adjusts transparency of the reputation bar"] = "Ajuste la transparence de la barre de reputation", + ["Adjusts transparency of the XP bar"] = "Ajuste la transparence de la barre d'XP", + ["Adjusts transparency of zoom buttons"] = "Ajuste la transparence de les boutons de zoom", + ["Adjusts vertical position of gryphon/wyvern decorations"] = "Ajuste la position verticale de gryphon/wyvern decorations", + ["Adjusts vertical position of keybind text"] = "Ajuste la position verticale de keybind text", + ["Adjusts vertical position of macro text"] = "Ajuste la position verticale de macro text", + ["Adjusts vertical position of the time display"] = "Ajuste la position verticale de l'affichage de l'heure", + ["Adjusts vertical position of the zone text"] = "Ajuste la position verticale de le texte de zone", + ["Adjusts vertical position of zoom buttons"] = "Ajuste la position verticale de les boutons de zoom", + ["appearance"] = "Apparence", + ["Appearance"] = "Apparence", + ["Automatically track reputation for factions you gain reputation with"] = "Suit automatiquement la reputation des factions avec lesquelles vous gagnez de la reputation", + ["bag basic"] = "Sacs", + ["Bags"] = "Sacs", + ["Bars"] = "Barres d'action", + ["boss"] = "boss", + ["BUG: blizzards highlight blinks at the wrong position - fix soon"] = "BUG : la surbrillance Blizzard clignote au mauvais endroit - correctif a venir", + ["Bug: move char after setting (unfixable)"] = "Bug : bouger le personnage apres reglage (non corrigible)", + ["BUG: slash commands not implemented yet - fix soon"] = "BUG : les commandes slash ne sont pas encore implementees - correctif a venir", + ["Build Number:"] = "Numero de build :", + ["Cast"] = "Barre de cast", + ["Castbar"] = "Barre de cast", + ["castbar Basic"] = "Castbar", + ["center"] = "centre", + ["CENTER"] = "CENTRE", + ["Change all fonts in the GUI"] = "Change toutes les polices de l'interface", + ["Change bag color"] = "Change la couleur des sacs", + ["Change bars color"] = "Change la couleur des barres", + ["Change cast color"] = "Change la couleur de la barre de cast", + ["Change castbar font size"] = "Change la taille de police de la barre de cast", + ["Change castbar font Y offset"] = "Change le decalage Y de la police de la barre de cast", + ["Change castbar height"] = "Change la hauteur de la barre de cast", + ["Change castbar width"] = "Change la largeur de la barre de cast", + ["Change casting time X offset"] = "Change le decalage X du temps d'incantation", + ["Change chat color"] = "Change la couleur du chat", + ["Change map color"] = "Change la couleur de la carte", + ["Change micro color"] = "Change la couleur du micro-menu", + ["Change mini color"] = "Change la couleur des mini-cadres", + ["Change player color"] = "Change la couleur du cadre joueur", + ["Change spell name X offset"] = "Change le decalage X du nom du sort", + ["Change spell text alignment"] = "Change l'alignement du texte du sort", + ["Change target color"] = "Change la couleur du cadre cible", + ["Change the font used for all smaller frames"] = "Change la police utilisee pour all smaller frames", + ["Change the font used for the castbar"] = "Change la police utilisee pour la barre de cast", + ["Change the font used for the experience and reputation bar"] = "Change la police utilisee pour les barres d'experience et de reputation", + ["Change the font used for the hotkeys and macros"] = "Change la police utilisee pour les raccourcis et macros", + ["Change the font used for the minimap"] = "Change la police utilisee pour la mini-carte", + ["Change the font used for the playerframe"] = "Change la police utilisee pour le cadre joueur", + ["Change the font used for the targetframe"] = "Change la police utilisee pour le cadre cible", + ["Change xprep color"] = "Change la couleur des barres XP/Reputation", + ["Changes take effect after reload:"] = "Les changements prennent effet apres rechargement :", + ["Changes the alpha of the side view"] = "Change la transparence du panneau lateral", + ["Changes the color of the close and min button"] = "Change la couleur des boutons Fermer/Mini", + ["Changes the color of the time on the home screen"] = "Change la couleur de l'heure sur l'ecran d'accueil", + ["Changes the colour of action button highlights"] = "Change la couleur de action button highlights", + ["Changes the colour of keybind text on action buttons"] = "Change la couleur de le texte des raccourcis sur les boutons d'action", + ["Changes the colour of macro text on action buttons"] = "Change la couleur de le texte des macros sur les boutons d'action", + ["Changes the colour of the resting glow animation"] = "Change la couleur de l'animation lumineuse de repos", + ["Changes the grid layout of bottom left action bar"] = "Change la disposition en grille de la barre d'action bas gauche", + ["Changes the grid layout of bottom right action bar"] = "Change la disposition en grille de la barre d'action bas droite", + ["Changes the grid layout of left action bar"] = "Change la disposition en grille de la barre d'action gauche", + ["Changes the grid layout of main action bar"] = "Change la disposition en grille de la barre d'action principale", + ["Changes the grid layout of pet action bar"] = "Change la disposition en grille de la barre du familier", + ["Changes the grid layout of right action bar"] = "Change la disposition en grille de la barre d'action droite", + ["Changes the scale of the mainframe"] = "Change l'echelle de la fenetre principale", + ["Changes the texture of the playerframe"] = "Change la texture de le cadre joueur", + ["Chat"] = "Chat", + ["chat basic"] = "Chat", + ["Client Version:"] = "Version client :", + ["close"] = "Fermer", + ["Collector"] = "Collecteur", + ["Color for cutout animation on all mini frames"] = "Couleur pour l'animation de decoupe sur tous les mini-cadres", + ["Color for damage cutout effect"] = "Couleur pour l'effet de decoupe des degats", + ["Color for pulse animation"] = "Couleur pour l'animation de pulsation", + ["Color for pulse animation on all mini frames"] = "Couleur pour l'animation de pulsation sur tous les mini-cadres", + ["Color health bar based on class"] = "Colore la barre de vie selon la classe", + ["Color health bar based on target class"] = "Colore la barre de vie selon la classe de la cible", + ["Color health bar based on target reaction"] = "Colore la barre de vie selon la reaction de la cible", + ["Color target of target and party health bars based on class"] = "Colore les barres de vie de la cible de la cible et du groupe selon la classe", + ["Color target of target health bars based on reaction"] = "Colore les barres de vie de la cible de la cible selon la reaction", + ["Color text based on health percentage"] = "Colore le texte selon le pourcentage de vie", + ["Color text based on health percentage from white to red"] = "Colore le texte selon le pourcentage de vie, du blanc au rouge", + ["Color text based on resource (mana/rage/energy) percentage"] = "Colore le texte selon le pourcentage de ressource (mana/rage/energie)", + ["Color text based on resource (mana/rage/energy) percentage from white to red"] = "Colore le texte selon le pourcentage de ressource (mana/rage/energie), du blanc au rouge", + ["Colorize the PizzaWorldBuffs Alliance/Horde text"] = "Colorise le texte Alliance/Horde de PizzaWorldBuffs", + ["Combat Effects"] = "Effets de combat", + ["Copy"] = "Copier", + ["Compact Horizontal"] = "Compact horizontal", + ["Compact Vertical"] = "Compact vertical", + ["Current profile reloaded"] = "Profil actuel recharge", + ["CURRENT PROFILE RELOADED"] = "PROFIL ACTUEL RECHARGE", + ["Custom"] = "Personnalise", + ["Choose how the pet bar grows when using a single row layout"] = "Choisit comment la barre du familier se deploie avec une disposition sur une seule ligne", + ["Default"] = "Defaut", + ["Grid 2x5"] = "Grille 2x5", + ["Horizontal"] = "Horizontal", + ["Reload Profile"] = "Recharger le profil", + ["Adjusts the size of pet action bar buttons"] = "Ajuste la taille des boutons de la barre du familier", + ["Adjusts the shine overlay of pet auto-cast visuals"] = "Ajuste la brillance de l'effet visuel d'auto-lancement du familier", + ["Adjusts the strength of the pet auto-cast glow"] = "Ajuste l'intensite de la lueur d'auto-lancement du familier", + ["Apply a quick preset for the pet bar"] = "Applique un preset rapide pour la barre du familier", + ["Vertical Down"] = "Vertical vers le bas", + ["Vertical Up"] = "Vertical vers le haut", + ["Vertical modes are especially useful for compact hunter layouts"] = "Les modes verticaux sont particulierement utiles pour les chasseurs avec une interface compacte", + ["Current"] = "Actuel", + ["CURRENT PROFILE RESET"] = "PROFIL ACTUEL REINITIALISE", + ["Dark Mode"] = "Mode sombre", + ["Database Version:"] = "Version base de donnees :", + ["Default"] = "Defaut", + ["Delete"] = "Supprimer", + ["deleted"] = "supprime", + ["dfrl evolved"] = "dfrl evolved", + ["dfrl nebula"] = "dfrl nebula", + ["Dragonflight Info"] = "Infos Dragonflight", + ["elite"] = "elite", + ["Enable combat pulse animation"] = "Active l'animation de pulsation en combat", + ["Enable cutout animation on bars"] = "Active cutout animation on bars", + ["Enable cutout animation on damage for all mini frames"] = "Active l'animation de decoupe sur les degats pour tous les mini-cadres", + ["Enable dark mode for the character panel"] = "Active le mode sombre pour la fiche du personnage", + ["Enable dark mode for the game menu"] = "Active le mode sombre pour le menu du jeu", + ["Enable dark mode for the questlog"] = "Active le mode sombre pour le journal de quetes", + ["Enable fade in/out animation"] = "Active l'animation de fondu entree/sortie", + ["Enable or disable addon modules. Changes require UI reload to take effect."] = "Active ou desactive les modules de l'addon. Rechargement de l'UI requis pour appliquer les changements.", + ["Enable pulse animation on bars"] = "Active l'animation de pulsation sur les barres", + ["Enable pulse animation on low health for all mini frames"] = "Active l'animation de pulsation a faible vie pour tous les mini-cadres", + ["Enable resting glow animation"] = "Active l'animation lumineuse de repos", + ["English"] = "Anglais", + ["enter profile name"] = "entrer le nom du profil", + ["Errors"] = "Erreurs", + ["Exit Game"] = "Quitter le jeu", + ["experience Bar"] = "Barre d'XP", + ["ext. PizzaWorldBuffs"] = "Ext. PizzaWorldBuffs", + ["Extended maximum camera distance"] = "Etend la distance maximale de la camera", + ["Fade out chat text after 10 seconds"] = "Fait disparaitre progressivement le texte du chat apres 10 secondes", + ["Flip the gryphon/wyvern textures"] = "Inverse les textures gryphon/wyvern", + ["font"] = "Police", + ["FPS:"] = "FPS :", + ["Francais"] = "Francais", + ["Français"] = "Francais", + ["GUI-Dragonflight"] = "Interface generale", + ["Health Bar"] = "Barre de vie", + ["Health Bars"] = "Barres de vie", + ["Health text font size"] = "Taille de police du texte de vie", + ["Health threshold for low HP warning"] = "Seuil de vie pour alerte de PV faibles", + ["Hide frame at full HP when not in combat"] = "Masque le cadre a PV pleins hors combat", + ["Hide party health and mana percent text"] = "Masque le pourcentage de vie et mana du groupe", + ["Hide pet health and mana percent text"] = "Masque le pourcentage de vie et mana du familier", + ["Hide target of target health and mana percent text"] = "Masque le pourcentage de vie et mana de la cible de la cible", + ["Hide the top UI error message (e.g. 'Spell is not ready')"] = "Masque le message d'erreur de l'UI en haut (ex. 'Le sort n'est pas pret')", + ["Home"] = "Accueil", + ["Home Screen"] = "Ecran d'accueil", + ["Info"] = "Infos", + ["Installed"] = "Installe", + ["Interface"] = "Interface", + ["Key Bindings"] = "Raccourcis clavier", + ["Last Update:"] = "Derniere mise a jour :", + ["left"] = "gauche", + ["LEFT"] = "GAUCHE", + ["Level text font size"] = "Taille de police du texte de niveau", + ["Light Mode"] = "Mode clair", + ["Locale:"] = "Langue :", + ["localization"] = "Langue", + ["Logout"] = "Deconnexion", + ["Macros"] = "Macros", + ["mainbar"] = "Barre principale", + ["mainbar deco"] = "Decors barre principale", + ["mainbar paging"] = "Pagination barre principale", + ["Mana text font size"] = "Taille de police du texte de mana", + ["Manage"] = "Gestion", + ["Map"] = "Mini-carte", + ["map basic"] = "Mini-carte", + ["map shadow"] = "Ombre mini-carte", + ["map zoom"] = "Zoom mini-carte", + ["MAX PROFILES REACHED"] = "LIMITE DE PROFILS ATTEINTE", + ["Memory (kb)"] = "Memoire (kb)", + ["Menu"] = "Menu", + ["Micro"] = "Micro-menu", + ["micro basic"] = "Micro-menu", + ["Micromenu"] = "Micro-menu", + ["min"] = "Mini", + ["Mini"] = "Mini-cadres", + ["mini text settings"] = "Texte mini-cadres", + ["Minimap"] = "Mini-carte", + ["Module"] = "Module", + ["Modules"] = "Modules", + ["multibar 1"] = "Multi-barre 1", + ["multibar 2"] = "Multi-barre 2", + ["multibar 3"] = "Multi-barre 3", + ["multibar 4"] = "Multi-barre 4", + ["Name text font size"] = "Taille de police du texte du nom", + ["Never"] = "Jamais", + ["New Profile"] = "Nouv. profil", + ["new profile created"] = "nouveau profil cree", + ["Not installed"] = "Non installe", + ["OFF"] = "OFF", + ["Okay"] = "OK", + ["ON"] = "ON", + ["Only for Blizzards version"] = "Uniquement pour la version Blizzard", + ["Options"] = "Options", + ["Party Text"] = "Texte groupe", + ["Performance"] = "Performance", + ["pet bar"] = "Barre du familier", + ["Pet Text"] = "Texte familier", + ["Player"] = "Joueur", + ["Profile"] = "Profil", + ["profile copied from"] = "profil copie depuis", + ["PROFILE RESET FAILED"] = "ECHEC DE LA REINITIALISATION", + ["profile saved"] = "profil sauvegarde", + ["Profiles"] = "Profils", + ["PVPIcon"] = "Icone JcJ", + ["RangeIndicator"] = "Indicateur de portee", + ["rare"] = "rare", + ["rare-elite"] = "rare-elite", + ["Realm:"] = "Royaume :", + ["Reload UI"] = "Recharger l'UI", + ["reputation Bar"] = "Barre de reputation", + ["Requires ShaguTweaks"] = "Necessite ShaguTweaks", + ["Reset"] = "Reinitialiser", + ["Resting Effects"] = "Effets de repos", + ["Resume Game"] = "Reprendre le jeu", + ["right"] = "droite", + ["RIGHT"] = "DROITE", + ["Save Profile"] = "Enregistrer le profil", + ["Script"] = "Script", + ["Select the language used in the configuration UI"] = "Choisit la langue utilisee dans l'interface de configuration", + ["Set fill direction"] = "Definit la direction de remplissage", + ["SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS"] = "SHAGU TWEAKS EXTRAS MANQUANT\nINSTALLE-LE POUR PLUS D'OPTIONS", + ["ShaguTweaks"] = "ShaguTweaks", + ["shapeshift bar"] = "Barre de metamorphose", + ["Show Blzzards sun/moon indicator"] = "Affiche l'indicateur soleil/lune de Blizzard", + ["Show casting spell icon"] = "Affiche l'icone du sort en cours d'incantation", + ["Show casting time"] = "Affiche le temps d'incantation", + ["Show drop shadow below the castbar"] = "Affiche l'ombre portee sous la barre de cast", + ["Show energy and mana tick indicators"] = "Affiche les indicateurs de ticks d'energie et de mana", + ["Show health and mana text"] = "Affiche le texte de vie et de mana", + ["Show max health and mana text"] = "Affiche le texte de vie et mana max", + ["Show nameplates only in combat"] = "Affiche les plaques de nom uniquement en combat", + ["Show only current values without percentages"] = "Affiche uniquement les valeurs actuelles sans pourcentages", + ["Show or hide bags on mouse hover"] = "Affiche ou masque les sacs au survol de la souris", + ["Show or hide bottom left action bar"] = "Affiche ou masque la barre d'action bas gauche", + ["Show or hide bottom right action bar"] = "Affiche ou masque la barre d'action bas droite", + ["Show or hide chat buttons"] = "Affiche ou masque les boutons du chat", + ["Show or hide free bag slots"] = "Affiche ou masque les emplacements de sac libres", + ["Show or hide keybind text on action buttons"] = "Affiche ou masque le texte des raccourcis sur les boutons d'action", + ["Show or hide left side action bar"] = "Affiche ou masque la barre d'action laterale gauche", + ["Show or hide macro text on action buttons"] = "Affiche ou masque le texte des macros sur les boutons d'action", + ["Show or hide main action bar background"] = "Affiche ou masque le fond de la barre d'action principale", + ["Show or hide reputation text on the reputation bar"] = "Affiche ou masque le texte de reputation sur la barre de reputation", + ["Show or hide right side action bar"] = "Affiche ou masque la barre d'action laterale droite", + ["Show or hide the action bar paging buttons"] = "Affiche ou masque les boutons de pagination de la barre d'action", + ["Show or hide the bag frame"] = "Affiche ou masque le cadre des sacs", + ["Show or hide the bag toggle button"] = "Affiche ou masque le bouton de bascule des sacs", + ["Show or hide the gryphon/wyvern decorations"] = "Affiche ou masque les decorations gryphon/wyvern", + ["Show or hide the shadow inside the minimap"] = "Affiche ou masque l'ombre a l'interieur de la mini-carte", + ["Show or hide the small bag slots"] = "Affiche ou masque les petits emplacements de sac", + ["Show or hide the time display on the minimap"] = "Affiche ou masque l'affichage de l'heure sur la mini-carte", + ["Show or hide the top information panel"] = "Affiche ou masque le panneau d'information superieur", + ["Show or hide the XP bar"] = "Affiche ou masque la barre d'XP", + ["Show or hide XP text on the XP bar"] = "Affiche ou masque le texte d'XP sur la barre d'XP", + ["Show or hide zoom buttons on the minimap"] = "Affiche ou masque les boutons de zoom sur la mini-carte", + ["Show party max health and mana text"] = "Affiche le texte de vie et mana max du groupe", + ["Show pet max health and mana text"] = "Affiche le texte de vie et mana max du familier", + ["Show pet/target of target/party health and mana text"] = "Affiche le texte de vie et mana du familier / cible de la cible / groupe", + ["Show red border when health is low"] = "Affiche la bordure rouge quand la vie est basse", + ["Show reputation text for 5 seconds when gaining reputation"] = "Affiche le texte de reputation pendant 5 secondes lors d'un gain de reputation", + ["Show reputation text when hovering over the reputation bar"] = "Affiche le texte de reputation au survol de la barre de reputation", + ["Show smaller FPS/MS watcher (CTRL+R)"] = "Affiche smaller FPS/MS watcher (CTRL+R)", + ["Show spell name text"] = "Affiche le texte du nom du sort", + ["Show target of target max health and mana text"] = "Affiche le texte de vie et mana max de la cible de la cible", + ["Show the Minimap Square design"] = "Affiche le design carre de la mini-carte", + ["Show the tooltip above your cursor"] = "Affiche l'infobulle au-dessus du curseur", + ["Show XP text for 5 seconds when gaining XP"] = "Affiche le texte d'XP pendant 5 secondes lors d'un gain d'XP", + ["Show XP text when hovering over the XP bar"] = "Affiche le texte d'XP au survol de la barre d'XP", + ["standard"] = "standard", + ["Status"] = "Statut", + ["Supported Addons"] = "Addons pris en charge", + ["Swap the anchorpoint of the paging buttons"] = "Inverse le point d'ancrage des boutons de pagination", + ["Switch"] = "Activer", + ["Switch between gray and colorfull micro menu"] = "Bascule entre le micro-menu gris ou colore", + ["switched to"] = "profil actif :", + ["System"] = "Systeme", + ["Target"] = "Cible", + ["Target level text font size"] = "Taille de police du texte de niveau de la cible", + ["Target name text font size"] = "Taille de police du nom de la cible", + ["Target of Target Text"] = "Texte cible de la cible", + ["Text"] = "Texte", + ["text settings"] = "Texte", + ["Third Party"] = "Tiers", + ["Time (ms)"] = "Temps (ms)", + ["Tooltip"] = "Infobulles", + ["top panel"] = "Panneau superieur", + ["top panel time"] = "Heure mini-carte", + ["top panel zone"] = "Texte de zone", + ["TOTAL:"] = "TOTAL :", + ["tweaks"] = "Ajustements", + ["Ui"] = "Interface", + ["ui tweaks"] = "Ajustements UI", + ["Unitframes"] = "Cadres d'unite", + ["UpdateNotifier"] = "Notifications de maj", + ["Usage:\n\n\n1) new profile: create and switch to a new profile\n\n2) switch: change active profile\n\n3) copy: copies all settings into active profile\n\n4) delete: delete profile and switch back to default\n\n5)reset: reset active profile to the default settings\n\n\ndoes not affect shagutweaks\n\nBUG: DOUBLE CLICK DELETE AFTER NEW PROFILE\n\nBUG: ENTER PROFILE NAME STAYS"] = "Utilisation :\n\n\n1) nouveau profil : cree et active un nouveau profil\n\n2) activer : change le profil actif\n\n3) copier : copie tous les reglages dans le profil actif\n\n4) supprimer : supprime le profil et revient sur Defaut\n\n5) reinitialiser : remet le profil actif aux reglages par defaut\n\n\nn'affecte pas ShaguTweaks\n\nBUG : double clic sur supprimer apres un nouveau profil\n\nBUG : le nom du profil reste affiche", + ["Use 12-hour AM/PM time format instead of 24-hour"] = "Utilise le format horaire 12h AM/PM au lieu du 24h", + ["Use dark color for PvP icons"] = "Utilise la couleur sombre pour les icones JcJ", + ["Use dark color instead of red"] = "Utilise la couleur sombre au lieu du rouge", + ["Use original Blizzard chat buttons"] = "Utilise les boutons de chat Blizzard d'origine", + ["Use simple X instead of texture"] = "Utilise un X simple au lieu d'une texture", + ["Use the alternative gryphon/wyvern textures"] = "Utilise les textures alternatives gryphon/wyvern", + ["Xprep"] = "XP/Reputation", + + ["Navigation"] = "Navigation", + ["Drag to move - ESC to close"] = "Glisser pour deplacer - ECHAP pour fermer", + ["Profiles help text"] = "Utilisation :\n\n1) Nouveau profil : creer et activer un nouveau profil\n2) Activer : changer le profil actif\n3) Copier : copier tous les reglages vers le profil actif\n4) Supprimer : supprimer le profil et revenir sur Defaut\n5) Reinitialiser : restaurer les reglages du profil actif\n\nRemarque : n'affecte pas ShaguTweaks.", + ["Quick Actions"] = "Actions rapides", + ["Save Profile"] = "Enregistrer le profil", + ["Reload Profile"] = "Recharger le profil", + ["New Profile"] = "Nouveau profil", + ["Delete"] = "Supprimer", + ["Switch"] = "Activer", + ["Copy"] = "Copier", + ["Reset"] = "Reinitialiser", + ["Adjusts background alpha of XP and reputation bars"] = "Ajuste l'alpha de fond des barres d'XP et de reputation", + ["Adjusts font size of the zone text"] = "Ajuste la taille de police du texte de zone", + ["Adjusts horizontal position of gryphon/wyvern decorations"] = "Ajuste la position horizontale des decorations gryphon/wyvern", + ["Adjusts horizontal position of keybind text"] = "Ajuste la position horizontale du texte des raccourcis", + ["Adjusts horizontal position of macro text"] = "Ajuste la position horizontale du texte des macros", + ["Adjusts horizontal position of paging buttons"] = "Ajuste la position horizontale des boutons de pagination", + ["Adjusts horizontal position of the zone text"] = "Ajuste la position horizontale du texte de zone", + ["Adjusts horizontal position of zoom buttons"] = "Ajuste la position horizontale des boutons de zoom", + ["Adjusts size of zoom buttons"] = "Ajuste la taille des boutons de zoom", + ["Adjusts spacing between bottom left action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action bas gauche", + ["Adjusts spacing between bottom right action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action bas droite", + ["Adjusts spacing between left action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action gauche", + ["Adjusts spacing between main action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action principale", + ["Adjusts spacing between micro menu buttons"] = "Ajuste l'espacement entre les boutons du micro-menu", + ["Adjusts spacing between right action bar buttons"] = "Ajuste l'espacement entre les boutons de la barre d'action droite", + ["Adjusts the font size of the reputation bar text"] = "Ajuste la taille de police du texte de la barre de reputation", + ["Adjusts the font size of the XP bar text"] = "Ajuste la taille de police du texte de la barre d'XP", + ["Adjusts the height of the top panel"] = "Ajuste la hauteur du panneau superieur", + ["Adjusts the scale of the main backpack"] = "Ajuste l'echelle du sac principal", + ["Adjusts the scale of the micro menu"] = "Ajuste l'echelle du micro-menu", + ["Adjusts the scale of the paging buttons"] = "Ajuste l'echelle des boutons de pagination", + ["Adjusts the size of keybind text on action buttons"] = "Ajuste la taille du texte des raccourcis sur les boutons d'action", + ["Adjusts the size of macro text on action buttons"] = "Ajuste la taille du texte des macros sur les boutons d'action", + ["Adjusts the size of the gryphon/wyvern decorations"] = "Ajuste la taille des decorations gryphon/wyvern", + ["Adjusts the transparency of the micro menu"] = "Ajuste la transparence du micro-menu", + ["Adjusts the width of the top panel"] = "Ajuste la largeur du panneau superieur", + ["Adjusts transparency of gryphon/wyvern decorations"] = "Ajuste la transparence des decorations gryphon/wyvern", + ["Adjusts transparency of zoom buttons"] = "Ajuste la transparence des boutons de zoom", + ["Adjusts vertical position of gryphon/wyvern decorations"] = "Ajuste la position verticale des decorations gryphon/wyvern", + ["Adjusts vertical position of keybind text"] = "Ajuste la position verticale du texte des raccourcis", + ["Adjusts vertical position of macro text"] = "Ajuste la position verticale du texte des macros", + ["Adjusts vertical position of the zone text"] = "Ajuste la position verticale du texte de zone", + ["Adjusts vertical position of zoom buttons"] = "Ajuste la position verticale des boutons de zoom", + ["Changes the colour of action button highlights"] = "Change la couleur de surbrillance des boutons d'action", + ["Changes the colour of keybind text on action buttons"] = "Change la couleur du texte des raccourcis sur les boutons d'action", + ["Changes the colour of macro text on action buttons"] = "Change la couleur du texte des macros sur les boutons d'action", + ["Changes the texture of the playerframe"] = "Change la texture du cadre joueur", + + ["Change the font used for all smaller frames"] = "Change la police utilisee pour tous les petits cadres", +} + +DFRL.locale.configLabels.frFR = { + ["Bags.bagAlpha"] = "Transparence sacs", + ["Bags.bagColor"] = "Couleur sacs", + ["Bags.bagDarkMode"] = "Mode sombre sacs", + ["Bags.bagScale"] = "Echelle sacs", + ["Bags.freeSlots"] = "Places libres", + ["Bags.hoverShow"] = "Afficher au survol", + ["Bags.showBags"] = "Afficher sacs", + ["Bags.showToggle"] = "Bouton sacs", + ["Bags.toggleBags"] = "Petits sacs", + ["barHeight"] = "Hauteur", + ["Bars.altGryphoon"] = "Textures alternatives gryphon", + ["Bars.barsColor"] = "Couleur des barres", + ["Bars.barsDarkMode"] = "Mode sombre barres", + ["Bars.flipGryphoon"] = "Inverser gryphon/wyvern", + ["Bars.gryphoonAlpha"] = "Transparence gryphon/wyvern", + ["Bars.gryphoonScale"] = "Taille gryphon/wyvern", + ["Bars.gryphoonX"] = "Position X gryphon/wyvern", + ["Bars.gryphoonY"] = "Position Y gryphon/wyvern", + ["Bars.highlightColor"] = "Couleur surbrillance", + ["Bars.hotkeyColour"] = "Couleur raccourcis", + ["Bars.hotkeyFont"] = "Police raccourcis", + ["Bars.hotkeyScale"] = "Taille raccourcis", + ["Bars.hotkeyShow"] = "Afficher raccourcis", + ["Bars.hotkeyX"] = "Position X raccourcis", + ["Bars.hotkeyY"] = "Position Y raccourcis", + ["Bars.macroColour"] = "Couleur macros", + ["Bars.macroScale"] = "Taille macros", + ["Bars.macroShow"] = "Afficher macros", + ["Bars.macroX"] = "Position X macros", + ["Bars.macroY"] = "Position Y macros", + ["Bars.mainBarAlpha"] = "Transparence barre principale", + ["Bars.mainBarBG"] = "Fond barre principale", + ["Bars.mainBarGrid"] = "Grille barre principale", + ["Bars.mainBarScale"] = "Echelle barre principale", + ["Bars.mainBarSpacing"] = "Espacement barre principale", + ["Bars.multiBarFourAlpha"] = "Transparence multi-barre 4", + ["Bars.multiBarFourGrid"] = "Grille multi-barre 4", + ["Bars.multiBarFourScale"] = "Echelle multi-barre 4", + ["Bars.multiBarFourShow"] = "Afficher multi-barre 4", + ["Bars.multiBarFourSpacing"] = "Espacement multi-barre 4", + ["Bars.multiBarOneAlpha"] = "Transparence multi-barre 1", + ["Bars.multiBarOneGrid"] = "Grille multi-barre 1", + ["Bars.multiBarOneScale"] = "Echelle multi-barre 1", + ["Bars.multiBarOneShow"] = "Afficher multi-barre 1", + ["Bars.multiBarOneSpacing"] = "Espacement multi-barre 1", + ["Bars.multiBarThreeAlpha"] = "Transparence multi-barre 3", + ["Bars.multiBarThreeGrid"] = "Grille multi-barre 3", + ["Bars.multiBarThreeScale"] = "Echelle multi-barre 3", + ["Bars.multiBarThreeShow"] = "Afficher multi-barre 3", + ["Bars.multiBarThreeSpacing"] = "Espacement multi-barre 3", + ["Bars.multiBarTwoAlpha"] = "Transparence multi-barre 2", + ["Bars.multiBarTwoGrid"] = "Grille multi-barre 2", + ["Bars.multiBarTwoScale"] = "Echelle multi-barre 2", + ["Bars.multiBarTwoShow"] = "Afficher multi-barre 2", + ["Bars.multiBarTwoSpacing"] = "Espacement multi-barre 2", + ["Bars.pagingScale"] = "Echelle pagination", + ["Bars.pagingShow"] = "Afficher pagination", + ["Bars.pagingSwap"] = "Inverser ancrage pagination", + ["Bars.pagingX"] = "Position X pagination", + ["Bars.petbarAlpha"] = "Transparence barre familier", + ["Bars.petbarGrid"] = "Grille barre familier", + ["Bars.petbarScale"] = "Echelle barre familier", + ["Bars.petbarSpacing"] = "Espacement barre familier", + ["Bars.petbarOrientation"] = "Orientation barre familier", + ["Bars.petbarButtonSize"] = "Taille boutons familier", + ["Bars.petbarPreset"] = "Preset barre familier", + ["Bars.petbarAutoCastAlpha"] = "Intensite glow auto-cast", + ["Bars.petbarShineAlpha"] = "Intensite shine auto-cast", + ["Bars.shapeshiftAlpha"] = "Transparence metamorphose", + ["Bars.shapeshiftScale"] = "Echelle metamorphose", + ["Bars.shapeshiftSpacing"] = "Espacement metamorphose", + ["Bars.showGryphoon"] = "Afficher gryphon/wyvern", + ["barWidth"] = "Largeur", + ["Cast.barHeight"] = "Hauteur castbar", + ["Cast.barWidth"] = "Largeur castbar", + ["Cast.castColor"] = "Couleur castbar", + ["Cast.castDarkMode"] = "Mode sombre castbar", + ["Cast.castFont"] = "Police castbar", + ["Cast.fontSize"] = "Taille police castbar", + ["Cast.fontY"] = "Position Y police", + ["Cast.setFillDirection"] = "Sens de remplissage", + ["Cast.showIcon"] = "Afficher icone", + ["Cast.showShadow"] = "Afficher ombre", + ["Cast.showSpell"] = "Afficher nom du sort", + ["Cast.showTime"] = "Afficher temps", + ["Cast.spellX"] = "Position X nom sort", + ["Cast.textAlign"] = "Alignement texte", + ["Cast.timeX"] = "Position X temps", + ["Chat.blizzardButtons"] = "Boutons Blizzard", + ["Chat.chatColor"] = "Couleur chat", + ["Chat.chatDarkMode"] = "Mode sombre chat", + ["Chat.fadeChat"] = "Fondu du chat", + ["Chat.showButtons"] = "Afficher boutons chat", + ["Collector.collectDarkMode"] = "Mode sombre collecte", + ["cutoutColor"] = "Couleur effet degats", + ["enableCutout"] = "Effet degats", + ["enablePulse"] = "Pulse", + ["Errors.hideErrors"] = "Masquer erreurs Lua", + ["fontSize"] = "Taille police", + ["frameScale"] = "Taille du cadre", + ["GUI-Dragonflight.globalFont"] = "Police globale", + ["GUI-Dragonflight.homeMinMaxColor"] = "Couleur Fermer/Mini", + ["GUI-Dragonflight.homeTimeColor"] = "Couleur horloge", + ["GUI-Dragonflight.language"] = "Langue", + ["GUI-Dragonflight.sideView"] = "Panneau lateral", + ["GUI-Dragonflight.smallerFrame"] = "Fenetre compacte", + ["Map.alphaShadow"] = "Transparence ombre", + ["Map.alphaZoom"] = "Transparence zoom", + ["Map.mapAlpha"] = "Transparence mini-carte", + ["Map.mapColor"] = "Couleur mini-carte", + ["Map.mapDarkMode"] = "Mode sombre mini-carte", + ["Map.mapShadow"] = "Afficher ombre", + ["Map.mapSize"] = "Taille mini-carte", + ["Map.mapSquare"] = "Style carre", + ["Map.mapTime"] = "Afficher heure", + ["Map.scaleZoom"] = "Taille zoom", + ["Map.showSunMoon"] = "Soleil/lune Blizzard", + ["Map.showTopPanel"] = "Afficher panneau haut", + ["Map.showZoom"] = "Afficher zoom", + ["Map.textColor"] = "Couleurs PizzaWB", + ["Map.timeFormat12h"] = "Format 12h", + ["Map.timeSize"] = "Taille heure", + ["Map.timeX"] = "Position X heure", + ["Map.timeY"] = "Position Y heure", + ["Map.topPanelFont"] = "Police mini-carte", + ["Map.topPanelHeight"] = "Hauteur panneau haut", + ["Map.topPanelWidth"] = "Largeur panneau haut", + ["Map.zoneTextSize"] = "Taille texte zone", + ["Map.zoneTextX"] = "Position X zone", + ["Map.zoneTextY"] = "Position Y zone", + ["Map.zoomX"] = "Position X zoom", + ["Map.zoomY"] = "Position Y zoom", + ["Micro.microAlpha"] = "Transparence micro-menu", + ["Micro.microColor"] = "Couleur micro-menu", + ["Micro.microDarkMode"] = "Mode sombre micro-menu", + ["Micro.microScale"] = "Echelle micro-menu", + ["Micro.microSpacing"] = "Espacement micro-menu", + ["Micro.smallFPS"] = "FPS/MS compacts", + ["Micro.switchColor"] = "Style gris/couleur", + ["Mini.colorClass"] = "Couleur par classe", + ["Mini.colorReaction"] = "Couleur par reaction", + ["Mini.cutoutColor"] = "Couleur effet degats", + ["Mini.enableCutout"] = "Effet degats", + ["Mini.enablePulse"] = "Pulse faible vie", + ["Mini.frameFont"] = "Police mini-cadres", + ["Mini.miniColor"] = "Couleur mini-cadres", + ["Mini.miniDarkMode"] = "Mode sombre mini-cadres", + ["Mini.miniPartyTextMaxShow"] = "Afficher max groupe", + ["Mini.miniPetTextMaxShow"] = "Afficher max familier", + ["Mini.miniTextShow"] = "Afficher texte vie/mana", + ["Mini.miniTotTextMaxShow"] = "Afficher max cible de cible", + ["Mini.noPartyPercent"] = "Masquer % groupe", + ["Mini.noPetPercent"] = "Masquer % familier", + ["Mini.noTotPercent"] = "Masquer % cible de cible", + ["Mini.partyFrameScale"] = "Taille cadre groupe", + ["Mini.petFrameScale"] = "Taille cadre familier", + ["Mini.pulseColor"] = "Couleur pulse", + ["Mini.totFrameScale"] = "Taille cadre cible de cible", + ["noPercent"] = "Masquer pourcentages", + ["Player.classColor"] = "Vie selon classe", + ["Player.classPortrait"] = "Portraits de classe 2D", + ["Player.combatGlow"] = "Pulse combat", + ["Player.cutoutColor"] = "Couleur effet degats", + ["Player.eliteBorder"] = "Texture du cadre", + ["Player.enableCutout"] = "Effet degats", + ["Player.enablePulse"] = "Pulse barres", + ["Player.energyTick"] = "Ticks energie/mana", + ["Player.frameFont"] = "Police joueur", + ["Player.frameHide"] = "Masquer a PV pleins", + ["Player.frameScale"] = "Taille du cadre", + ["Player.glowAlpha"] = "Alpha pulse combat", + ["Player.glowSpeed"] = "Vitesse pulse combat", + ["Player.healthSize"] = "Taille texte vie", + ["Player.levelSize"] = "Taille niveau", + ["Player.manaSize"] = "Taille texte mana", + ["Player.nameSize"] = "Taille nom", + ["Player.noPercent"] = "Masquer pourcentages", + ["Player.playerColor"] = "Couleur joueur", + ["Player.playerDarkMode"] = "Mode sombre joueur", + ["Player.pulseColor"] = "Couleur pulse", + ["Player.restingAlpha"] = "Alpha repos", + ["Player.restingColor"] = "Couleur repos", + ["Player.restingGlow"] = "Lueur repos", + ["Player.restingSpeed"] = "Vitesse repos", + ["Player.textColoringHealth"] = "Texte selon vie", + ["Player.textColoringResource"] = "Texte selon ressource", + ["Player.textMaxShow"] = "Afficher valeurs max", + ["Player.textShow"] = "Afficher texte vie/mana", + ["pulseColor"] = "Couleur pulse", + ["PVPIcon.pvpDark"] = "Icnes JcJ sombres", + ["RangeIndicator.indicatorAlpha"] = "Opacite indicateur", + ["RangeIndicator.indicatorDark"] = "Couleur sombre", + ["RangeIndicator.indicatorFade"] = "Fondu animation", + ["RangeIndicator.indicatorSimple"] = "X simple", + ["Target.colorClass"] = "Vie selon classe", + ["Target.colorReaction"] = "Vie selon reaction", + ["Target.cutoutColor"] = "Couleur effet degats", + ["Target.enableCutout"] = "Effet degats", + ["Target.enablePulse"] = "Pulse barres", + ["Target.frameFont"] = "Police cible", + ["Target.frameScale"] = "Taille du cadre", + ["Target.healthSize"] = "Taille texte vie", + ["Target.levelSize"] = "Taille niveau cible", + ["Target.manaSize"] = "Taille texte mana", + ["Target.nameSize"] = "Taille nom cible", + ["Target.noPercent"] = "Masquer pourcentages", + ["Target.pulseColor"] = "Couleur pulse", + ["Target.targetColor"] = "Couleur cible", + ["Target.targetDarkMode"] = "Mode sombre cible", + ["Target.textColoringHealth"] = "Texte selon vie", + ["Target.textColoringResource"] = "Texte selon ressource", + ["Target.textMaxShow"] = "Afficher valeurs max", + ["Target.textShow"] = "Afficher texte vie/mana", + ["textMaxShow"] = "Afficher valeurs max", + ["textShow"] = "Afficher texte", + ["Tooltip.toolTipMouse"] = "Infobulle au curseur", + ["Tooltip.toolTipX"] = "Decalage X infobulle", + ["Tooltip.toolTipY"] = "Decalage Y infobulle", + ["Ui.cameraDistanceFactor"] = "Distance camera max", + ["Ui.characterPanel"] = "Fiche personnage", + ["Ui.gameMenu"] = "Menu du jeu", + ["Ui.hideErrorMessage"] = "Masquer message d'erreur", + ["Ui.lowHpThreshold"] = "Seuil PV faibles", + ["Ui.lowHpWarn"] = "Alerte PV faibles", + ["Ui.questLog"] = "Journal de quetes", + ["Ui.showPlates"] = "Plaques de nom en combat", + ["Xprep.autoTrack"] = "Suivi auto reputation", + ["Xprep.barFont"] = "Police XP/Rep", + ["Xprep.bgAlpha"] = "Alpha du fond", + ["Xprep.hoverRep"] = "Texte rep au survol", + ["Xprep.hoverXP"] = "Texte XP au survol", + ["Xprep.repBarAlpha"] = "Transparence barre rep", + ["Xprep.repBarHeight"] = "Hauteur barre rep", + ["Xprep.repBarTextSize"] = "Taille texte rep", + ["Xprep.repBarWidth"] = "Largeur barre rep", + ["Xprep.showRepOnGain"] = "Texte rep au gain", + ["Xprep.showRepText"] = "Afficher texte reputation", + ["Xprep.showXpBar"] = "Afficher barre XP", + ["Xprep.showXpOnGain"] = "Texte XP au gain", + ["Xprep.showXpText"] = "Afficher texte XP", + ["Xprep.xpBarAlpha"] = "Transparence barre XP", + ["Xprep.xpBarHeight"] = "Hauteur barre XP", + ["Xprep.xpBarTextSize"] = "Taille texte XP", + ["Xprep.xpBarWidth"] = "Largeur barre XP", + ["Xprep.xprepColor"] = "Couleur XP/Rep", + ["Xprep.xprepDarkMode"] = "Mode sombre XP/Rep", +} + +DFRL.locale.wordMap.frFR = { + ["alpha"] = "alpha", + ["bag"] = "sac", + ["bags"] = "sacs", + ["bar"] = "barre", + ["bars"] = "barres", + ["bg"] = "fond", + ["camera"] = "camera", + ["cast"] = "cast", + ["chat"] = "chat", + ["class"] = "classe", + ["color"] = "couleur", + ["colour"] = "couleur", + ["combat"] = "combat", + ["cutout"] = "decoupe", + ["dark"] = "sombre", + ["distance"] = "distance", + ["energy"] = "energie", + ["error"] = "erreur", + ["fade"] = "fondu", + ["font"] = "police", + ["fps"] = "fps", + ["frame"] = "cadre", + ["free"] = "libres", + ["glow"] = "lueur", + ["grid"] = "grille", + ["health"] = "vie", + ["hide"] = "masquer", + ["hotkey"] = "raccourcis", + ["icon"] = "icone", + ["indicator"] = "indicateur", + ["language"] = "langue", + ["level"] = "niveau", + ["macro"] = "macro", + ["mana"] = "mana", + ["map"] = "carte", + ["micro"] = "micro", + ["mini"] = "mini", + ["mode"] = "mode", + ["name"] = "nom", + ["panel"] = "panneau", + ["party"] = "groupe", + ["pet"] = "familier", + ["player"] = "joueur", + ["profile"] = "profil", + ["profiles"] = "profils", + ["pulse"] = "pulse", + ["pvp"] = "jcj", + ["quest"] = "quete", + ["reaction"] = "reaction", + ["rep"] = "rep", + ["resting"] = "repos", + ["scale"] = "echelle", + ["shadow"] = "ombre", + ["show"] = "afficher", + ["size"] = "taille", + ["slots"] = "emplacements", + ["spacing"] = "espacement", + ["target"] = "cible", + ["text"] = "texte", + ["threshold"] = "seuil", + ["time"] = "temps", + ["toggle"] = "bascule", + ["tooltip"] = "infobulle", + ["tot"] = "cible", + ["transparency"] = "transparence", + ["ui"] = "ui", + ["warn"] = "alerte", + ["width"] = "largeur", + ["x"] = "X", + ["xp"] = "XP", + ["y"] = "Y", + ["zoom"] = "zoom", +} + +function DFRL:GetLanguage() + local language = nil + if self.tempDB and self.tempDB["GUI-Dragonflight"] and self.tempDB["GUI-Dragonflight"].language then + language = self.tempDB["GUI-Dragonflight"].language + end + + if not language or language == "" then + if GetLocale and GetLocale() == "frFR" then + return "Francais" + end + return "English" + end + + return language +end + +function DFRL:IsFrench() + local language = self:GetLanguage() + return language == "Francais" or language == "Français" or language == "frFR" or language == "fr" +end + +function DFRL:TR(text) + if text == nil then return text end + if not self:IsFrench() then return text end + + local tbl = self.locale and self.locale.translations and self.locale.translations.frFR + if not tbl then return text end + return tbl[text] or text +end + +function DFRL:HumanizeKey(key) + if not key then return "" end + local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") + displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + return displayTxt +end + +function DFRL:TranslateWords(text) + if not text or text == "" then return text end + local map = self.locale and self.locale.wordMap and self.locale.wordMap.frFR + if not map then return text end + + local result = {} + for token in string.gfind(text, "%S+") do + local core = string.gsub(token, "([%.,:;!%?])$", "") + local _, _, punct = string.find(token, "([%.,:;!%?])$") + local lookup = string.lower(core or token) + local translated = map[lookup] or core + table.insert(result, translated .. (punct or "")) + end + return table.concat(result, " ") +end + +function DFRL:GetOptionLabel(moduleName, key) + local fallback = self:HumanizeKey(key) + if not self:IsFrench() then + return fallback + end + + local tbl = self.locale and self.locale.configLabels and self.locale.configLabels.frFR + if tbl then + local exactKey = (moduleName and key) and (moduleName .. "." .. key) or nil + if exactKey and tbl[exactKey] then + return tbl[exactKey] + end + if tbl[key] then + return tbl[key] + end + end + + local translated = self:TR(fallback) + if translated ~= fallback then + return translated + end + + return self:TranslateWords(fallback) +end + +function DFRL:DisplayProfileName(name) + if not name then return "" end + if name == "Default" then + return self:TR("Default") + end + return name +end diff --git a/media/tex/micromenu/color_micro/instancejournal-faded.tga b/media/tex/micromenu/color_micro/instancejournal-faded.tga new file mode 100644 index 0000000000000000000000000000000000000000..4c4489c21b419d838e2a05eda1e8c1ea6235a0fa GIT binary patch literal 65580 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 VcH6qG`u}qwPD=m) literal 0 HcmV?d00001 diff --git a/media/tex/micromenu/color_micro/instancejournal-highlight.tga b/media/tex/micromenu/color_micro/instancejournal-highlight.tga new file mode 100644 index 0000000000000000000000000000000000000000..639bd52be6e3176e10321d8b179b79022f053f42 GIT binary patch literal 65580 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 Af&c&j literal 0 HcmV?d00001 diff --git a/modules/bars/bars.lua b/modules/bars/bars.lua index e0b6441..236c982 100644 --- a/modules/bars/bars.lua +++ b/modules/bars/bars.lua @@ -54,9 +54,15 @@ DFRL:NewDefaults("Bars", { petbarScale = {0.8, "slider", {0.2, 2}, nil, "pet bar", 51, "Adjusts the scale of the pet action bar", nil, nil}, petbarSpacing = {6, "slider", {0.1, 20}, nil, "pet bar", 52, "Adjusts spacing between pet action bar buttons", nil, nil}, petbarAlpha = {1, "slider", {0.1, 1}, nil, "pet bar", 53, "Adjusts transparency of pet action bar", nil, nil}, - shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 54, "Adjusts the scale of the shapeshift bar", nil, nil}, - shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 55, "Adjusts spacing between shapeshift buttons", nil, nil}, - shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 56, "Adjusts transparency of shapeshift bar", nil, nil}, + petbarGrid = {1, "slider", {1, 6}, nil, "pet bar", 54, "Changes the grid layout of pet action bar", "5 = 2 columns x 5 rows", nil}, + petbarOrientation = {"Horizontal", "dropdown", {"Horizontal", "Vertical Down", "Vertical Up"}, nil, "pet bar", 55, "Choose how the pet bar grows when using a single row layout", "Vertical modes are especially useful for compact hunter layouts", nil}, + petbarButtonSize = {30, "slider", {20, 40}, nil, "pet bar", 56, "Adjusts the size of pet action bar buttons", nil, nil}, + petbarPreset = {"Custom", "dropdown", {"Custom", "Default", "Compact Vertical", "Compact Horizontal", "Grid 2x5"}, nil, "pet bar", 57, "Apply a quick preset for the pet bar", nil, nil}, + petbarAutoCastAlpha = {0.40, "slider", {0.1, 1}, nil, "pet bar", 58, "Adjusts the strength of the pet auto-cast glow", nil, nil}, + petbarShineAlpha = {0.28, "slider", {0.1, 1}, nil, "pet bar", 59, "Adjusts the shine overlay of pet auto-cast visuals", nil, nil}, + shapeshiftScale = {0.8, "slider", {0.2, 2}, nil, "shapeshift bar", 60, "Adjusts the scale of the shapeshift bar", nil, nil}, + shapeshiftSpacing = {6, "slider", {0.1, 20}, nil, "shapeshift bar", 61, "Adjusts spacing between shapeshift buttons", nil, nil}, + shapeshiftAlpha = {1, "slider", {0.1, 1}, nil, "shapeshift bar", 62, "Adjusts transparency of shapeshift bar", nil, nil}, }) DFRL:NewMod("Bars", 1, function() @@ -342,6 +348,62 @@ DFRL:NewMod("Bars", 1, function() button:ClearAllPoints() button:SetPoint("LEFT", self.newPetBar, "LEFT", (i-1)*36, 0) end + + self:PetBarAutoCastVisuals() + end + + function Setup:PetBarAutoCastVisuals() + if self.petBarAutoCastFrame then return end + + local function softenTexture(tex, alpha) + if tex and tex.SetAlpha then + tex:SetAlpha(alpha) + end + end + + local function applyPetAutoCastLook() + for i = 1, 10 do + local button = _G["PetActionButton" .. i] + if button then + local name = button:GetName() + local shine = button.Shine or _G[name .. "Shine"] + local autoCast = button.AutoCastable or _G[name .. "AutoCastable"] + local autoCast2 = button.AutoCast or _G[name .. "AutoCast"] + + local shineAlpha = DFRL:GetTempDB('Bars', 'petbarShineAlpha') or 0.28 + local autoCastAlpha = DFRL:GetTempDB('Bars', 'petbarAutoCastAlpha') or 0.40 + + softenTexture(shine, shineAlpha) + softenTexture(autoCast, autoCastAlpha) + softenTexture(autoCast2, autoCastAlpha) + end + end + end + + self.petBarAutoCastFrame = CreateFrame("Frame") + self.petBarAutoCastFrame:RegisterEvent("PLAYER_ENTERING_WORLD") + self.petBarAutoCastFrame:RegisterEvent("UNIT_PET") + self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE") + self.petBarAutoCastFrame:RegisterEvent("PET_BAR_UPDATE_USABLE") + self.petBarAutoCastFrame:RegisterEvent("PET_UI_UPDATE") + self.petBarAutoCastFrame:SetScript("OnEvent", function() + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'PetBarAutoCastEvent', event or 'nil', arg1 or 'nil') + end + applyPetAutoCastLook() + end) + + local refreshFrame = CreateFrame('Frame') + local elapsed = 0 + refreshFrame:SetScript('OnUpdate', function() + elapsed = elapsed + (arg1 or 0) + if elapsed > 1 then + this:SetScript('OnUpdate', nil) + applyPetAutoCastLook() + end + end) + + applyPetAutoCastLook() end function Setup:ShapeshiftBar() @@ -547,7 +609,8 @@ DFRL:NewMod("Bars", 1, function() -- callbacks local callbacks = {} - local helpers = { + local helpers = {} + helpers = { getFontPath = function(fontName) if fontName == 'Expressway' then return 'Interface\\AddOns\\DragonflightUI-Reforged\\media\\fnt\\Expressway.ttf' @@ -576,30 +639,124 @@ DFRL:NewMod("Bars", 1, function() end end, - setGridLayout = function(barFrame, buttonPrefix, value, spacingKey) - local layoutIndex = math.floor(value + 0.5) + normalizeLayoutIndex = function(value) + local layoutIndex = math.floor((value or 1) + 0.5) if layoutIndex < 1 then layoutIndex = 1 end if layoutIndex > 6 then layoutIndex = 6 end + return layoutIndex + end, + + setGridLayout = function(barFrame, buttonPrefix, value, spacingKey, maxButtons) + maxButtons = maxButtons or 12 + local layoutIndex = helpers.normalizeLayoutIndex(value) local layout = Setup.layouts[layoutIndex] if not layout then return end local spacing = DFRL:GetTempDB('Bars', spacingKey) - local buttonSize = _G[buttonPrefix .. '1']:GetWidth() + local firstButton = _G[buttonPrefix .. '1'] + if not firstButton then + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'GridLayoutSkipped', buttonPrefix, 'button 1 missing') + end + return + end + local buttonSize = firstButton:GetWidth() local isReversed = buttonPrefix == 'MultiBarLeftButton' or buttonPrefix == 'MultiBarRightButton' + local effectiveCols = math.min(layout.cols, maxButtons) + local effectiveRows = math.ceil(maxButtons / effectiveCols) + + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'GridLayout', buttonPrefix, 'layout', layoutIndex, 'cols', effectiveCols, 'rows', effectiveRows, 'spacing', spacing) + end - for i = (isReversed and 12 or 1), (isReversed and 1 or 12), (isReversed and -1 or 1) do + for i = (isReversed and maxButtons or 1), (isReversed and 1 or maxButtons), (isReversed and -1 or 1) do local button = _G[buttonPrefix .. i] if button then button:ClearAllPoints() - local index = isReversed and (13 - i) or i - local row = math.floor((index - 1) / layout.cols) - local col = (index - 1) - (row * layout.cols) + local index = isReversed and (maxButtons + 1 - i) or i + local row = math.floor((index - 1) / effectiveCols) + local col = (index - 1) - (row * effectiveCols) button:SetPoint('BOTTOMLEFT', barFrame, 'BOTTOMLEFT', col * (buttonSize + spacing), row * (buttonSize + spacing)) end end - barFrame:SetHeight((buttonSize + spacing) * layout.rows - spacing) - barFrame:SetWidth((buttonSize + spacing) * layout.cols - spacing) + barFrame:SetHeight((buttonSize + spacing) * effectiveRows - spacing) + barFrame:SetWidth((buttonSize + spacing) * effectiveCols - spacing) + end, + + applyPetBarButtonSize = function(size) + local buttonSize = tonumber(size) or 30 + for i = 1, 10 do + local button = _G['PetActionButton' .. i] + if button then + button:SetWidth(buttonSize) + button:SetHeight(buttonSize) + end + end + end, + + applyPetBarLayout = function() + if not DFRL.newPetBar then return end + local firstButton = _G['PetActionButton1'] + if not firstButton then return end + + local spacing = DFRL:GetTempDB('Bars', 'petbarSpacing') or 6 + local layoutIndex = helpers.normalizeLayoutIndex(DFRL:GetTempDB('Bars', 'petbarGrid') or 1) + local orientation = DFRL:GetTempDB('Bars', 'petbarOrientation') or 'Horizontal' + local buttonSize = tonumber(DFRL:GetTempDB('Bars', 'petbarButtonSize')) or firstButton:GetWidth() or 30 + local layout = Setup.layouts[layoutIndex] + if not layout then return end + + helpers.applyPetBarButtonSize(buttonSize) + + local cols = math.min(layout.cols, 10) + local rows = math.ceil(10 / cols) + local anchor = 'BOTTOMLEFT' + local verticalDirection = 1 + + if layoutIndex == 1 then + if orientation == 'Vertical Down' then + cols = 1 + rows = 10 + anchor = 'TOPLEFT' + verticalDirection = -1 + elseif orientation == 'Vertical Up' then + cols = 1 + rows = 10 + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + else + cols = 10 + rows = 1 + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + end + else + if orientation == 'Vertical Up' then + anchor = 'BOTTOMLEFT' + verticalDirection = 1 + else + anchor = 'TOPLEFT' + verticalDirection = -1 + end + end + + for i = 1, 10 do + local button = _G['PetActionButton' .. i] + if button then + local row = math.floor((i - 1) / cols) + local col = (i - 1) - (row * cols) + button:ClearAllPoints() + button:SetPoint(anchor, DFRL.newPetBar, anchor, col * (buttonSize + spacing), row * (buttonSize + spacing) * verticalDirection) + end + end + + DFRL.newPetBar:SetWidth((buttonSize + spacing) * cols - spacing) + DFRL.newPetBar:SetHeight((buttonSize + spacing) * rows - spacing) + + if DFRL.DebugLog then + DFRL:DebugLog('bars', 'PetBarLayout', 'grid', layoutIndex, 'orientation', orientation, 'cols', cols, 'rows', rows, 'size', buttonSize, 'spacing', spacing) + end end, iterateButtons = function(callback) @@ -637,6 +794,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarOneSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarOneGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarBottomLeftButton', value) end helpers.setSpacing('MultiBarBottomLeftButton', value) end @@ -651,6 +811,7 @@ DFRL:NewMod("Bars", 1, function() callbacks.multiBarTwoSpacing = function(value) local gridLayout = DFRL:GetTempDB('Bars', 'multiBarTwoGrid') if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarBottomRightButton', value) end helpers.setSpacing('MultiBarBottomRightButton', value) end @@ -663,6 +824,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarThreeSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarThreeGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarLeftButton', value) end helpers.setSpacing('MultiBarLeftButton', value, 'vertical') end @@ -675,6 +839,9 @@ DFRL:NewMod("Bars", 1, function() end callbacks.multiBarFourSpacing = function(value) + local gridLayout = DFRL:GetTempDB('Bars', 'multiBarFourGrid') + if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'MultiBarRightButton', value) end helpers.setSpacing('MultiBarRightButton', value, 'vertical') end @@ -963,7 +1130,7 @@ DFRL:NewMod("Bars", 1, function() end callbacks.petbarSpacing = function(value) - helpers.setSpacing('PetActionButton', value, 'horizontal', 10) + helpers.applyPetBarLayout() end callbacks.petbarAlpha = function(value) @@ -972,6 +1139,80 @@ DFRL:NewMod("Bars", 1, function() end end + callbacks.petbarOrientation = function(value) + helpers.applyPetBarLayout() + end + + callbacks.petbarButtonSize = function(value) + helpers.applyPetBarLayout() + end + + callbacks.petbarPreset = function(value) + if value == 'Custom' then return end + + local preset = { + ['Default'] = { + petbarGrid = 1, + petbarOrientation = 'Horizontal', + petbarButtonSize = 30, + petbarSpacing = 6, + petbarScale = 0.8, + }, + ['Compact Vertical'] = { + petbarGrid = 6, + petbarOrientation = 'Vertical Down', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + ['Compact Horizontal'] = { + petbarGrid = 1, + petbarOrientation = 'Horizontal', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + ['Grid 2x5'] = { + petbarGrid = 5, + petbarOrientation = 'Vertical Down', + petbarButtonSize = 28, + petbarSpacing = 4, + petbarScale = 0.8, + }, + } + + local cfg = preset[value] + if not cfg then return end + + for key, setting in pairs(cfg) do + DFRL:SetTempDBNoCallback('Bars', key, setting) + end + + callbacks.petbarScale(DFRL:GetTempDB('Bars', 'petbarScale')) + callbacks.petbarGrid(DFRL:GetTempDB('Bars', 'petbarGrid')) + callbacks.petbarOrientation(DFRL:GetTempDB('Bars', 'petbarOrientation')) + callbacks.petbarButtonSize(DFRL:GetTempDB('Bars', 'petbarButtonSize')) + callbacks.petbarSpacing(DFRL:GetTempDB('Bars', 'petbarSpacing')) + + if DFRL.gui and DFRL.gui.Base and DFRL.gui.Base.UpdateHandler then + DFRL.gui.Base:UpdateHandler() + end + end + + callbacks.petbarAutoCastAlpha = function(value) + if Setup and Setup.petBarAutoCastFrame and Setup.petBarAutoCastFrame:GetScript('OnEvent') then + local fn = Setup.petBarAutoCastFrame:GetScript('OnEvent') + fn() + end + end + + callbacks.petbarShineAlpha = function(value) + if Setup and Setup.petBarAutoCastFrame and Setup.petBarAutoCastFrame:GetScript('OnEvent') then + local fn = Setup.petBarAutoCastFrame:GetScript('OnEvent') + fn() + end + end + callbacks.shapeshiftSpacing = function(value) helpers.setSpacing('ShapeshiftButton', value, 'horizontal', 10) end @@ -1072,6 +1313,11 @@ DFRL:NewMod("Bars", 1, function() helpers.setGridLayout(MultiBarRight, 'MultiBarRightButton', value, 'multiBarFourSpacing') end + callbacks.petbarGrid = function(value) + if not DFRL.newPetBar then return end + helpers.applyPetBarLayout() + end + callbacks.mainBarScale = function(value) DFRL.mainBar:SetScale(value) DFRL.actionBarFrame:SetScale(value) @@ -1096,6 +1342,7 @@ DFRL:NewMod("Bars", 1, function() callbacks.mainBarSpacing = function(value) local gridLayout = DFRL:GetTempDB('Bars', 'mainBarGrid') if math.floor(gridLayout + 0.5) ~= 1 then return end + if DFRL.DebugLog then DFRL:DebugLog('bars', 'Spacing', 'ActionButton', value) end local buttonSize = ActionButton1:GetWidth() diff --git a/modules/gui/base.lua b/modules/gui/base.lua index 8f8e152..65f497f 100644 --- a/modules/gui/base.lua +++ b/modules/gui/base.lua @@ -11,21 +11,21 @@ DFRL:NewMod("Gui-base", 2, function() path = DFRL:GetInfoOrCons("media"), CONSTANTS = { - MAIN_FRAME_WIDTH = 900, - MAIN_FRAME_HEIGHT = 600, - TAB_FRAME_WIDTH = 130, + MAIN_FRAME_WIDTH = 980, + MAIN_FRAME_HEIGHT = 640, + TAB_FRAME_WIDTH = 150, TITLE_FRAME_HEIGHT = 30, SUB_FRAME_HEIGHT = 30, - SUB_FRAME_WIDTH = 400, - TAB_BUTTON_HEIGHT = 30, - TAB_BUTTON_WIDTH = 120, + SUB_FRAME_WIDTH = 460, + TAB_BUTTON_HEIGHT = 32, + TAB_BUTTON_WIDTH = 136, LEFT_PANEL_RATIO = 1.5, RIGHT_PANEL_RATIO = 3, - BACKGROUND_ALPHA = 0.8, - RIGHT_TEX_DIMMED_ALPHA = 0.4, + BACKGROUND_ALPHA = 0.9, + RIGHT_TEX_DIMMED_ALPHA = 0.55, - TAB_VERTICAL_SPACING = 35, + TAB_VERTICAL_SPACING = 33, TAB_GROUP_SEPARATOR = 20, TITLE_FRAME_OFFSET = 200, SUB_FRAME_OFFSET = 20, @@ -35,8 +35,8 @@ DFRL:NewMod("Gui-base", 2, function() PULSE_MIN_ALPHA = 0.1, PULSE_ALPHA_STEP = 0.02, - TITLE_FONT_SIZE = 16, - TAB_FONT_SIZE = 14, + TITLE_FONT_SIZE = 18, + TAB_FONT_SIZE = 15, SCROLL_SPEED = 15, SCROLL_STEP_SIZE = 250, @@ -89,6 +89,31 @@ DFRL:NewMod("Gui-base", 2, function() } } + function Setup:ApplyPanelStyle(frame, alpha) + if not frame then return end + frame:SetBackdrop({ + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } + }) + frame:SetBackdropColor(0, 0, 0, alpha or self.CONSTANTS.BACKGROUND_ALPHA) + frame:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end + + function Setup:StyleTabButton(tab, active) + if not tab then return end + if active then + tab.bg:SetVertexColor(0.14, 0.14, 0.14, 0.95) + tab.border:SetVertexColor(1, 0.82, 0, 0.75) + tab:GetFontString():SetTextColor(1, 0.95, 0.75, 1) + else + tab.bg:SetVertexColor(0.05, 0.05, 0.05, 0.75) + tab.border:SetVertexColor(1, 0.82, 0, 0.18) + tab:GetFontString():SetTextColor(0.82, 0.82, 0.82, 1) + end + end + function Setup:MainFrame() if not self.mainFrame then self.mainFrame = CreateFrame("Frame", "DFRLMainFrame", UIParent) @@ -102,6 +127,7 @@ DFRL:NewMod("Gui-base", 2, function() self.mainFrame:SetMovable(true) self.mainFrame:SetScript("OnMouseDown", function() this:StartMoving() end) self.mainFrame:SetScript("OnMouseUp", function() this:StopMovingOrSizing() end) + self:ApplyPanelStyle(self.mainFrame, self.CONSTANTS.BACKGROUND_ALPHA) tinsert(UISpecialFrames, self.mainFrame:GetName()) -- shagutweaks buggs this out, disable when debugging @@ -110,14 +136,14 @@ DFRL:NewMod("Gui-base", 2, function() leftTex:SetPoint("TOPLEFT", self.mainFrame, "TOPLEFT", 0, 0) leftTex:SetWidth(self.mainFrame:GetWidth() / self.CONSTANTS.LEFT_PANEL_RATIO) leftTex:SetHeight(self.mainFrame:GetHeight()) - leftTex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + leftTex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) self.rightTex = self.mainFrame:CreateTexture(nil, "BACKGROUND") self.rightTex:SetTexture("Interface\\Buttons\\WHITE8X8") self.rightTex:SetPoint("TOPRIGHT", self.mainFrame, "TOPRIGHT", 0, 0) self.rightTex:SetWidth(self.mainFrame:GetWidth() / self.CONSTANTS.RIGHT_PANEL_RATIO) self.rightTex:SetHeight(self.mainFrame:GetHeight()) - self.rightTex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + self.rightTex:SetVertexColor(0.04, 0.04, 0.04, self.CONSTANTS.BACKGROUND_ALPHA) T.GradientLine(self.mainFrame, "TOP", 3) T.GradientLine(self.mainFrame, "BOTTOM", -3) @@ -131,10 +157,18 @@ DFRL:NewMod("Gui-base", 2, function() self.tabFrame:SetHeight(self.mainFrame:GetHeight() - self.CONSTANTS.TITLE_FRAME_HEIGHT) self.tabFrame:SetWidth(self.CONSTANTS.TAB_FRAME_WIDTH) + self:ApplyPanelStyle(self.tabFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.tabFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.tabFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.01, 0.01, 0.01, self.CONSTANTS.BACKGROUND_ALPHA) + + self.tabHeader = self.tabFrame:CreateFontString(nil, "OVERLAY") + self.tabHeader:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") + self.tabHeader:SetTextColor(1, .82, 0, 1) + self.tabHeader:SetPoint("TOP", self.tabFrame, "TOP", 0, -8) + self.tabHeader:SetText(DFRL:TR("Navigation")) end end @@ -147,10 +181,12 @@ DFRL:NewMod("Gui-base", 2, function() self.titleFrame:SetFrameStrata("DIALOG") self.titleFrame:SetClampedToScreen(true) self.titleFrame:SetToplevel(true) + self:ApplyPanelStyle(self.titleFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.titleFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.titleFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) tinsert(UISpecialFrames, self.titleFrame:GetName()) @@ -213,10 +249,12 @@ DFRL:NewMod("Gui-base", 2, function() self.subFrame:SetHeight(self.CONSTANTS.SUB_FRAME_HEIGHT) self.subFrame:SetWidth(self.CONSTANTS.SUB_FRAME_WIDTH) + self:ApplyPanelStyle(self.subFrame, self.CONSTANTS.BACKGROUND_ALPHA) + local tex = self.subFrame:CreateTexture(nil, "BACKGROUND") tex:SetTexture("Interface\\Buttons\\WHITE8X8") tex:SetAllPoints(self.subFrame) - tex:SetVertexColor(0, 0, 0, self.CONSTANTS.BACKGROUND_ALPHA) + tex:SetVertexColor(0.02, 0.02, 0.02, self.CONSTANTS.BACKGROUND_ALPHA) self.profileText = self.subFrame:CreateFontString(nil, "OVERLAY") self.profileText:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") @@ -225,19 +263,25 @@ DFRL:NewMod("Gui-base", 2, function() local charName = UnitName("player") local profileName = DFRL_CUR_PROFILE[charName] or "Default" - self.profileText:SetText("Profile: |cffffffff" .. profileName .. "|r") + self.profileText:SetText(DFRL:TR("Profile") .. ": |cffffffff" .. DFRL:DisplayProfileName(profileName) .. "|r") self.fpsText = self.subFrame:CreateFontString(nil, "OVERLAY") self.fpsText:SetFont(self.font.. "BigNoodleTitling.ttf", 14, "OUTLINE") self.fpsText:SetTextColor(1, .82, 0, 1) self.fpsText:SetPoint("RIGHT", self.subFrame, "RIGHT", -10, 0) + self.helpText = self.subFrame:CreateFontString(nil, "OVERLAY") + self.helpText:SetFont(self.font.. "BigNoodleTitling.ttf", 11, "OUTLINE") + self.helpText:SetTextColor(0.75, 0.75, 0.75, 1) + self.helpText:SetPoint("CENTER", self.subFrame, "CENTER", 0, 0) + self.helpText:SetText(DFRL:TR("Drag to move - ESC to close")) + self.subFrame:SetScript("OnUpdate", function() if (this.fpsTimer or 0) > GetTime() then return end this.fpsTimer = GetTime() + 0.5 DFRL.activeScripts["GUI SubFrame"] = true - self.fpsText:SetText("FPS: |cffffffff" .. format("%.1f", GetFramerate()) .. "|r") - self.profileText:SetText("Profile: |cffffffff" .. (DFRL_CUR_PROFILE[UnitName("player")] or "Default") .. "|r") + self.fpsText:SetText(DFRL:TR("FPS:") .. " |cffffffff" .. format("%.1f", GetFramerate()) .. "|r") + self.profileText:SetText(DFRL:TR("Profile") .. ": |cffffffff" .. DFRL:DisplayProfileName(DFRL_CUR_PROFILE[UnitName("player")] or "Default") .. "|r") end) self.subFrame:SetScript("OnShow", function() @@ -257,12 +301,23 @@ DFRL:NewMod("Gui-base", 2, function() tab:SetHeight(self.CONSTANTS.TAB_BUTTON_HEIGHT) tab:SetWidth(self.CONSTANTS.TAB_BUTTON_WIDTH) - local yOffset = -10 - (i - 1) * self.CONSTANTS.TAB_VERTICAL_SPACING + local yOffset = -30 - (i - 1) * self.CONSTANTS.TAB_VERTICAL_SPACING if i > 5 then yOffset = yOffset - self.CONSTANTS.TAB_GROUP_SEPARATOR end tab:SetPoint("TOP", self.tabFrame, "TOP", 0, yOffset) + local bg = tab:CreateTexture(nil, "BACKGROUND") + bg:SetTexture("Interface\\Buttons\\WHITE8X8") + bg:SetAllPoints(tab) + tab.bg = bg + + local border = tab:CreateTexture(nil, "BORDER") + border:SetTexture("Interface\\Buttons\\WHITE8X8") + border:SetPoint("TOPLEFT", tab, "TOPLEFT", 2, -2) + border:SetPoint("BOTTOMRIGHT", tab, "BOTTOMRIGHT", -2, 2) + tab.border = border + local highlight = tab:CreateTexture(nil, "OVERLAY") highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") highlight:SetAllPoints(tab) @@ -275,7 +330,7 @@ DFRL:NewMod("Gui-base", 2, function() text:SetTextColor(.7, .7, .7, 1) text:SetPoint("CENTER", tab, "CENTER") tab:SetFontString(text) - tab:SetText(Setup.tabs[i]) + tab:SetText(DFRL:TR(Setup.tabs[i])) local tabIndex = i tab:SetScript("OnClick", function() @@ -285,19 +340,24 @@ DFRL:NewMod("Gui-base", 2, function() tab:SetScript("OnEnter", function() if tabIndex ~= self.selectedTab then tab.highlight:Show() + tab.bg:SetVertexColor(0.10, 0.10, 0.10, 0.92) + tab.border:SetVertexColor(1, 0.82, 0, 0.45) end end) tab:SetScript("OnLeave", function() if tabIndex ~= self.selectedTab then tab.highlight:Hide() + self:StyleTabButton(tab, false) end end) + self:StyleTabButton(tab, false) self.tabButtons[i] = tab end self.tabButtons[13]:Disable() self.tabButtons[13]:GetFontString():SetTextColor(.4, .4, .4, 1) + if self.tabButtons[13].border then self.tabButtons[13].border:SetVertexColor(0.4, 0.4, 0.4, 0.1) end self.tabsCreated = true end end @@ -305,10 +365,11 @@ DFRL:NewMod("Gui-base", 2, function() function Setup:SelectTab(tabIndex) for i = 1, table.getn(self.tabs) do self.tabButtons[i].highlight:Hide() + self:StyleTabButton(self.tabButtons[i], false) end - self.tabButtons[tabIndex].highlight:Show() + self:StyleTabButton(self.tabButtons[tabIndex], true) self.selectedTab = tabIndex @@ -346,7 +407,7 @@ DFRL:NewMod("Gui-base", 2, function() self.slider:Show() end if tabIndex ~= 1 then - self.panelTitle:SetText(self.tabs[tabIndex]) + self.panelTitle:SetText(DFRL:TR(self.tabs[tabIndex])) else self.panelTitle:SetText("") end @@ -468,9 +529,9 @@ DFRL:NewMod("Gui-base", 2, function() function Setup:PanelTitles() if not self.panelTitle then self.panelTitle = self.mainFrame:CreateFontString(nil, "OVERLAY") - self.panelTitle:SetFont(self.font.. "BigNoodleTitling.ttf", 18, "OUTLINE") + self.panelTitle:SetFont(self.font.. "BigNoodleTitling.ttf", 22, "OUTLINE") self.panelTitle:SetTextColor(1, .82, 0, 1) - self.panelTitle:SetPoint("TOP", self.scrollFrame, "TOP", -20, 25) + self.panelTitle:SetPoint("TOP", self.scrollFrame, "TOP", -20, 28) end end diff --git a/modules/gui/elem.lua b/modules/gui/elem.lua index c3fba1e..04cb7e0 100644 --- a/modules/gui/elem.lua +++ b/modules/gui/elem.lua @@ -31,11 +31,11 @@ DFRL:NewMod("Gui-elem", 3, function() tabPositions = {}, configCache = {}, - DESCRIPTION_FONT_SIZE = 15, - EXTRA_DESCRIPTION_FONT_SIZE = 11, - VALUE_FONT_SIZE = 14, + DESCRIPTION_FONT_SIZE = 16, + EXTRA_DESCRIPTION_FONT_SIZE = 12, + VALUE_FONT_SIZE = 15, - MODULE_TOP_SPACING = 40, + MODULE_TOP_SPACING = 44, MODULE_BOTTOM_SPACING = 40, HEADER_TOP_SPACING = 40, HEADER_BOTTOM_SPACING = 25, @@ -287,14 +287,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 3) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementName] = extraDescLabel end @@ -348,14 +348,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 6) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end @@ -434,14 +434,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 10) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end @@ -495,14 +495,14 @@ DFRL:NewMod("Gui-elem", 3, function() local descLabel = scrollChild:CreateFontString(nil, "BACKGROUND") descLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") descLabel:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 10, currentY - 6) - descLabel:SetText(data.description or "") + descLabel:SetText(DFRL:TR(data.description or "")) descLabel:SetTextColor(.9,.9,.9) if data.extraDescription then local extraDescLabel = scrollChild:CreateFontString(nil, "BACKGROUND") extraDescLabel:SetFont(self.font .. "BigNoodleTitling.ttf", self.EXTRA_DESCRIPTION_FONT_SIZE, "OUTLINE") extraDescLabel:SetPoint("LEFT", descLabel, "RIGHT", 10, 0) - extraDescLabel:SetText(data.extraDescription) + extraDescLabel:SetText(DFRL:TR(data.extraDescription)) extraDescLabel:SetTextColor(1, 0.5, 0.5) self.extraDescriptionLabels[elementKey] = extraDescLabel end diff --git a/modules/gui/homeb.lua b/modules/gui/homeb.lua index 6735658..02c067b 100644 --- a/modules/gui/homeb.lua +++ b/modules/gui/homeb.lua @@ -18,6 +18,7 @@ DFRL:NewDefaults("GUI-Dragonflight", { sideView = {.3, "slider", {.1, .8}, nil, "Home Screen", 3, "Changes the alpha of the side view", "", nil}, homeMinMaxColor = {{1, .82, 0}, "colour", nil, nil, "Home Screen", 4, "Changes the color of the close and min button", nil, nil}, homeTimeColor = {{1, .82, 0}, "colour", nil, nil, "Home Screen", 5, "Changes the color of the time on the home screen", nil, nil}, + language = {(GetLocale() == "frFR" and "Francais" or "English"), "dropdown", {"English", "Francais"}, nil, "localization", 6, "Select the language used in the configuration UI", nil, nil}, }) DFRL:NewMod("GUI-Dragonflight", 4, function() @@ -313,6 +314,7 @@ DFRL:NewMod("GUI-Dragonflight", 4, function() -- callbacks local callbacks = {} + local lastAppliedLanguage = nil callbacks.homeTimeColor = function (value) Setup.timeText:SetTextColor(value[1], value[2], value[3]) @@ -351,6 +353,21 @@ DFRL:NewMod("GUI-Dragonflight", 4, function() end end + callbacks.language = function(value) + if not lastAppliedLanguage then + lastAppliedLanguage = value + return + end + + if lastAppliedLanguage == value then + return + end + + lastAppliedLanguage = value + DFRL:SaveTempDB() + ReloadUI() + end + callbacks.globalFont = function(value) local fontPath if value == 'Expressway' then diff --git a/modules/gui/info.lua b/modules/gui/info.lua index f32dc9b..a3ddcc1 100644 --- a/modules/gui/info.lua +++ b/modules/gui/info.lua @@ -264,7 +264,7 @@ self.grid:AddElement(6, 8, scriptText:SetText(scriptName) scriptText:SetTextColor(1, 1, 1) - statusText:SetText(DFRL.activeScripts[scriptName] and "ON" or "OFF") + statusText:SetText(DFRL:TR(DFRL.activeScripts[scriptName] and "ON" or "OFF")) statusText:SetTextColor(DFRL.activeScripts[scriptName] and 0 or 0.5, DFRL.activeScripts[scriptName] and 1 or 0.5, DFRL.activeScripts[scriptName] and 0 or 0.5) index = index + 1 @@ -294,7 +294,7 @@ self.grid:AddElement(6, 8, scriptText:SetText(scriptName) scriptText:SetTextColor(1, 1, 1) - statusText:SetText(DFRL.activeScripts[scriptName] and "ON" or "OFF") + statusText:SetText(DFRL:TR(DFRL.activeScripts[scriptName] and "ON" or "OFF")) statusText:SetTextColor(DFRL.activeScripts[scriptName] and 0 or 0.5, DFRL.activeScripts[scriptName] and 1 or 0.5, DFRL.activeScripts[scriptName] and 0 or 0.5) index = index + 1 diff --git a/modules/gui/mods.lua b/modules/gui/mods.lua index bae809d..7a951f1 100644 --- a/modules/gui/mods.lua +++ b/modules/gui/mods.lua @@ -49,7 +49,7 @@ DFRL:NewMod("Gui-mods", 3, function() local moduleName = modules[i] local checkbox = DFRL.tools.CreateCheckbox(nil, nil, moduleName, "enabled", true) - checkbox.label:SetText(moduleName) + checkbox.label:SetText(DFRL:TR(moduleName)) self.grid:AddElement(row, line, checkbox) line = line + 1 diff --git a/modules/gui/prof.lua b/modules/gui/prof.lua index 8427693..2f9ce2f 100644 --- a/modules/gui/prof.lua +++ b/modules/gui/prof.lua @@ -44,11 +44,11 @@ DFRL:NewMod("Gui-prof", 4, function() switchBtns = {}, newProfileBtn = nil, resetBtn = nil, + saveBtn = nil, warner = nil } } - function Setup:ListFrame() if not self.headers then self.grid:AddElement(2, 1, DFRL.tools.CreateCategoryHeader(nil, "Manage")) @@ -56,13 +56,13 @@ DFRL:NewMod("Gui-prof", 4, function() end if not self.ui.usageText then - self.ui.usageText = DFRL.tools.CreateFont(panel, 14, "Usage:\n\n\n1) new profile: create and switch to a new profile\n\n2) switch: change active profile\n\n3) copy: copies all settings into active profile\n\n4) delete: delete profile and switch back to default\n\n5)reset: reset active profile to the default settings\n\n\ndoes not affect shagutweaks\n\nBUG: DOUBLE CLICK DELETE AFTER NEW PROFILE\n\nBUG: ENTER PROFILE NAME STAYS", {.5, .5, .5}, "LEFT") + self.ui.usageText = DFRL.tools.CreateFont(panel, 14, "Profiles help text", {.65, .65, .65}, "LEFT") self.grid:AddElement(5, 4, self.ui.usageText) end if not self.ui.frame then self.ui.frame = CreateFrame("Frame", nil, panel) - self.ui.frame:SetWidth(300) - self.ui.frame:SetHeight(400) + self.ui.frame:SetWidth(320) + self.ui.frame:SetHeight(420) self.grid:AddElement(2, 3, self.ui.frame) T.GradientLine(self.ui.frame, "TOP", 20, 2) T.GradientLine(self.ui.frame, "TOP", 60, 2) @@ -76,7 +76,7 @@ DFRL:NewMod("Gui-prof", 4, function() self.ui.curText:SetFont(self.font .. "BigNoodleTitling.ttf", self.TEXT_SIZE, "OUTLINE") self.ui.curText:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 10, -10) end - self.ui.curText:SetText("Current: |cff80ff80" .. curProf .. "|r") + self.ui.curText:SetText(DFRL:TR("Current") .. ": |cff80ff80" .. DFRL:DisplayProfileName(curProf) .. "|r") for _, text in pairs(self.ui.texts) do text:Hide() end @@ -113,12 +113,12 @@ DFRL:NewMod("Gui-prof", 4, function() local text = self.ui.frame:CreateFontString(nil, "OVERLAY") text:SetFont(self.font .. "BigNoodleTitling.ttf", self.TEXT_SIZE, "OUTLINE") text:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 10, yOffset) - text:SetText(name) + text:SetText(DFRL:DisplayProfileName(name)) table.insert(self.ui.texts, text) if name ~= "Default" then local profName = name - local switchBtn = DFRL.tools.CreateButton(self.ui.frame, "Switch", 50, 20, true, {0.5, 1, 0.5}) - switchBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 125, yOffset) + local switchBtn = DFRL.tools.CreateButton(self.ui.frame, "Switch", 55, 20, true, {0.5, 1, 0.5}) + switchBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 135, yOffset) switchBtn.profName = profName switchBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -132,13 +132,17 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("switched to " .. clickedName) + if DFRL:IsFrench() then + Setup.ui.warner:SetText(DFRL:TR("switched to") .. " " .. clickedName) + else + Setup.ui.warner:SetText("switched to " .. clickedName) + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) table.insert(self.ui.switchBtns, switchBtn) - local copyBtn = DFRL.tools.CreateButton(self.ui.frame, "Copy", 50, 20, true) - copyBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 180, yOffset) + local copyBtn = DFRL.tools.CreateButton(self.ui.frame, "Copy", 55, 20, true) + copyBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 195, yOffset) copyBtn.profName = profName copyBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -152,13 +156,17 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 1, 0) - Setup.ui.warner:SetText("profile copied from " .. clickedName) + if DFRL:IsFrench() then + Setup.ui.warner:SetText(DFRL:TR("profile copied from") .. " " .. clickedName) + else + Setup.ui.warner:SetText("profile copied from " .. clickedName) + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) table.insert(self.ui.copyBtns, copyBtn) - local delBtn = DFRL.tools.CreateButton(self.ui.frame, "Delete", 50, 20, true, {1, 0.5, 0.5}) - delBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 235, yOffset) + local delBtn = DFRL.tools.CreateButton(self.ui.frame, "Delete", 55, 20, true, {1, 0.5, 0.5}) + delBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPLEFT", 255, yOffset) delBtn.profName = profName delBtn:SetScript("OnClick", function() local clickedName = this.profName @@ -171,7 +179,11 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText(clickedName .. " deleted") + if DFRL:IsFrench() then + Setup.ui.warner:SetText(clickedName .. " " .. DFRL:TR("deleted")) + else + Setup.ui.warner:SetText(clickedName .. " deleted") + end Setup.ui.warner:Show() Setup:RestartWarnerPulse() end) @@ -181,7 +193,6 @@ DFRL:NewMod("Gui-prof", 4, function() yOffset = yOffset - 20 end - end function Setup:RestartWarnerPulse() @@ -219,8 +230,13 @@ DFRL:NewMod("Gui-prof", 4, function() end function Setup:ExtraButtons() + if not self.ui.actionsHeader then + self.ui.actionsHeader = DFRL.tools.CreateCategoryHeader(panel, "Quick Actions", false, 150, 24, 14) + self.ui.actionsHeader:SetPoint("BOTTOMLEFT", self.ui.frame, "TOPRIGHT", 10, -22) + end + if not self.ui.newProfileBtn then - self.ui.newProfileBtn = DFRL.tools.CreateButton(panel, "New Profile", 100, 30, true) + self.ui.newProfileBtn = DFRL.tools.CreateButton(panel, "New Profile", 130, 30, true) self.ui.newProfileBtn:SetPoint("TOPLEFT", self.ui.frame, "TOPRIGHT", 20, -25) self.ui.newProfileBtn:SetScript("OnClick", function() local count = 0 @@ -233,7 +249,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText("MAX PROFILES REACHED") + Setup.ui.warner:SetText(DFRL:TR("MAX PROFILES REACHED")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() return @@ -259,7 +275,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("new profile created") + Setup.ui.warner:SetText(DFRL:TR("new profile created")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() end @@ -275,7 +291,7 @@ DFRL:NewMod("Gui-prof", 4, function() end if not self.ui.resetBtn then - self.ui.resetBtn = DFRL.tools.CreateButton(panel, "Reset", 100, 30, true, {1, 0.5, 0.5}) + self.ui.resetBtn = DFRL.tools.CreateButton(panel, "Reset", 130, 30, true, {1, 0.5, 0.5}) self.ui.resetBtn:SetPoint("TOPLEFT", self.ui.newProfileBtn, "BOTTOMLEFT", 0, -10) self.ui.resetBtn:SetScript("OnClick", function() local success, _ = pcall(function() @@ -288,7 +304,7 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(0, 1, 0) - Setup.ui.warner:SetText("CURRENT PROFILE RESET") + Setup.ui.warner:SetText(DFRL:TR("CURRENT PROFILE RESET")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() else @@ -297,13 +313,28 @@ DFRL:NewMod("Gui-prof", 4, function() Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) end Setup.ui.warner:SetTextColor(1, 0, 0) - Setup.ui.warner:SetText("PROFILE RESET FAILED") + Setup.ui.warner:SetText(DFRL:TR("PROFILE RESET FAILED")) Setup.ui.warner:Show() Setup:RestartWarnerPulse() end end) end + if not self.ui.saveBtn then + self.ui.saveBtn = DFRL.tools.CreateButton(panel, "Save Profile", 130, 30, true, {0.5, 1, 0.5}) + self.ui.saveBtn:SetPoint("TOPLEFT", self.ui.resetBtn, "BOTTOMLEFT", 0, -10) + self.ui.saveBtn:SetScript("OnClick", function() + DFRL:SaveTempDB() + if not Setup.ui.warner then + Setup.ui.warner = DFRL.tools.CreateFontWarner(panel, 14, "", {0, 1, 0}, true, 3) + Setup.ui.warner:SetPoint("TOP", Setup.ui.frame, "BOTTOM", 0, 25) + end + Setup.ui.warner:SetTextColor(0, 1, 0) + Setup.ui.warner:SetText(DFRL:TR("profile saved")) + Setup.ui.warner:Show() + Setup:RestartWarnerPulse() + end) + end end --================= diff --git a/modules/gui/shag.lua b/modules/gui/shag.lua index f4ade38..9f1a959 100644 --- a/modules/gui/shag.lua +++ b/modules/gui/shag.lua @@ -133,7 +133,7 @@ DFRL:NewMod("Gui-shag", 3, function() local desc = panel:CreateFontString(nil, "OVERLAY", "GameFontNormal") desc:SetFont(self.font .. "BigNoodleTitling.ttf", self.DESCRIPTION_FONT_SIZE, "OUTLINE") desc:SetPoint("TOPLEFT", panel, "TOPLEFT", 10, -yPos) - desc:SetText(element.data.description or element.key) + desc:SetText(DFRL:TR(element.data.description or element.key)) desc:SetTextColor(.9, .9, .9) self.descriptionLabels[element.key] = desc @@ -150,7 +150,7 @@ DFRL:NewMod("Gui-shag", 3, function() local txt = panel:CreateFontString(nil, "OVERLAY") txt:SetFont(self.font .. "BigNoodleTitling.ttf", 30, "OUTLINE") txt:SetPoint("TOP", panel, "TOP", 10, -yPos-50) - txt:SetText("SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS") + txt:SetText(DFRL:TR("SHAGU TWEAKS EXTRAS MISSING\nINSTALL FOR MORE OPTIONS")) txt:SetTextColor(1, 0.5, 0.5) local f3 = CreateFrame("Frame") f3.t = 0 diff --git a/modules/gui/tools.lua b/modules/gui/tools.lua index 02b5cfd..bea2bb6 100644 --- a/modules/gui/tools.lua +++ b/modules/gui/tools.lua @@ -98,8 +98,15 @@ function DFRL.tools.CreateFont(parent, size, text, colour, align) font:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", size or 14, "OUTLINE") colour = colour or {1, 1, 1} font:SetTextColor(colour[1], colour[2], colour[3]) - font:SetText(text) + font.rawText = text + font:SetText(DFRL:TR(text or "")) font.align = align or "CENTER" + + function font:SetLocalizedText(newText) + self.rawText = newText + self:SetText(DFRL:TR(newText or "")) + end + return font end @@ -107,21 +114,37 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo local btn = CreateFrame("Button", nil, parent or UIParent) btn:SetWidth(width or 140) btn:SetHeight(height or 30) + if not noBackdrop then btn:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, tileSize = 16, edgeSize = 16, + tile = true, tileSize = 16, edgeSize = 14, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) - btn:SetBackdropColor(0, 0, 0, .5) - btn:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) + btn:SetBackdropColor(0.04, 0.04, 0.04, .88) + btn:SetBackdropBorderColor(1, 0.82, 0, 0.35) + else + local bg = btn:CreateTexture(nil, "BACKGROUND") + bg:SetTexture("Interface\\Buttons\\WHITE8X8") + bg:SetPoint("TOPLEFT", btn, "TOPLEFT", 1, -1) + bg:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -1, 1) + bg:SetVertexColor(0.08, 0.08, 0.08, 0.28) + btn._bg = bg + + local border = btn:CreateTexture(nil, "BORDER") + border:SetTexture("Interface\\Buttons\\WHITE8X8") + border:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0) + border:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0) + border:SetVertexColor(1, 0.82, 0, 0.16) + btn._border = border end local btnTxt = btn:CreateFontString(nil, "OVERLAY") btnTxt:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") btnTxt:SetPoint("CENTER", btn, "CENTER", 0, 0) - btnTxt:SetText(text) + btn.rawText = text + btnTxt:SetText(DFRL:TR(text or "")) if textColor then btnTxt:SetTextColor(textColor[1], textColor[2], textColor[3]) @@ -131,6 +154,11 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo btn.text = btnTxt + function btn:SetLocalizedText(newText) + self.rawText = newText + self.text:SetText(DFRL:TR(newText or "")) + end + local origEnable = btn.Enable local origDisable = btn.Disable @@ -141,11 +169,17 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo else btnTxt:SetTextColor(1, 1, 1) end + if self.SetBackdropBorderColor and not noBackdrop then + self:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end end btn.Disable = function(self) origDisable(self) btnTxt:SetTextColor(0.5, 0.5, 0.5) + if self.SetBackdropBorderColor and not noBackdrop then + self:SetBackdropBorderColor(0.4, 0.4, 0.4, 0.2) + end end local highlight = btn:CreateTexture(nil, "HIGHLIGHT") @@ -154,6 +188,24 @@ function DFRL.tools.CreateButton(parent, text, width, height, noBackdrop, textCo highlight:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -2, 4) highlight:SetBlendMode("ADD") + btn:SetScript("OnEnter", function() + if noBackdrop then + if this._bg then this._bg:SetVertexColor(0.12, 0.12, 0.12, 0.45) end + if this._border then this._border:SetVertexColor(1, 0.82, 0, 0.45) end + else + this:SetBackdropBorderColor(1, 0.82, 0, 0.65) + end + end) + + btn:SetScript("OnLeave", function() + if noBackdrop then + if this._bg then this._bg:SetVertexColor(0.08, 0.08, 0.08, 0.28) end + if this._border then this._border:SetVertexColor(1, 0.82, 0, 0.16) end + else + this:SetBackdropBorderColor(1, 0.82, 0, 0.35) + end + end) + return btn end @@ -165,7 +217,7 @@ function DFRL.tools.CreateIndiCheckbox(parent, name, text) local label = checkbox:CreateFontString(nil, "BACKGROUND") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - label:SetText(text or "Checkbox") + label:SetText(DFRL:TR(text or "Checkbox")) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -194,18 +246,20 @@ function DFRL.tools.CreateIndiSlider(parent, name, text, minVal, maxVal, step) slider:SetOrientation("HORIZONTAL") slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") slider:SetBackdrop({ - bgFile = "Interface\\Buttons\\UI-SliderBar-Background", - edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", - tile = true, tileSize = 8, edgeSize = 8, + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 10, insets = { left = 3, right = 3, top = 6, bottom = 6 } }) + slider:SetBackdropColor(0.03, 0.03, 0.03, 0.85) + slider:SetBackdropBorderColor(1, 0.82, 0, 0.18) slider:SetMinMaxValues(minVal or 0, maxVal or 5) slider:SetValueStep(step or 0.1) local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - label:SetText(text or "Slider") + label:SetText(DFRL:TR(text or "Slider")) label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetTextColor(.9,.9,.9) slider.label = label @@ -279,13 +333,15 @@ function DFRL.tools.CreateIndiDropDown(parent, text, items, width, height) btn.popup = popup btn.selectedValue = items[1] + btn.text:SetText(DFRL:TR(btn.selectedValue)) for i = 1, table.getn(items) do local itemBtn = DFRL.tools.CreateButton(popup, items[i], popup:GetWidth() - 4, 20, true) + itemBtn.itemValue = items[i] itemBtn:SetPoint("TOP", popup, "TOP", 0, -(i - 1) * 22 - 5) itemBtn:SetScript("OnClick", function() - btn.text:SetText(this.text:GetText()) - btn.selectedValue = this.text:GetText() + btn.text:SetText(DFRL:TR(this.itemValue)) + btn.selectedValue = this.itemValue popup:Hide() end) end @@ -320,10 +376,12 @@ function DFRL.tools.CreateEditBox(parent, width, height, letters, numbers, max) box:SetHeight(height or 20) box:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", - insets = { left = -5, right = -5, top = 0, bottom = 0 } + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } }) - box:SetBackdropColor(0, 0, 0, 0.8) - box:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) + box:SetBackdropColor(0.02, 0.02, 0.02, 0.9) + box:SetBackdropBorderColor(1, 0.82, 0, 0.25) box:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 14, "OUTLINE") box:SetTextColor(1, 1, 1) box:SetTextInsets(5, 5, 5, 5) @@ -390,19 +448,31 @@ function DFRL.tools.CreateCategoryHeader(parent, categoryName, noBG, width, heig tile = true, tileSize = 16, edgeSize = 16, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) - categoryBg:SetBackdropColor(0.1, 0.1, 0.1, 0.6) - categoryBg:SetBackdropBorderColor(0.1, 0.1, 0.1, 0.5) + categoryBg:SetBackdropColor(0.05, 0.05, 0.05, 0.78) + categoryBg:SetBackdropBorderColor(1, 0.82, 0, 0.22) end local categoryTitle = categoryBg:CreateFontString(nil, "OVERLAY") categoryTitle:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", txtSize or 14, "OUTLINE") categoryTitle:SetPoint("CENTER", categoryBg, "CENTER", 0, 1) - local words = string.gfind(categoryName, "%S+") - local capitalizedWords = {} - for word in words do - table.insert(capitalizedWords, string.upper(string.sub(word, 1, 1)) .. string.sub(word, 2)) + categoryBg.title = categoryTitle + categoryBg.rawCategoryName = categoryName + + function categoryBg:RefreshText() + local localizedName = DFRL:TR(self.rawCategoryName or "") + if DFRL:IsFrench() then + self.title:SetText(localizedName) + else + local words = string.gfind(localizedName, "%S+") + local capitalizedWords = {} + for word in words do + table.insert(capitalizedWords, string.upper(string.sub(word, 1, 1)) .. string.sub(word, 2)) + end + self.title:SetText(table.concat(capitalizedWords, " ")) + end end - categoryTitle:SetText(table.concat(capitalizedWords, " ")) + + categoryBg:RefreshText() categoryTitle:SetTextColor(1, 0.82, 0) return categoryBg @@ -416,8 +486,7 @@ function DFRL.tools.CreateCheckbox(parent, name, moduleName, key, noCall) local label = checkbox:CreateFontString(nil, "BACKGROUND") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayTxt) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -445,7 +514,7 @@ function DFRL.tools.CreateShaguCheckbox(parent, name, key) local label = checkbox:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 14, "OUTLINE") label:SetPoint("LEFT", checkbox, "RIGHT", 5, 0) - label:SetText(key) + label:SetText(DFRL:TR(key)) label:SetTextColor(.9,.9,.9) checkbox.label = label @@ -490,8 +559,7 @@ function DFRL.tools.CreateSlider(parent, name, moduleName, key, minVal, maxVal, local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayTxt) label:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") label:SetTextColor(.9,.9,.9) @@ -591,19 +659,20 @@ function DFRL.tools.CreateColour(parent, name, moduleName, key) slider:SetOrientation("HORIZONTAL") slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") slider:SetBackdrop({ - bgFile = "Interface\\Buttons\\UI-SliderBar-Background", - edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", - tile = true, tileSize = 8, edgeSize = 8, + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 10, insets = { left = 3, right = 3, top = 6, bottom = 6 } }) + slider:SetBackdropColor(0.03, 0.03, 0.03, 0.85) + slider:SetBackdropBorderColor(1, 0.82, 0, 0.18) slider:SetMinMaxValues(1, COLOR_COUNT) slider:SetValueStep(1) local label = slider:CreateFontString(nil, "OVERLAY", "GameFontNormal") label:SetPoint("BOTTOMLEFT", slider, "TOPLEFT", 0, -0) - local displayText = string.gsub(key, "(%l)(%u)", "%1 %2") - displayText = string.upper(string.sub(displayText, 1, 1)) .. string.sub(displayText, 2) + local displayText = DFRL:GetOptionLabel(moduleName, key) label:SetText(displayText) label:SetFont("Fonts\\FRIZQT__.TTF", 11, "") label:SetTextColor(.9,.9,.9) @@ -680,8 +749,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, local btnTxt = btn:CreateFontString(nil, "OVERLAY") btnTxt:SetFont(DFRL:GetInfoOrCons("font") .. "BigNoodleTitling.ttf", 12, "OUTLINE") btnTxt:SetPoint("CENTER", btn, "CENTER", 0, 0) - local displayTxt = string.gsub(key, "(%l)(%u)", "%1 %2") - displayTxt = string.upper(string.sub(displayTxt, 1, 1)) .. string.sub(displayTxt, 2) + local displayTxt = DFRL:GetOptionLabel(moduleName, key) btnTxt:SetText(displayTxt) btnTxt:SetTextColor(1, 1, 1) btn.text = btnTxt @@ -693,7 +761,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, local currentValue = DFRL:GetTempDB(moduleName, key) if currentValue then - btnTxt:SetText(currentValue) + btnTxt:SetText(DFRL:TR(currentValue)) end if not btn.popup then @@ -705,12 +773,20 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, popup:SetFrameStrata("DIALOG") popup:SetToplevel(true) popup:EnableMouse(true) + popup:SetBackdrop({ + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, tileSize = 8, edgeSize = 12, + insets = { left = 3, right = 3, top = 3, bottom = 3 } + }) + popup:SetBackdropColor(0.02, 0.02, 0.02, 0.95) + popup:SetBackdropBorderColor(1, 0.82, 0, 0.25) DFRL.tools.GradientLine(popup, "TOP", 2) local bg = popup:CreateTexture(nil, "BACKGROUND") bg:SetTexture("Interface\\Buttons\\WHITE8X8") bg:SetAllPoints(popup) - bg:SetVertexColor(0, 0, 0, .8) + bg:SetVertexColor(0.02, 0.02, 0.02, .92) popup:Hide() btn.popup = popup @@ -724,7 +800,7 @@ function DFRL.tools.CreateDropDown(parent, name, moduleName, key, items, noCall, itemBtn.itemText = items[i] itemBtn:SetScript("OnClick", function() - btn.text:SetText(this.itemText) + btn.text:SetText(DFRL:TR(this.itemText)) if noCall then DFRL:SetTempDBNoCallback(moduleName, key, this.itemText) else @@ -841,7 +917,13 @@ function DFRL.tools.CreateFontWarner(parent, size, text, colour, pulse, time) fontString:SetTextColor(1, 1, 1) end - fontString:SetText(text) + fontString.rawText = text + fontString:SetText(DFRL:TR(text or "")) + + function fontString:SetLocalizedText(newText) + self.rawText = newText + self:SetText(DFRL:TR(newText or "")) + end if pulse or time then local frame = CreateFrame("Frame") diff --git a/modules/micro/micro.lua b/modules/micro/micro.lua index 2ca753c..8fc76ff 100644 --- a/modules/micro/micro.lua +++ b/modules/micro/micro.lua @@ -20,6 +20,7 @@ DFRL:NewMod("Micro", 1, function() pvpButton = nil, lftButton = nil, ebcButton = nil, + ijStandaloneButton = nil, msText = nil, bwText = nil, @@ -157,6 +158,71 @@ DFRL:NewMod("Micro", 1, function() end) end + + function Setup:CreateInstanceJournalStandaloneButton() + if self.ijStandaloneButton then return end + + self.ijStandaloneButton = CreateFrame("Button", "DFRLIJStandaloneButton", self.microMenuContainer) + self.ijStandaloneButton:SetWidth(self.buttonWidth) + self.ijStandaloneButton:SetHeight(self.buttonHeight) + self.ijStandaloneButton:SetHitRectInsets(0, 0, 0, 0) + self.ijStandaloneButton:Show() + self.ijStandaloneButton:Enable() + + self.ijStandaloneButton:SetScript("OnClick", function() + if _G["InstanceJournal"] and InstanceJournal.ToggleInstanceJournal then + InstanceJournal:ToggleInstanceJournal() + elseif _G["ToggleInstanceJournal"] then + ToggleInstanceJournal() + end + end) + + self.ijStandaloneButton:SetScript("OnEnter", function() + GameTooltip:SetOwner(self.ijStandaloneButton, "ANCHOR_RIGHT") + GameTooltip:SetText("Instance Journal", 1, 1, 1) + GameTooltip:AddLine("Open the Instance Journal.") + GameTooltip:Show() + end) + + self.ijStandaloneButton:SetScript("OnLeave", function() + GameTooltip:Hide() + end) + end + + function Setup:PositionInstanceJournalStandaloneButton(spacing) + if not self.ijStandaloneButton or not self.buttons or not self.buttons[table.getn(self.buttons)] then return end + local lastButton = self.buttons[table.getn(self.buttons)] + self.ijStandaloneButton:ClearAllPoints() + self.ijStandaloneButton:SetPoint("TOPLEFT", lastButton, "TOPRIGHT", spacing or self.buttonSpacing, 0) + self.ijStandaloneButton:SetParent(self.microMenuContainer) + self.ijStandaloneButton:SetFrameStrata(lastButton:GetFrameStrata()) + self.ijStandaloneButton:SetFrameLevel(lastButton:GetFrameLevel()) + end + + function Setup:ApplyInstanceJournalStandaloneStyle(useColor) + if not self.ijStandaloneButton then return end + local colorpath = self.texpath .. "color_micro\\" + if useColor then + self.ijStandaloneButton:SetNormalTexture(colorpath .. "instancejournal-regular.tga") + self.ijStandaloneButton:SetPushedTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetHighlightTexture(colorpath .. "instancejournal-highlight.tga") + else + self.ijStandaloneButton:SetNormalTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetPushedTexture(colorpath .. "instancejournal-faded.tga") + self.ijStandaloneButton:SetHighlightTexture(colorpath .. "instancejournal-highlight.tga") + end + if self.ijStandaloneButton:GetNormalTexture() then + self.ijStandaloneButton:GetNormalTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + self.ijStandaloneButton:GetNormalTexture():Show() + end + if self.ijStandaloneButton:GetPushedTexture() then + self.ijStandaloneButton:GetPushedTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + end + if self.ijStandaloneButton:GetHighlightTexture() then + self.ijStandaloneButton:GetHighlightTexture():SetTexCoord(36/128, 86/128, 29/128, 98/128) + end + end + function Setup:LowLevelTalentButton() if not DFRL.lowLevelTalentsButton then local lowLevelTalentsButton = CreateFrame("Button", "DFRLLowLevelTalentsButton", Setup.microMenuContainer) @@ -365,6 +431,9 @@ DFRL:NewMod("Micro", 1, function() self:LFTButton() self:EBCButton() self:ArrangeButtons() + self:CreateInstanceJournalStandaloneButton() + self:PositionInstanceJournalStandaloneButton(self.buttonSpacing) + self:ApplyInstanceJournalStandaloneStyle(DFRL:GetTempDB("Micro", "switchColor")) self:HideOtherUI() self:DisableBlizzardFPS() @@ -443,6 +512,7 @@ DFRL:NewMod("Micro", 1, function() end DFRL.microMenuContainer:SetWidth((Setup.buttonWidth + value) * table.getn(Setup.buttons)) + Setup:PositionInstanceJournalStandaloneButton(value) end end @@ -635,6 +705,7 @@ DFRL:NewMod("Micro", 1, function() end end + Setup:ApplyInstanceJournalStandaloneStyle(value) callbacks.microColor(DFRL:GetTempDB("Micro", "microColor")) end diff --git a/modules/track/track.lua b/modules/track/track.lua index 9a9d472..1dc3e44 100644 --- a/modules/track/track.lua +++ b/modules/track/track.lua @@ -13,6 +13,7 @@ DFRL:NewMod("UpdateNotifier", 1, function() txt2 = nil, dd = nil, btn = nil, + closeBtn = nil, } function Setup:ParseDate(dateStr) @@ -102,6 +103,36 @@ DFRL:NewMod("UpdateNotifier", 1, function() DFRL.tools.MoveFrame(self.frame, 0, 1, .3, 120) end) end + + if not self.closeBtn then + self.closeBtn = CreateFrame("Button", nil, self.frame) + self.closeBtn:SetWidth(18) + self.closeBtn:SetHeight(18) + self.closeBtn:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -6, -6) + self.closeBtn:SetFrameStrata(self.frame:GetFrameStrata()) + + self.closeBtn.text = self.closeBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal") + self.closeBtn.text:SetAllPoints() + self.closeBtn.text:SetText("X") + + self.closeBtn:SetScript("OnEnter", function() + if self.closeBtn.text then + self.closeBtn.text:SetTextColor(1, 0.2, 0.2) + end + end) + + self.closeBtn:SetScript("OnLeave", function() + if self.closeBtn.text then + self.closeBtn.text:SetTextColor(1, 0.82, 0) + end + end) + + self.closeBtn:SetScript("OnClick", function() + DFRL.tools.MoveFrame(self.frame, 0, 1, .3, 120) + end) + + self.closeBtn.text:SetTextColor(1, 0.82, 0) + end end function Setup:Run()