You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
412 lines
13 KiB
412 lines
13 KiB
|
3 years ago
|
|
||
|
|
-- module independent variables --
|
||
|
|
----------------------------------
|
||
|
|
local addon, ns = ...
|
||
|
|
local C, L, I = ns.LC.color, ns.L, ns.I
|
||
|
|
|
||
|
|
|
||
|
|
-- module own local variables and local cached functions --
|
||
|
|
-----------------------------------------------------------
|
||
|
|
local name = "Volume" -- VOLUME L["ModDesc-Volume"]
|
||
|
|
local ttName,ttColumns,tt,module,createTooltip = name.."TT",2;
|
||
|
|
local updateBrokerButton,getSoundHardware,setSoundHardware
|
||
|
|
local icon = "Interface\\AddOns\\"..addon.."\\media\\volume_"
|
||
|
|
local VIDEO_VOLUME_TITLE = L["Video Volume"];
|
||
|
|
local volume,cvars,updateBroker,vol = {},{};
|
||
|
|
local GetCVar,SetCVar = GetCVar or C_CVar.GetCVar, SetCVar or C_CVar.SetCVar;
|
||
|
|
|
||
|
|
if not ENABLE_DSP_EFFECTS then
|
||
|
|
if LOCALE_deDE then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Todesritterstimmen"
|
||
|
|
elseif LOCALE_esES or LOCALE_esMX then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Voces caballeros de la M."
|
||
|
|
elseif LOCALE_frFR then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Voix ch. de la mort"
|
||
|
|
elseif LOCALE_itIT then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Voci Cavalieri della Morte"
|
||
|
|
elseif LOCALE_koKR then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "죽음의 기사 음성"
|
||
|
|
elseif LOCALE_ptBR or LOCALE_ptPT then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Vozes de CdM"
|
||
|
|
elseif LOCALE_ruRU then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Голоса рыцарей смерти"
|
||
|
|
elseif LOCALE_zhCN then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "死亡骑士语音"
|
||
|
|
elseif LOCALE_zhTW then
|
||
|
|
L.ENABLE_DSP_EFFECTS = "死亡騎士語音"
|
||
|
|
else
|
||
|
|
L.ENABLE_DSP_EFFECTS = "Death Knight Voices"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- register icon names and default files --
|
||
|
|
-------------------------------------------
|
||
|
|
I[name..'_0'] = {iconfile=icon.."0"} --IconName::Volume_0--
|
||
|
|
I[name..'_33'] = {iconfile=icon.."33"} --IconName::Volume_33--
|
||
|
|
I[name..'_66'] = {iconfile=icon.."66"} --IconName::Volume_66--
|
||
|
|
I[name..'_100'] = {iconfile=icon.."100"} --IconName::Volume_100--
|
||
|
|
|
||
|
|
|
||
|
|
-- some local functions --
|
||
|
|
--------------------------
|
||
|
|
function updateBroker()
|
||
|
|
volume.master = tonumber(("%.2f"):format(GetCVar("Sound_MasterVolume") or 0))
|
||
|
|
local obj = ns.LDB:GetDataObjectByName(module.ldbName);
|
||
|
|
local suffix,color = "100","green"
|
||
|
|
if volume.master < .1 then
|
||
|
|
suffix,color = "0","gray"
|
||
|
|
elseif volume.master < .3 then
|
||
|
|
suffix = "33"
|
||
|
|
elseif volume.master < .6 then
|
||
|
|
suffix = "66"
|
||
|
|
end
|
||
|
|
|
||
|
|
obj.iconCoords = {0,1,0,1};
|
||
|
|
obj.icon = "interface\\common\\VOICECHAT-MUTED";
|
||
|
|
if GetCVar("Sound_EnableAllSound")=="1" then
|
||
|
|
if volume.master>0 then
|
||
|
|
local icon = I(name.."_"..(suffix or "100"));
|
||
|
|
obj.iconCoords = icon.coords or {0,1,0,1};
|
||
|
|
obj.icon = icon.iconfile;
|
||
|
|
end
|
||
|
|
obj.text = ceil(volume.master*100).."%";
|
||
|
|
else
|
||
|
|
obj.text = C("gray",ceil(volume.master*100).."%");
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
do
|
||
|
|
local cvar = "Sound_OutputDriverIndex"
|
||
|
|
local hardware = {
|
||
|
|
selected = tonumber(GetCVar(cvar))+1,
|
||
|
|
list = {}
|
||
|
|
}
|
||
|
|
local hardware_selected = nil
|
||
|
|
|
||
|
|
function getSoundHardware()
|
||
|
|
if #hardware.list==0 then
|
||
|
|
local num = Sound_GameSystem_GetNumOutputDrivers()
|
||
|
|
for index=1, num do
|
||
|
|
hardware.list[index] = Sound_GameSystem_GetOutputDriverNameByIndex(index-1)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
return hardware.list, hardware.num, hardware.selected
|
||
|
|
end
|
||
|
|
|
||
|
|
function setSoundHardware(self,hardwareIndex,button)
|
||
|
|
if InCombatLockdown() then
|
||
|
|
ns:print("("..VOLUME..")",C("orange",L["Sorry, In combat lockdown."]));
|
||
|
|
else
|
||
|
|
hardware.selected = hardwareIndex;
|
||
|
|
SetCVar(cvar,tostring(hardwareIndex-1) or 0);
|
||
|
|
Sound_GameSystem_RestartSoundSystem();
|
||
|
|
createTooltip(tt,true);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function updateTooltip()
|
||
|
|
createTooltip(tt, true);
|
||
|
|
end
|
||
|
|
|
||
|
|
local function toggleEntry(self, info, button)
|
||
|
|
ns.SetCVar(info.toggle,tostring(info.inv),info.toggle);
|
||
|
|
updateBroker();
|
||
|
|
createTooltip(tt,true);
|
||
|
|
end
|
||
|
|
|
||
|
|
local function percent(self,cvar,now,direction)
|
||
|
|
if not (cvar and now) then return end
|
||
|
|
if (direction==-1 and now==0) or (direction==1 and now==1) then return end
|
||
|
|
local new = now + ((direction * ns.profile[name].steps) / 100);
|
||
|
|
new = (new>1 and 1) or (new<0 and 0) or new;
|
||
|
|
ns.SetCVar(cvar,new,cvar);
|
||
|
|
createTooltip(tt,true);
|
||
|
|
updateBroker();
|
||
|
|
end
|
||
|
|
|
||
|
|
local function volumeWheel(self,direction)
|
||
|
|
percent(self,self.info.percent,self.info.pnow,direction);
|
||
|
|
end
|
||
|
|
|
||
|
|
local function volumeClick(self,data,button)
|
||
|
|
percent(self,data.percent,data.pnow,button=="RightButton" and -1 or 1);
|
||
|
|
end
|
||
|
|
|
||
|
|
function createTooltip(tt, update)
|
||
|
|
if not (tt and tt.key and tt.key==ttName) then return end -- don't override other LibQTip tooltips...
|
||
|
|
if tt.lines~=nil then tt:Clear(); end
|
||
|
|
|
||
|
|
local wheels,l,c={};
|
||
|
|
|
||
|
|
tt:AddHeader(C("dkyellow",VOLUME))
|
||
|
|
tt:AddSeparator()
|
||
|
|
|
||
|
|
for i,v in ipairs(vol) do
|
||
|
|
local color,disabled
|
||
|
|
|
||
|
|
local label = _G[v.locale];
|
||
|
|
if not label then
|
||
|
|
label = L[v.locale];
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.hide) or not label then
|
||
|
|
-- do nothing
|
||
|
|
elseif type(v.toggle)=="string" then
|
||
|
|
l,c = tt:AddLine();
|
||
|
|
v.now = tonumber(GetCVar(v.toggle)); vol[i].now=v.now;
|
||
|
|
v.inv = v.now==1 and 0 or 1;
|
||
|
|
if (v.toggle~="no-toggle") then
|
||
|
|
if v.depend~=nil and ( (v.depend[1]~=nil and vol[v.depend[1]].now==0) or (v.depend[2]~=nil and vol[v.depend[2]].now==0) ) then
|
||
|
|
color = v.now==1 and "gray" or "dkgray";
|
||
|
|
disabled = color;
|
||
|
|
end
|
||
|
|
if color==nil then
|
||
|
|
color = v.now==1 and "green" or "red";
|
||
|
|
disabled = v.now==1 and "white" or "gray";
|
||
|
|
end
|
||
|
|
tt:SetLineScript(l,"OnMouseUp",toggleEntry,v);
|
||
|
|
else
|
||
|
|
if v.depend~=nil and ( (v.depend[1]~=nil and vol[v.depend[1]].now==0) or (v.depend[2]~=nil and vol[v.depend[2]].now==0) ) then
|
||
|
|
color = "gray";
|
||
|
|
disabled = color;
|
||
|
|
else
|
||
|
|
color = "dkyellow"
|
||
|
|
disabled = "white";
|
||
|
|
end
|
||
|
|
tt:SetLineScript(l,"OnMouseUp",updateTooltip);
|
||
|
|
end
|
||
|
|
|
||
|
|
tt:SetCell(l,1,strrep(" ",3 * v.inset)..C(color,label));
|
||
|
|
|
||
|
|
if v.percent~=nil then
|
||
|
|
v.pnow = tonumber(("%.2f"):format(GetCVar(v.percent) or 0));
|
||
|
|
|
||
|
|
tt.lines[l].info = v;
|
||
|
|
tt.lines[l]:EnableMouseWheel(1)
|
||
|
|
tt.lines[l]:SetScript("OnMouseWheel",volumeWheel);
|
||
|
|
tinsert(wheels,l);
|
||
|
|
|
||
|
|
tt:SetCell(l,ttColumns,C(disabled,ceil(v.pnow*100).."%"));
|
||
|
|
|
||
|
|
tt:SetCellScript(l,ttColumns,"OnMouseUp",volumeClick,v);
|
||
|
|
else
|
||
|
|
tt:SetCell(l,ttColumns," ");
|
||
|
|
end
|
||
|
|
elseif (v.special=="hardware") and (ns.profile[name].listHardware) then
|
||
|
|
tt:AddSeparator(3,0,0,0,0);
|
||
|
|
tt:AddHeader(C("dkyellow",label)..(InCombatLockdown() and C("orange"," (disabled in combat)") or ""));
|
||
|
|
tt:AddSeparator();
|
||
|
|
|
||
|
|
local lst,num,sel = getSoundHardware();
|
||
|
|
|
||
|
|
for I,V in ipairs(lst) do
|
||
|
|
local color = I==sel and "green" or "ltgray";
|
||
|
|
|
||
|
|
local m = 30
|
||
|
|
if strlen(V)>m then
|
||
|
|
V = strsub(V,0,m-3).."...";
|
||
|
|
end
|
||
|
|
|
||
|
|
l,c = tt:AddLine(strrep(" ",3 * (v.inset+1))..C(color,V).." ")
|
||
|
|
|
||
|
|
if not InCombatLockdown() then
|
||
|
|
tt:SetLineScript(l,"OnMouseUp",setSoundHardware,I);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
elseif (v.special=="video") then
|
||
|
|
tt:AddSeparator(3,0,0,0,0);
|
||
|
|
tt:AddHeader(C("dkyellow",VIDEO_VOLUME_TITLE));
|
||
|
|
tt:AddSeparator();
|
||
|
|
-- master volumes
|
||
|
|
tt:AddLine(" ".._G["MASTER_VOLUME"], "0%");
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if ns.profile.GeneralOptions.showHints then
|
||
|
|
tt:AddSeparator(5,0,0,0,0)
|
||
|
|
tt:AddLine(C("ltblue",L["MouseBtn"]).. " || "..C("green",L["On/Off"]));
|
||
|
|
tt:AddLine(C("ltblue",L["Mousewheel"]).. " || "..C("green",L["Louder"].."/"..L["Quieter"]));
|
||
|
|
ns.ClickOpts.ttAddHints(tt,name);
|
||
|
|
end
|
||
|
|
|
||
|
|
if not update then
|
||
|
|
ns.roundupTooltip(tt);
|
||
|
|
tt.OnHide = function(self)
|
||
|
|
if type(wheels)=="table" then
|
||
|
|
for i=1, #wheels do
|
||
|
|
if self.lines[wheels[i]] and self.lines[wheels[i]].EnableMouseWheel then
|
||
|
|
self.lines[wheels[i]]:EnableMouseWheel(false);
|
||
|
|
self.lines[wheels[i]]:SetScript("OnMouseWheel",nil);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function SetCVarHook(cvar)
|
||
|
|
if cvars[cvar:lower()] then
|
||
|
|
updateBroker();
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
-- module variables for registration --
|
||
|
|
---------------------------------------
|
||
|
|
module = {
|
||
|
|
icon_suffix = "_100",
|
||
|
|
events = {
|
||
|
|
"PLAYER_LOGIN",
|
||
|
|
"CVAR_UPDATE",
|
||
|
|
"SOUND_DEVICE_UPDATE"
|
||
|
|
},
|
||
|
|
config_defaults = {
|
||
|
|
enabled = true,
|
||
|
|
useWheel = false,
|
||
|
|
steps = 10,
|
||
|
|
listHardware = true
|
||
|
|
},
|
||
|
|
clickOptionsRename = {
|
||
|
|
["mute"] = "0_mute",
|
||
|
|
["louder"] = "1_louder",
|
||
|
|
["quieter"] = "2_quieter",
|
||
|
|
["menu"] = "3_open_menu"
|
||
|
|
},
|
||
|
|
clickOptions = {
|
||
|
|
["mute"] = {"Mute game sound","module","mute"}, -- L["Mute game sound"]
|
||
|
|
["louder"] = {"Louder","module","volumeAdjust"}, -- L["Louder"]
|
||
|
|
["quieter"] = {"Quieter","module","volumeAdjust"}, -- L["Quieter"]
|
||
|
|
["menu"] = "OptionMenu"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
ns.ClickOpts.addDefaults(module,{
|
||
|
|
mute = "_LEFT",
|
||
|
|
louder = "__NONE",
|
||
|
|
quieter = "__NONE",
|
||
|
|
menu = "_RIGHT"
|
||
|
|
});
|
||
|
|
|
||
|
|
function module.volumeAdjust(self,button,modName,action)
|
||
|
|
local cap,new = volume.master,0;
|
||
|
|
if action=="louder" then
|
||
|
|
cap,new = 1,volume.master + (ns.profile[name].steps / 100);
|
||
|
|
if new > cap then new=1; end
|
||
|
|
elseif action=="quieter" then
|
||
|
|
cap,new = 0,volume.master-(ns.profile[name].steps / 100);
|
||
|
|
if new < cap then new=0; end
|
||
|
|
end
|
||
|
|
if volume.master==cap then return; end
|
||
|
|
volume.master = new;
|
||
|
|
SetCVar("Sound_MasterVolume",tostring(volume.master));
|
||
|
|
updateBroker();
|
||
|
|
createTooltip(tt,true);
|
||
|
|
end
|
||
|
|
|
||
|
|
function module.mute()
|
||
|
|
SetCVar("Sound_EnableAllSound",GetCVar("Sound_EnableAllSound")=="0" and "1" or "0");
|
||
|
|
updateBroker();
|
||
|
|
createTooltip(tt,true);
|
||
|
|
end
|
||
|
|
|
||
|
|
function module.options()
|
||
|
|
return {
|
||
|
|
broker = nil,
|
||
|
|
tooltip = {
|
||
|
|
listHardware={ type="toggle", name=L["List of hardware"], desc=L["Display in tooltip a list of your sound output hardware."] },
|
||
|
|
},
|
||
|
|
misc = {
|
||
|
|
useWheel={ type="toggle", name=L["Use MouseWheel"], desc=L["Use the MouseWheel to change the volume"] },
|
||
|
|
steps={ type="range", name=L["Change steps"], desc=L["Change the stepping width for volume changes with mousewheel and clicks."], min=1, max=100, step=1 },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
function module.init()
|
||
|
|
vol = {
|
||
|
|
{inset=0,locale="MASTER_VOLUME", toggle="Sound_EnableAllSound", percent="Sound_MasterVolume"},
|
||
|
|
{inset=1,locale="ENABLE_SOUNDFX", toggle="Sound_EnableSFX", depend={1}, percent="Sound_SFXVolume"},
|
||
|
|
{inset=2,locale="ENABLE_ERROR_SPEECH", toggle="Sound_EnableErrorSpeech", depend={1,2} },
|
||
|
|
{inset=2,locale="ENABLE_EMOTE_SOUNDS", toggle="Sound_EnableEmoteSounds", depend={1,2} },
|
||
|
|
{inset=2,locale="ENABLE_PET_SOUNDS", toggle="Sound_EnablePetSounds", depend={1,2} },
|
||
|
|
{inset=1,locale="MUSIC_VOLUME", toggle="Sound_EnableMusic", depend={1}, percent="Sound_MusicVolume"},
|
||
|
|
{inset=2,locale="ENABLE_MUSIC_LOOPING", toggle="Sound_ZoneMusicNoDelay", depend={1,6} },
|
||
|
|
{inset=2,locale="ENABLE_PET_BATTLE_MUSIC", toggle="Sound_EnablePetBattleMusic", depend={1,6} },
|
||
|
|
{inset=1,locale="ENABLE_AMBIENCE", toggle="Sound_EnableAmbience", depend={1}, percent="Sound_AmbienceVolume"},
|
||
|
|
{inset=1,locale="DIALOG_VOLUME", toggle="Sound_EnableDialog", depend={1}, percent="Sound_DialogVolume", hide=(select(4,GetBuildInfo())<60000)},
|
||
|
|
{inset=1,locale="ENABLE_BGSOUND", toggle="Sound_EnableSoundWhenGameIsInBG", depend={1} },
|
||
|
|
{inset=1,locale="ENABLE_SOUND_AT_CHARACTER",toggle="Sound_ListenerAtCharacter", depend={1} },
|
||
|
|
{inset=1,locale="ENABLE_REVERB", toggle="Sound_EnableReverb", depend={1} },
|
||
|
|
{inset=1,locale="ENABLE_SOFTWARE_HRTF", toggle="Sound_EnablePositionalLowPassFilter", depend={1} },
|
||
|
|
{inset=1,locale="ENABLE_DSP_EFFECTS", toggle="Sound_EnableDSPEffects", depend={1} },
|
||
|
|
--{inset=0,locale="VIDEO_VOLUME_TITLE", toggle=false, special="video"},
|
||
|
|
{inset=0,locale="HARDWARE", toggle=false, special="hardware"},
|
||
|
|
}
|
||
|
|
for i=1,#vol do
|
||
|
|
if vol[i].locale then
|
||
|
|
cvars[vol[i].locale:lower()]=true;
|
||
|
|
end
|
||
|
|
if vol[i].toggle then
|
||
|
|
cvars[vol[i].toggle:lower()]=true;
|
||
|
|
end
|
||
|
|
if vol[i].percent then
|
||
|
|
cvars[vol[i].percent:lower()]=true;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function module.onevent(self,event,arg1)
|
||
|
|
if event=="BE_UPDATE_CFG" and arg1 and arg1:find("^ClickOpt") then
|
||
|
|
ns.ClickOpts.update(name);
|
||
|
|
elseif event=="BE_UPDATE_CFG" or event=="PLAYER_LOGIN" or event=="SOUND_DEVICE_UPDATE" or (event=="CVAR_UPDATE" and cvars[arg1:lower()]) then
|
||
|
|
if not self.hooked then
|
||
|
|
hooksecurefunc("SetCVar",SetCVarHook);
|
||
|
|
self.hooked = true;
|
||
|
|
end
|
||
|
|
updateBroker();
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- function module.optionspanel(panel) end
|
||
|
|
|
||
|
|
function module.onmousewheel(self,direction)
|
||
|
|
if not ns.profile[name].useWheel then return end
|
||
|
|
if (direction==-1 and volume.master == 0) or (direction==1 and volume.master == 1) then return end
|
||
|
|
|
||
|
|
volume.master = volume.master + (direction * ns.profile[name].steps / 100)
|
||
|
|
if volume.master > 1 then
|
||
|
|
volume.master = 1
|
||
|
|
elseif volume.master < 0 then
|
||
|
|
volume.master = 0
|
||
|
|
end
|
||
|
|
local cvar = "Sound_MasterVolume"
|
||
|
|
ns.SetCVar(cvar,volume.master,cvar)
|
||
|
|
updateBroker();
|
||
|
|
if tt and tt.key==ttName and tt:IsShown() then
|
||
|
|
createTooltip(tt,true);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function module.onenter(self)
|
||
|
|
if (ns.tooltipChkOnShowModifier(false)) then return; end
|
||
|
|
|
||
|
|
if not self.mousewheelOn then
|
||
|
|
self:EnableMouseWheel(1);
|
||
|
|
self.mousewheelOn = true;
|
||
|
|
end
|
||
|
|
|
||
|
|
tt = ns.acquireTooltip({ttName, 2, "LEFT", "RIGHT"},{false},{self})
|
||
|
|
ns.RegisterMouseWheel(self,module.onmousewheel)
|
||
|
|
createTooltip(tt);
|
||
|
|
end
|
||
|
|
|
||
|
|
-- function module.onleave(self) end
|
||
|
|
-- function module.onclick(self,button) end
|
||
|
|
-- function module.ondblclick(self,button) end
|
||
|
|
|
||
|
|
|
||
|
|
-- final module registration --
|
||
|
|
-------------------------------
|
||
|
|
ns.modules[name] = module;
|