diff SayIt.lua @ 0:24f337b9dfa0

Initial commit, testing .pkgmeta
author contrebasse
date Sun, 08 May 2011 17:11:26 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SayIt.lua	Sun May 08 17:11:26 2011 +0200
@@ -0,0 +1,604 @@
+--[[ TODO :
+- Changer la couleur pour toutes les fenêtres de quête (possible ?)
+- Chercher le texte pour les couleurs à partir de la somme des longueurs de texte précédents (incrémental), compliqué !
+- Modifier les variables statiques directement dans la fonction Paragraphes() (Bof...)
+- Traduction
+- Clic droit pour phrase perso
+- Shif clic droit pour emote
+- griser le choix des couleurs si pas de coloration
+- reset des options (virer les couleurs foireuses...)
+--]]
+
+--********************************************************
+--
+-- Déclarations de variables
+--
+--********************************************************
+--
+-- Variables statiques
+--
+local target_name = "" -- "" vide ou nom du npc
+local text_table = {}  -- table du texte à dire
+local text_full = ''
+local i_phrase = 1     -- indice de la prochaine phrase à dire
+--local char_dits = 0    -- nombre de caractères prononcés, pour améliorer la recherche lors de la coloration
+local max_phrase = 0   -- indice du nombre de phrases à dire
+local gossip_button, quest_button, current_button
+local TextFrame
+
+--
+-- Fonctions locales pour accélérer l'exécution
+--
+local _G = _G
+local GetUnitName = GetUnitName
+local GetQuestText = GetQuestText
+local GetProgressText = GetProgressText
+local GetGossipText = GetGossipText
+local GetRewardText = GetRewardText
+local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME
+local UIErrorsFrame,UIErrorsFrame_OnEvent = UIErrorsFrame,UIErrorsFrame_OnEvent
+local SendChatMessage = SendChatMessage
+local GameTooltip = GameTooltip
+local CreateFrame = CreateFrame
+local IsShiftKeyDown,IsControlKeyDown = IsShiftKeyDown,IsControlKeyDown
+local GossipFrame,QuestFrame = GossipFrame,QuestFrame
+local GossipGreetingText = GossipGreetingText
+local QuestProgressText = QuestProgressText
+local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor;
+
+local tonumber = tonumber;
+local string = string;
+local string_format = string.format;
+
+local LibStub = LibStub;
+
+--********************************************************
+--
+-- Fonctions de debug et warning
+--
+--********************************************************
+--
+-- fonction qui affiche des messages de debug
+--
+local function DEBUG(msg)
+	--if true then return end
+	if not msg then msg="nil" end
+	DEFAULT_CHAT_FRAME:AddMessage("(DEBUG) " .. msg);
+end
+
+local function Warn(msg)
+	if not msg then return end
+	--DEFAULT_CHAT_FRAME:AddMessage("(SayIt) "..msg);
+	local event = "UI_INFO_MESSAGE"
+	UIErrorsFrame_OnEvent(UIErrorsFrame, event, msg)
+end
+
+
+--********************************************************
+--
+-- Analyse de texte
+--
+--********************************************************
+--
+-- Function qui sépare les paragraphes/phrases d'un texte en éléments de tableau
+--
+local function Paragraphes(txt)
+	-- Si pas de texte, pas la peine de continuer
+	if not txt or txt=="" then
+		return {}, 0
+	end
+
+	local text = {}
+	local p = 1
+	for paragraph in txt:gmatch("[^\r\n]+") do
+		-- On enlève au texte le double '|', le nom du Npc le " dit : " et un caractère en plus (fin de string ?)
+
+		-- Est-ce une émote ?
+		local e = (paragraph:sub(1,1)=="<" and paragraph:sub(-1)==">")
+		local t,Nchar_supp
+		if e then
+			Nchar_supp = 2
+			t = paragraph:sub(2,-2) -- on vire les < >
+		else
+			Nchar_supp = 9+target_name:len()
+			t = paragraph
+		end
+
+		-- Coupe par phrase
+		-- [.!?]+ : au moins un signe de ponctuation, permet de gérer ... !? ?! par exemple
+		-- [^%s][^%s]%s* : le dernier mot de la phrase dois avoir au moins 2 caractères, pour éviter de couper "M. Dupont" (pas parfait mais mieux que rien)
+		-- on transforme chaque phrase en paragraphe, et on repasse le test précédent
+		for tt in t:gsub('([^%s][^%s]%s*[%.%!%?]+)(%s+)(%u)','%1\n%3'):gmatch('[^\r\n]+') do --for tt in t:gmatch('(.-[.!?]+)%s*') do
+			text[p] = { -- Le texte est coupé au cas où...
+			["texte"] = tt:sub(1,254-Nchar_supp), -- ça devrait être 255, mais ça ne passe pas...
+			["emote"] = e }
+			p = p+1
+		end
+	end
+
+	return text, p-1
+end
+
+--
+-- Coloration du texte de la fenêtre
+--
+local cDit = "|cff".."606060" -- gris clair
+local cJusteDit = "|cff".."7f0000" -- gris foncé
+local cADire = "|cff".."00007f" -- jaunasse
+local cNonDit = "|cff".."202020" -- noir
+
+local function SpecialChar(txt)
+	return txt and txt:gsub('([%(%)%.%+%-%*%?%[%^%$%]])','%%%1') or ''
+end
+local function ColorieTexte(txt)
+	--print('______')
+	local tJusteDit,tADire
+	if i_phrase > 1 then
+		tJusteDit = text_table[i_phrase-1].texte
+	end
+	if i_phrase <= max_phrase then
+		tADire = text_table[i_phrase].texte
+	end
+	
+	--print(txt)
+	--print('^(.*)('..SpecialChar(tJusteDit)..')(.-)('..SpecialChar(tADire)..')(.*)$')
+	local _,_,tDit,tJusteDit2,space,tADire2,tNonDit = txt:find('^(.-)('..SpecialChar(tJusteDit)..')(.-)('..SpecialChar(tADire)..')(.*)$') --,char_dits)
+
+	--print('tDit:'..(tDit or ''))
+	--print('tJusteDit2:'..(tJusteDit2 or ''))
+	--print('tADire2:'..(tADire2 or ''))
+	--print('tNonDit:'..(tNonDit or ''))
+
+	return (tDit and SayItOptions.cDit..tDit..'|r' or '' )..
+			(tJusteDit and SayItOptions.cJusteDit..tJusteDit..'|r' or '' )..
+			(space or '')..(tADire and SayItOptions.cADire..tADire..'|r' or '' )..
+			(tNonDit and SayItOptions.cNonDit..tNonDit..'|r' or '' )
+end
+
+--
+-- Faire parler un Npc
+--
+local function NpcDit(txt)
+	if not txt then return end
+	if not txt.emote then
+		SendChatMessage("\124\124 "..GetUnitName("Npc").." dit : "..
+				txt.texte,"EMOTE")
+	else
+		SendChatMessage("\124\124 "..txt.texte,"EMOTE")
+		return
+	end
+end
+
+
+--********************************************************
+--
+-- Boutons et tooltips
+--
+--********************************************************
+--
+-- Remplissage du tooltip
+--
+local function TooltipUpdate(b)
+	if max_phrase>0 then
+		-- Coloration du texte dans la fenêtre
+		if TextFrame and SayItOptions.colorisation == 2 then
+			TextFrame:SetText(ColorieTexte(text_full))
+		end
+
+		-- tooltip
+		if not SayItOptions.tooltip then return end
+
+		if SayItOptions.ancre_tooltip then
+			GameTooltip:SetOwner(b,"ANCHOR_BOTTOMRIGHT")-- Position du tooltip
+		else
+			GameTooltip_SetDefaultAnchor(GameTooltip, b)
+		end
+
+		-- texte du tolltip
+		GameTooltip:SetText(target_name,1,1,1) -- Nom du Pnj
+		if SayItOptions.texte_tooltip then
+			local txt = ""
+			if i_phrase <= max_phrase then
+				if not text_table[i_phrase].emote then
+					GameTooltip:AppendText(" va dire :")
+				else
+					GameTooltip:AppendText(" :")
+				end
+				txt = text_table[i_phrase].texte
+				GameTooltip:AddLine('"'..txt..'"',1,0.82,0,true)
+			else
+				GameTooltip:AppendText(" a terminé.")
+			end
+		end
+
+		-- Raccourcis
+		if SayItOptions.raccourcis_tooltip then
+			GameTooltip:AddLine(" ")
+			if i_phrase <= max_phrase then
+				GameTooltip:AddDoubleLine("Dire la phrase","Clic gauche",1,1,1,1,1,1)
+			end
+			if i_phrase>1 then
+				GameTooltip:AddDoubleLine("Phrase précédente","Ctrl+Clic/Roulette haut",1,1,1,1,1,1)
+			end
+			if i_phrase <= max_phrase then
+				GameTooltip:AddDoubleLine("Sauter la phrase","Shift+Clic/Roulette bas",1,1,1,1,1,1)
+			end
+		end
+		GameTooltip:Show()
+	else
+		GameTooltip:SetText("")
+		GameTooltip:Hide()
+	end
+end
+
+--
+-- Créations des boutons, avec les fonctions des clics/mouseover
+--
+local function CreerBouton(parent)
+	local button = CreateFrame("Button", parent:GetName().."SayButton", parent, "UIPanelButtonTemplate")
+	button:SetText("Dire")
+	button:SetHeight(22)
+	button:SetWidth(button:GetTextWidth() + 40)
+	button:SetPoint("BOTTOM",parent,"BOTTOM",-9,72)
+
+	-- Set the frame level of the gossip_button to be 1 deeper than its parent
+	local buttonparent = button:GetParent()
+	local framelevel = buttonparent:GetFrameLevel()
+	local framestrata = buttonparent:GetFrameStrata()
+	button:SetFrameLevel(framelevel + 1)
+	button:SetFrameStrata(framestrata)
+	button:Enable()
+
+	-- Action du bouton
+	button:RegisterForClicks("LeftButtonUp")
+	button:EnableMouseWheel(true)
+	button:SetScript("OnClick",function(self, button, down)
+				-- état des modificateurs
+				local shiftDown = IsShiftKeyDown();
+				local ctrlDown  = IsControlKeyDown();
+
+				-- On évite le cas foireux
+				if shiftDown and ctrlDown then return end
+
+				-- lecture phrase actuelle
+				if not shiftDown and not ctrlDown and i_phrase<=max_phrase then
+					NpcDit(text_table[i_phrase])
+				end
+
+				-- Passage phrase suivante
+				if ctrlDown then
+					if i_phrase==1 then
+						Warn("Le début du texte est atteint.")
+					else
+						i_phrase = i_phrase-1
+						--char_dits = char_dits - text_table[i_phrase].texte:len()
+						if TextFrame and SayItOptions.colorisation == 3 then
+							TextFrame:SetText(ColorieTexte(text_full))
+						end
+					end
+				else
+					if i_phrase>max_phrase then
+						Warn("La fin du texte est atteinte.")
+					else
+						--char_dits = char_dits + text_table[i_phrase].texte:len()
+						i_phrase = i_phrase+1
+						if TextFrame and SayItOptions.colorisation == 3 then
+							TextFrame:SetText(ColorieTexte(text_full))
+						end
+					end
+				end
+
+				-- Mise à jour du texte du tooltip
+				TooltipUpdate(self)
+			end)
+	button:SetScript("OnMouseWheel", function(self, delta)
+				-- Passage phrase suivante
+				if delta==1 then
+					if i_phrase==1 then
+						Warn("Le début du texte est atteint.")
+					else
+						i_phrase = i_phrase-1
+						--char_dits = char_dits - text_table[i_phrase].texte:len()
+						if TextFrame and SayItOptions.colorisation == 3 then
+							TextFrame:SetText(ColorieTexte(text_full))
+						end
+					end
+				else
+					if i_phrase>max_phrase then
+						Warn("La fin du texte est atteinte.")
+					else
+						--char_dits = char_dits + text_table[i_phrase].texte:len()
+						i_phrase = i_phrase+1
+						if TextFrame and SayItOptions.colorisation == 3 then
+							TextFrame:SetText(ColorieTexte(text_full))
+						end
+					end
+				end
+
+				-- Mise à jour du texte du tooltip
+				TooltipUpdate(self)
+			end)
+
+
+	-- Tooltip
+	button:SetScript("OnEnter", TooltipUpdate)
+	button:SetScript("OnLeave", function()
+			GameTooltip:Hide()
+			if TextFrame and SayItOptions.colorisation == 2 then
+				TextFrame:SetText(text_full)
+			end
+		end)
+
+	return button
+end
+
+
+--********************************************************
+--
+-- Gestion des events
+--
+--********************************************************
+--
+-- fonction lancée au chargement de l'add-on
+--
+function _G.SayIt_OnLoad(self,...)
+	-- Création des deux boutons
+	gossip_button = CreerBouton(GossipFrame)
+	quest_button = CreerBouton(QuestFrame)
+
+	-- Pour ne pas avoir de warning avec findglobals
+	-- GLOBALS: this
+	-- Events à suivre
+	SayItFrame:RegisterEvent("GOSSIP_SHOW");    -- Affiche fenêtre Gossip
+	SayItFrame:RegisterEvent("GOSSIP_CLOSED");  -- Ferme fenêtre gossip (peut-être appelé juste avant l'ouverture d'une quête)
+	SayItFrame:RegisterEvent("QUEST_DETAIL");   -- Nouvelle quête
+	SayItFrame:RegisterEvent("QUEST_PROGRESS"); -- Quête en cours, non terminée
+	SayItFrame:RegisterEvent("QUEST_COMPLETE"); -- Quête en cours et terminée
+	SayItFrame:RegisterEvent("QUEST_FINISHED"); -- Fermeture fenêtre quête
+	--"QUEST_GREETING" ?
+end
+
+--
+-- fonction appelée quand il y a un event
+--
+function _G.SayIt_OnEvent(self, event, ...)
+	--DEBUG("Event:"..event)
+	--Warn(event)
+
+	if ( event=="GOSSIP_CLOSED" or event=="QUEST_FINISHED") then
+		-- Reset
+		target_name = ""
+		text_full = nil
+		current_button = nil
+		TextFrame = nil
+
+	elseif event=="GOSSIP_SHOW" then
+		target_name = GetUnitName("Npc")
+		text_full = GetGossipText()
+		current_button = gossip_button
+		TextFrame = GossipGreetingText
+
+	elseif event=="QUEST_DETAIL" then
+		target_name = GetUnitName("Npc")
+		text_full = GetQuestText();
+		current_button = quest_button
+		TextFrame = nil
+
+	elseif event=="QUEST_PROGRESS" then
+		target_name = GetUnitName("Npc")
+		text_full = GetProgressText();
+		current_button = quest_button
+		TextFrame = QuestProgressText
+		
+	elseif event=="QUEST_COMPLETE" then
+		target_name = GetUnitName("Npc")
+		text_full = GetRewardText();
+		current_button = quest_button
+		TextFrame = nil
+
+	--elseif event=="QUEST_GREETING" then
+	-- GetGreetingText()
+	--GreetingText
+	else return
+	end
+
+	-- On ne sait jamais (ça arrive quand la fenêtre ne s'ouvre pas parce que celle des options est ouverte, par exemple)
+	if not target_name or not text_full or not current_button then
+		return
+	end
+
+	-- Reset de l'indice
+	i_phrase = 1
+	--char_dits = 0
+
+	-- Découpage du texte en paragraphes/phrase
+	text_table, max_phrase = Paragraphes(text_full)
+
+	-- Affichage en couleur
+	if TextFrame and SayItOptions.colorisation == 3 then
+		TextFrame:SetText(ColorieTexte(text_full))
+	end
+end
+
+
+--********************************************************
+--
+-- Ace 3.0
+--
+--********************************************************
+-- http://www.wowace.com/addons/ace3/pages/getting-started/
+
+-- Enregistrement comme add-on
+local SayIt = LibStub("AceAddon-3.0"):NewAddon("SayIt")
+--
+-- Ace Config
+--
+local function Hex2Val(h)
+	if not h then return 0,0,0 end
+	return tonumber(h:sub(5,6),16)/255, tonumber(h:sub(7,8),16)/255, tonumber(h:sub(9,10),16)/255
+end
+local function Val2Hex(r,g,b)
+	return string_format("|cff%02x%02x%02x",(r or 0)*255,(g or 0)*255,(b or 0)*255)
+end
+local options = {
+	type = "group",
+	args = {
+		tooltip_header = {
+			name = "Tooltip",
+			type = "header",
+			order = 80
+		},
+		activer_tooltip = {
+			name = "Afficher le tooltip",
+			desc = "Affiche un tooltip pour le bouton \"Dire\"",
+			type = "toggle",
+			get = function() return SayItOptions.tooltip end,
+			set = function(info,state) SayItOptions.tooltip = state end,
+			width = "full",
+			order = 81
+		},
+		montrer_texte = {
+			name = "Afficher le texte dans le tooltip",
+			desc = "Affiche le texte qui va être dit pas le pnj dans le tooltip du bouton \"Dire\"",
+			type = "toggle",
+			get = function() return SayItOptions.texte_tooltip end,
+			set = function(info,state) SayItOptions.texte_tooltip = state end,
+			width = "full",
+			order = 82
+		},
+		montrer_raccourcis = {
+			name = "Afficher les raccourcis dans le tooltip",
+			desc = "Affiche les raccourcis dans le tooltip du bouton \"Dire\"",
+			type = "toggle",
+			get = function() return SayItOptions.raccourcis_tooltip end,
+			set = function(info,state) SayItOptions.raccourcis_tooltip = state end,
+			width = "full",
+			order = 83
+		},
+		ancre_tooltip = {
+			name = "Ancrer le tooltip au bouton",
+			desc = "Ancre le tooltip au bouton \"Dire\". Sinon, il sera dans sa position par défaut.",
+			type = "toggle",
+			get = function() return SayItOptions.ancre_tooltip end,
+			set = function(info,state) SayItOptions.ancre_tooltip = state end,
+			width = "full",
+			order = 84
+		},
+		couleur_header = {
+			name = "Couleurs des textes",
+			type = "header",
+			order = 99
+		},
+		o100 = {
+			name = "|cffffd100Remarque :|r La colorisation ne marche pas pour les fenêtres d'acceptation et de rendu de quête.\n",
+			type = "description",
+			order = 100
+		},
+		colorier = {
+			name = "Colorisation",
+			desc = "Colore le texte dans la fenêtre du pnj.",
+			--descStyle = 'inline',
+			type = "select",
+			values = {
+				"Aucune",
+				"Sous la souris",
+				"Toujours"
+			},
+			style = 'radio',
+			get = function() return SayItOptions.colorisation end,
+			set = function(info,val) SayItOptions.colorisation = val end,
+			order = 101
+		},
+		o102 = {
+			name = "\n|cffffd100Couleurs utilisées lors de la colorisation des textes|r",
+			type = "description",
+			order = 102
+		},
+		couleur_cDit = {
+			name = "Texte déjà dit",
+			desc = "Couleur dans laquelle apparaitra le texte que le pnj a déjà dit.",
+			type = "color",
+			get = function() return Hex2Val(SayItOptions.cDit) end,
+			set = function(info,r,g,b) SayItOptions.cDit = Val2Hex(r,g,b) end,
+			width = "full",
+			order = 103
+		},
+		couleur_cJusteDit = {
+			name = "Texte tout juste dit",
+			desc = "Couleur dans laquelle apparaitra le texte que le pnj vient de dire.",
+			type = "color",
+			get = function() return Hex2Val(SayItOptions.cJusteDit) end,
+			set = function(info,r,g,b) SayItOptions.cJusteDit = Val2Hex(r,g,b) end,
+			width = "full",
+			order = 104
+		},
+		couleur_cADire = {
+			name = "Texte qui va être dit",
+			desc = "Couleur dans laquelle apparaitra le texte que le pnj dira la prochaine fois.",
+			type = "color",
+			get = function() return Hex2Val(SayItOptions.cADire) end,
+			set = function(info,r,g,b) SayItOptions.cADire = Val2Hex(r,g,b) end,
+			width = "full",
+			order = 105
+		},
+		couleur_cNonDit = {
+			name = "Texte pas encore dit",
+			desc = "Couleur dans laquelle apparaitra le texte que le pnj n'a pas encore dit.",
+			type = "color",
+			get = function() return Hex2Val(SayItOptions.cNonDit) end,
+			set = function(info,r,g,b) SayItOptions.cNonDit = Val2Hex(r,g,b) end,
+			width = "full",
+			order = 106
+		}
+	}
+}
+
+function SayIt:OnInitialize()
+	-- Code that you want to run when the addon is first loaded goes here.
+
+	-- Application de la config par Ace
+	LibStub("AceConfig-3.0"):RegisterOptionsTable("SayIt".."BlizzOptions", options, {"sayit"})
+	LibStub("AceConfigDialog-3.0"):AddToBlizOptions("SayIt".."BlizzOptions","Say It")
+	LibStub("AceConfig-3.0"):RegisterOptionsTable("SayIt", function() return self:GetOptions() end) -- tiré de adibags
+
+	-- Récupération de la config...
+	if not SayItOptions then
+		SayItOptions = {}
+	end
+	if SayItOptions.tooltip==nil then
+		SayItOptions.tooltip = true
+	end
+	if SayItOptions.texte_tooltip==nil then
+		SayItOptions.texte_tooltip = true
+	end
+	if SayItOptions.raccourcis_tooltip==nil then
+		SayItOptions.raccourcis_tooltip = true
+	end
+	if SayItOptions.ancre_tooltip==nil then
+		SayItOptions.ancre_tooltip = true
+	end
+	if not SayItOptions.colorisation then
+		SayItOptions.colorisation = 2
+	end
+	if not SayItOptions.cDit then
+		SayItOptions.cDit = "|cff".."606060"
+	end
+	if not SayItOptions.cJusteDit then
+		SayItOptions.cJusteDit = "|cff".."7f0000"
+	end
+	if not SayItOptions.cADire then
+		SayItOptions.cADire = "|cff".."00007f"
+	end
+	if not SayItOptions.cNonDit then
+		SayItOptions.cNonDit = "|cff".."202020"
+	end
+end
+
+--function SayIt:OnEnable()
+	-- Called when the addon is enabled
+--end
+
+--function SayIt:OnDisable()
+	-- Called when the addon is disabled
+--end
+