WoWInterface SVN LanguageCycle

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tags
    from Rev 1 to Rev 3
    Reverse comparison

Rev 1 → Rev 3

v5.1.0-Release/Bindings.xml New file
0,0 → 1,5
<Bindings>
<Binding name="Cycle Language" header="LANGUAGECYCLE">
Language_Cycle_Cycle();
</Binding>
</Bindings>
\ No newline at end of file
v5.1.0-Release/embeds.xml New file
0,0 → 1,13
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
 
<!--@no-lib-strip@-->
 
<Script file="Libs\LibStub\LibStub.lua"/>
<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
<Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
<Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua"/>
 
<!--@end-no-lib-strip@-->
 
</Ui>
\ No newline at end of file
v5.1.0-Release/media/LanguageCycleIcon.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
v5.1.0-Release/LanguageCycle.xml New file
0,0 → 1,147
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LanguageCycle.lua"/>
 
<Frame name="Language_Cycle_Panel" parent="UIParent" enableMouse="true" toplevel="true" movable="true" frameStrata="HIGH">
<Size>
<AbsDimension x="151" y="56"/>
</Size>
<Anchors>
<Anchor point="TOP" relativePoint="TOP">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad function="Language_Cycle_OnLoad" />
<OnEvent function="Language_Cycle_OnEvent" />
<OnUpdate function="Language_Cycle_OnUpdate" />
<OnDragStart>
self:StartMoving();
</OnDragStart>
<OnDragStop>
self:StopMovingOrSizing();
ValidateFramePosition(this);
</OnDragStop>
<OnEnter function="Language_Cycle_Backdrop_Show" />
<OnLeave function="Language_Cycle_Backdrop_Hide" />
</Scripts>
<Frames>
<Frame name="Language_Cycle_Panel_Backdrop" parent="Language_Cycle_Panel" visible="false">
<Backdrop name="$parentBackdrop" bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="16"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Size>
<AbsDimension x="151" y="56"/>
</Size>
<Anchors>
<Anchor point="TOP" relativePoint="TOP">
</Anchor>
</Anchors>
<Frames>
<Button name="Language_Cycle_CloseButton" parent="Language_Cycle_Panel_Backdrop">
<Size>
<AbsDimension x="34" y="34"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="3" y="3"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnEnter function="Language_Cycle_Backdrop_Show" />
<OnLeave function="Language_Cycle_Backdrop_Hide" />
<OnClick>
PlaySound("igMainMenuOptionCheckBoxOff");
Language_Cycle_Panel_Visible();
</OnClick>
</Scripts>
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
</Button>
<CheckButton name="Language_Cycle_Party_Toggle" inherits="UICheckButtonTemplate">
<Size>
<AbsDimension x="28" y="28"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-4" y="3"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnEnter function="Language_Cycle_Backdrop_Show" />
<OnLeave function="Language_Cycle_Backdrop_Hide" />
<OnClick>
if ( self:GetChecked() ) then
PlaySound("igMainMenuOptionCheckBoxOff");
else
PlaySound("igMainMenuOptionCheckBoxOn");
end
Language_Cycle_Toggle_Group();
</OnClick>
</Scripts>
</CheckButton>
</Frames>
<Layers>
<Layer level="OVERLAY">
<FontString name="Language_Cycle_Party_Toggle_Text" inherits="GameFontNormalSmall" text="Speak Common in Party/Guild chat:">
<Size>
<AbsDimension x="110" y="42"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="0" y="-15"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
<!-- Button for Language Cycling -->
<Button name="Language_Cycle_Button" inherits="UIPanelButtonTemplate" enableMouse="true" visible="true" text="Loading...">
<Size>
<AbsDimension x="125" y="21"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="3" y="-3"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
self:RegisterForClicks("LeftButtonDown", "RightButtonDown")
</OnLoad>
<OnClick>
if (IsAltKeyDown()) then
Language_Cycle_Clear();
PlaySound("igMainMenuOptionCheckBoxOff");
else
Language_Cycle_Language_Clicked(button);
PlaySound("igMainMenuOptionCheckBoxOn");
end
</OnClick>
<OnEnter function="Language_Cycle_Backdrop_Show" />
<OnLeave function="Language_Cycle_Backdrop_Hide" />
</Scripts>
</Button>
</Frames>
</Frame>
</Ui>
\ No newline at end of file
v5.1.0-Release/LanguageCycle.lua New file
0,0 → 1,468
-- Language cycle script
-- Version 5.0.4.a
 
local ButtonTexture = "Interface\\Addons\\LanguageCycle\\media\\LanguageCycleIcon"
local addonName = "LanguageCycle"
 
BINDING_HEADER_LANGUAGECYCLE="Language Cycle";
 
local defaults = {
saved_language = {};
translate_group = true;
panel_visible = true;
panel_locked = false;
minimapIcon = {
hide = false,
minimapPos = 220,
radius = 80,
}
}
if not LANGUAGE_CYCLE then
LANGUAGE_CYCLE = defaults
else
for k, v in pairs(defaults) do
if LANGUAGE_CYCLE[k] == nil or type(LANGUAGE_CYCLE[k]) ~= type(v) then
LANGUAGE_CYCLE[k] = v
end
end
end
 
LC_default_language = "";
LC_verbose = true;
LC_unknown = "Unknown Entity";
LC_realm_name = "";
LC_player_name = "";
LC_player_id = nil;
LC_panel_height = 0;
LC_panel_width = 0;
LC_version = "4.2.2, by Halya, Argent Dawn, EU";
LC_Help_Text={};
LC_Help_Text[0]="Language Cycle will respond to the following commands:";
LC_Help_Text[1]="- /lc : Toggles spoken language between racial/common";
LC_Help_Text[2]="- /lc status : Displays current settings";
LC_Help_Text[3]="- /lc toggle : Toggles Guild/Party translation on/off";
LC_Help_Text[4]="- /lc help : Displays this message";
LC_Help_Text[5]="- /lc show : Display the language cycle button";
LC_Help_Text[6]="- /lc hide : Hide the language cycle button";
LC_Help_Text[7]="- /lc MM : Toggle the language cycle mini-map button";
LC_Help_Text[8]="--------------------------------------------------------------";
 
--Save Blizzard's original SendText function
local LC_Blizzard_SendChatMessage;
 
local LCButtonFrameObject = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject(addonName, {
type = "data source",
text = LANGUAGE_CYCLE.minimapIcon.text,
icon = ButtonTexture,
OnClick = function(frame, button)
GameTooltip:Hide()
if button =="LeftButton" then
Language_Cycle_Cycle();
elseif button =="MiddleButton" then
local t = 0;
while LC_Help_Text[t] ~= nil do
DEFAULT_CHAT_FRAME:AddMessage(LC_Help_Text[t],0.0, 1.0, 0.0);
t = t + 1;
end
elseif button == "RightButton" then
Language_Cycle_Panel_Visible();
end
end,
OnTooltipShow = function(tooltip)
if tooltip and tooltip.AddLine then
tooltip:SetText("LanguageCycle")
tooltip:AddLine("Left-Click: Cycle Language|nRight-Click: Show/Hide Built-in Panel|nMiddle-Click: Show Help",.8,.8,.8,1)
tooltip:Show()
end
end,
})
 
function Language_Cycle_OnLoad( self )
-- Hook SendChatMessage
LC_Blizzard_SendChatMessage = SendChatMessage;
SendChatMessage = LC_SendChatMessage;
 
SlashCmdList["LANGUAGECYCLE"] = Language_Cycle_Slash;
SLASH_LANGUAGECYCLE1 = "/lc";
ShowUIPanel(Language_Cycle_Panel);
if ( not Language_Cycle_Panel:IsVisible() ) then
Language_Cycle_Panel:SetOwner(UIParent, "ANCHOR_PRESERVE");
end
 
Language_Cycle_Panel_Backdrop:SetBackdropBorderColor(1,1,1);
Language_Cycle_Panel_Backdrop:SetBackdropColor(0.3, 0.3, 0.3);
Language_Cycle_Backdrop_Hide();
LC_panel_height = Language_Cycle_Panel:GetHeight();
LC_panel_width = Language_Cycle_Panel:GetWidth();
Language_Cycle_Party_Toggle_Text:SetJustifyH("Right");
Language_Cycle_Add_Message("LanguageCycle loaded; Type '/lc help' for a list of options; Version " .. LC_version);
 
-- self:SetPadding(16);
self:RegisterForDrag("LeftButton");
self:RegisterEvent("VARIABLES_LOADED");
self:RegisterEvent("PLAYER_ENTERING_WORLD");
 
end
 
function Language_Cycle_Get_Version()
return LC_version
end
 
-- replace Blizzard's SendChatMessage function instead. -Nhani
function LC_SendChatMessage(msg, chatType, language, channel)
 
if (LC_player_id ~= nil) then
language = LANGUAGE_CYCLE.saved_language[LC_player_id];
end
 
-- Small change here. Instead of defining what channels we WANT
-- in a common language, we define what channels we DON'T want.
-- Since those are far fewer in number. -Nhani
if (LANGUAGE_CYCLE.translate_group) then
if (chatType ~= "SAY" and chatType ~= "YELL") then
if (language ~= LC_default_language) then
language = LC_default_language;
end
end
end
local numLanguages = GetNumLanguages();
local i;
for i = 1, numLanguages, 1 do
local getlanguage, getlanguageID = GetLanguageByIndex(i);
if (language == getlanguage) then
languageID = getlanguageID;
end
end
 
LC_Blizzard_SendChatMessage(msg, chatType, languageID, channel);
 
end
 
 
function Language_Cycle_Panel_Visible()
if (Language_Cycle_Panel:IsVisible() ) then
HideUIPanel(Language_Cycle_Panel);
LANGUAGE_CYCLE.panel_visible = false;
else
ShowUIPanel(Language_Cycle_Panel);
LANGUAGE_CYCLE.panel_visible = true;
end
end
 
 
function Language_Cycle_Backdrop_Show(override)
if (LANGUAGE_CYCLE.panel_locked and not override) then
else
Language_Cycle_Panel_Backdrop:Show();
end
end
 
 
function Language_Cycle_Backdrop_Hide(override)
if (LANGUAGE_CYCLE.panel_locked and not override) then
else
Language_Cycle_Panel_Backdrop:Hide();
end
end
 
 
function Language_Cycle_Cycle()
local numLangs = GetNumLanguages();
local currentlang = 0;
local lang;
lang = Language_Cycle_Get_Lang();
 
for i=1,numLangs,1 do
if (lang == GetLanguageByIndex(i)) then
currentlang = i;
end
end
if (currentlang == numLangs) then
currentlang = 1;
else
currentlang = currentlang + 1;
end
Language_Cycle_Set_Lang(GetLanguageByIndex(currentlang));
-- if (IsAddOnLoaded("Titan")) then
-- TitanPanelButton_UpdateButton(TITAN_LANGUAGECYCLE_ID);
-- end
-- if (IsAddOnLoaded("FuBar")) then
-- LanguageCycleFuBar:UpdateText()
-- end
-- For debugging
-- Langauge_Cycle_Debug_Message();
end
 
function Language_Cycle_Language_Clicked(button)
 
if (button == "LeftButton") then
LC_verbose = false;
Language_Cycle_Cycle();
LC_verbose = true;
end
if (button == "RightButton") then
LANGUAGE_CYCLE.panel_locked = not LANGUAGE_CYCLE.panel_locked;
Langauge_Cycle_Lock_Backdrop();
end
end
 
 
function Langauge_Cycle_Lock_Backdrop()
if (LANGUAGE_CYCLE.panel_locked) then
Language_Cycle_Backdrop_Hide(true);
Language_Cycle_Panel:SetHeight(Language_Cycle_Button:GetHeight());
Language_Cycle_Panel:SetWidth(Language_Cycle_Button:GetWidth());
else
Language_Cycle_Backdrop_Show(true);
Language_Cycle_Panel:SetHeight(LC_panel_height);
Language_Cycle_Panel:SetWidth(LC_panel_width);
end
end
 
 
function Language_Cycle_Variables_Loaded()
--Called when variables_loaded event fires, usually on UI reload
if (LANGUAGE_CYCLE.panel_visible) then
ShowUIPanel(Language_Cycle_Panel);
else
HideUIPanel(Language_Cycle_Panel);
end
Langauge_Cycle_Lock_Backdrop();
-- For debugging
-- Language_Cycle_Debug_Message();
-- Language_Cycle_Add_Message("Onload done");
end
 
function Language_Cycle_OnEvent( self, event, ... )
 
if (event == "VARIABLES_LOADED") then
Language_Cycle_Variables_Loaded();
-- Add LanguageCycle to myAddOns addons list
if(myAddOnsFrame) then
myAddOnsList.LanguageCycle = {
name = "LanguageCycle",
description = "A button to change your spoken language",
version = Language_Cycle_Get_Version(),
category = MYADDONS_CATEGORY_CHAT,
frame = "Language_Cycle_Panel"};
end
----------------------------------------------------------------------------------------
-- LDB Button Creation
----------------------------------------------------------------------------------------
 
 
 
local defaults = {
minimapIcon = {
hide = false,
minimapPos = 220,
radius = 80,
text = lang,
}
}
if not LANGUAGE_CYCLE then
LANGUAGE_CYCLE = defaults
else
for k, v in pairs(defaults) do
if LANGUAGE_CYCLE[k] == nil or type(LANGUAGE_CYCLE[k]) ~= type(v) then
LANGUAGE_CYCLE[k] = v
end
end
end
 
 
LibStub("LibDBIcon-1.0"):Register(addonName, LCButtonFrameObject, LANGUAGE_CYCLE.minimapIcon)
 
end
if (event == "PLAYER_ENTERING_WORLD") then
Language_Cycle_Init();
end
end
 
 
 
function Language_Cycle_Init()
--Called when the Player_Entering_World event fires, usually on character login.
-- May be called later, if initialization fails
LC_realm_name = string.gsub(GetCVar("realmName"),"'","");
LC_player_name = UnitName("player");
LC_default_language = GetDefaultLanguage();
LC_verbose = false;
Language_Cycle_Backdrop_Hide(true);
Language_Cycle_Set_Text_Color();
local lang;
 
if (LC_player_name == nil or LC_player_name == LC_unknown or LC_realm_name == nil) then
else
LC_player_id = LC_realm_name .. " " .. LC_player_name;
end
 
lang = Language_Cycle_Get_Lang();
 
if (lang == nil) then
else
Language_Cycle_Set_Lang(lang)
end
 
if (LC_default_language == nil) then
else
Language_Cycle_Party_Toggle_Text:SetText("Speak " .. LC_default_language .. " in Party/Guild chat:");
end
 
Language_Cycle_Set_Party_Checkbutton();
 
LC_verbose = true;
-- For debugging
-- Language_Cycle_Debug_Message();
-- Language_Cycle_Add_Message("Entering World Done");
end
 
 
function Language_Cycle_OnUpdate( self, elapsed )
if (not LC_player_id) then
Language_Cycle_Init();
end
end
 
 
function Language_Cycle_Set_Lang(lang)
-- Updates the button text, chat window and returns a chat window message
Language_Cycle_Button:SetText(lang);
DEFAULT_CHAT_FRAME.editBox.language = lang;
LANGUAGE_CYCLE.minimapIcon.text = lang;
LCButtonFrameObject.text = lang
 
if (LC_verbose) then
Language_Cycle_Add_Message(string.format("Now speaking %s", lang));
end
 
Language_Cycle_Save_Lang(lang);
end
 
 
function Language_Cycle_Save_Lang(lang)
if (LC_player_id == nil) then
else
LANGUAGE_CYCLE.saved_language[LC_player_id] = lang;
end
end
 
 
function Language_Cycle_Get_Lang()
local lang, langID;
if (LC_player_id == nil) then
else
lang = DEFAULT_CHAT_FRAME.editBox.language;
if (LANGUAGE_CYCLE.saved_language[LC_player_id] == nil) then
if (lang == nil) then
lang = LC_default_language;
end
else
lang = LANGUAGE_CYCLE.saved_language[LC_player_id];
end
end
return lang
end
 
 
function Language_Cycle_Debug_Message()
local lang;
lang = LANGUAGE_CYCLE.saved_language[LC_player_id];
if (lang == nil) then
lang = "unknown";
end
if not(LC_player_name == nil) then
message(LC_player_name .. " speaks " .. lang);
else
message("LC_player_name is nil");
end
end
 
 
function Language_Cycle_Toggle_Group(verbose)
if (LANGUAGE_CYCLE.translate_group) then
LANGUAGE_CYCLE.translate_group = false;
if (verbose) then
Language_Cycle_Add_Message("Guild/Party translation is now off.");
end
else
LANGUAGE_CYCLE.translate_group = true;
if (verbose) then
Language_Cycle_Add_Message("Guild/Party translation is now on.");
end
end
Language_Cycle_Set_Text_Color();
Language_Cycle_Set_Party_Checkbutton();
-- if (IsAddOnLoaded("Titan")) then
-- TitanPanelButton_UpdateButton(TITAN_LANGUAGECYCLE_ID);
-- end
-- if (IsAddOnLoaded("FuBar")) then
-- LanguageCycleFuBar:UpdateText()
-- end
end
 
 
function Language_Cycle_Set_Party_Checkbutton()
if (LANGUAGE_CYCLE.translate_group) then
Language_Cycle_Party_Toggle:SetChecked(1);
else
Language_Cycle_Party_Toggle:SetChecked(0);
end
end
 
 
function Language_Cycle_Set_Text_Color()
if (LANGUAGE_CYCLE.translate_group) then
Language_Cycle_Button:GetNormalFontObject():SetTextColor(1, 1, 1);
else
Language_Cycle_Button:GetNormalFontObject():SetTextColor(.5, 1, .5);
end
end
 
function Language_Cycle_Slash(arg)
if (arg == "" or arg == nil) then
Language_Cycle_Cycle();
elseif (arg == "ver" or arg == "version") then
Language_Cycle_Add_Message("LanguageCycle version: " .. LC_version);
elseif (arg == "clear") then
Language_Cycle_Clear();
elseif (arg == "stat" or arg == "status") then
local msg = "Speaking: " .. LANGUAGE_CYCLE.saved_language[LC_player_id] .. "; Guild/Party translation is ";
if (LANGUAGE_CYCLE.translate_group) then
msg = msg .. "on.";
else
msg = msg .. "off.";
end
Language_Cycle_Add_Message(msg);
elseif (arg == "party" or arg == "guild" or arg == "group" or arg =="toggle") then
Language_Cycle_Toggle_Group(true);
elseif (arg == "show" or arg == "hide") then
Language_Cycle_Panel_Visible();
elseif (arg == "mm" or arg == "MM") then
if (LANGUAGE_CYCLE.minimapIcon.hide == false) then
LibStub("LibDBIcon-1.0"):Hide("LanguageCycle")
LANGUAGE_CYCLE.minimapIcon.hide = true
else
LibStub("LibDBIcon-1.0"):Show("LanguageCycle")
LANGUAGE_CYCLE.minimapIcon.hide = false
end
elseif (arg == "help") then
local t = 0;
while LC_Help_Text[t] ~= nil do
DEFAULT_CHAT_FRAME:AddMessage(LC_Help_Text[t],0.0, 1.0, 0.0);
t = t + 1;
end
end
end
 
function Language_Cycle_Clear()
LANGUAGE_CYCLE.saved_language[LC_player_id] = nil;
LANGUAGE_CYCLE.translate_group = true;
Language_Cycle_Add_Message(string.format("Cleared language for %s", LC_player_name));
Language_Cycle_Button:SetText("Pref Cleared...");
Language_Cycle_Set_Text_Color();
end
 
function Language_Cycle_Add_Message(msg)
DEFAULT_CHAT_FRAME:AddMessage(msg,0.0,1.0,0.0);
end
\ No newline at end of file
v5.1.0-Release/LanguageCycle.toc New file
0,0 → 1,12
## Interface: 50200
## Title: LanguageCycle
## Version: 5.0.4.a
## Description: Adds key binding and slash commands for selecting a character's current language.
## Notes: Adds key binding and slash commands for selecting a character's current language. Now with LDB support!
## Author: Halya of Argent Dawn EU.
## X-OriginalAuthor: aghokala@gmail.com.
## X-UpdatesBy: Nhani of Earthen Ring EU.
## X-Maintainers: Halya of Argent Dawn EU, Aenott of Earthen Ring EU.
## SavedVariables: LANGUAGE_CYCLE
 
LanguageCycle.xml
v5.1.0-Release/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua New file
0,0 → 1,344
--[[
Name: DBIcon-1.0
Revision: $Rev: 25 $
Author(s): Rabbit (rabbit.magtheridon@gmail.com)
Description: Allows addons to register to recieve a lightweight minimap icon as an alternative to more heavy LDB displays.
Dependencies: LibStub
License: GPL v2 or later.
]]
 
--[[
Copyright (C) 2008-2011 Rabbit
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
]]
 
-----------------------------------------------------------------------
-- DBIcon-1.0
--
-- Disclaimer: Most of this code was ripped from Barrel but fixed, streamlined
-- and cleaned up a lot so that it no longer sucks.
--
 
local DBICON10 = "LibDBIcon-1.0"
local DBICON10_MINOR = tonumber(("$Rev: 25 $"):match("(%d+)"))
if not LibStub then error(DBICON10 .. " requires LibStub.") end
local ldb = LibStub("LibDataBroker-1.1", true)
if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
if not lib then return end
 
lib.disabled = lib.disabled or nil
lib.objects = lib.objects or {}
lib.callbackRegistered = lib.callbackRegistered or nil
lib.notCreated = lib.notCreated or {}
 
function lib:IconCallback(event, name, key, value, dataobj)
if lib.objects[name] then
if key == "icon" then
lib.objects[name].icon:SetTexture(value)
elseif key == "iconCoords" then
lib.objects[name].icon:UpdateCoord()
end
end
end
if not lib.callbackRegistered then
ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
lib.callbackRegistered = true
end
 
-- Tooltip code ripped from StatBlockCore by Funkydude
local function getAnchors(frame)
local x, y = frame:GetCenter()
if not x or not y then return "CENTER" end
local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
end
 
local function onEnter(self)
if self.isMoving then return end
local obj = self.dataObject
if obj.OnTooltipShow then
GameTooltip:SetOwner(self, "ANCHOR_NONE")
GameTooltip:SetPoint(getAnchors(self))
obj.OnTooltipShow(GameTooltip)
GameTooltip:Show()
elseif obj.OnEnter then
obj.OnEnter(self)
end
end
 
local function onLeave(self)
local obj = self.dataObject
GameTooltip:Hide()
if obj.OnLeave then obj.OnLeave(self) end
end
 
--------------------------------------------------------------------------------
 
local onClick, onMouseUp, onMouseDown, onDragStart, onDragEnd, updatePosition
 
do
local minimapShapes = {
["ROUND"] = {true, true, true, true},
["SQUARE"] = {false, false, false, false},
["CORNER-TOPLEFT"] = {false, false, false, true},
["CORNER-TOPRIGHT"] = {false, false, true, false},
["CORNER-BOTTOMLEFT"] = {false, true, false, false},
["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
["SIDE-LEFT"] = {false, true, false, true},
["SIDE-RIGHT"] = {true, false, true, false},
["SIDE-TOP"] = {false, false, true, true},
["SIDE-BOTTOM"] = {true, true, false, false},
["TRICORNER-TOPLEFT"] = {false, true, true, true},
["TRICORNER-TOPRIGHT"] = {true, false, true, true},
["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
}
 
function updatePosition(button)
local angle = math.rad(button.db and button.db.minimapPos or button.minimapPos or 225)
local x, y, q = math.cos(angle), math.sin(angle), 1
if x < 0 then q = q + 1 end
if y > 0 then q = q + 2 end
local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
local quadTable = minimapShapes[minimapShape]
if quadTable[q] then
x, y = x*80, y*80
else
local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
x = math.max(-80, math.min(x*diagRadius, 80))
y = math.max(-80, math.min(y*diagRadius, 80))
end
button:SetPoint("CENTER", Minimap, "CENTER", x, y)
end
end
 
function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end
function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end
 
do
local function onUpdate(self)
local mx, my = Minimap:GetCenter()
local px, py = GetCursorPosition()
local scale = Minimap:GetEffectiveScale()
px, py = px / scale, py / scale
if self.db then
self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
else
self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
end
updatePosition(self)
end
 
function onDragStart(self)
self:LockHighlight()
self.isMouseDown = true
self.icon:UpdateCoord()
self:SetScript("OnUpdate", onUpdate)
self.isMoving = true
GameTooltip:Hide()
end
end
 
function onDragStop(self)
self:SetScript("OnUpdate", nil)
self.isMouseDown = false
self.icon:UpdateCoord()
self:UnlockHighlight()
self.isMoving = nil
end
 
local defaultCoords = {0, 1, 0, 1}
local function updateCoord(self)
local coords = self:GetParent().dataObject.iconCoords or defaultCoords
local deltaX, deltaY = 0, 0
if not self:GetParent().isMouseDown then
deltaX = (coords[2] - coords[1]) * 0.05
deltaY = (coords[4] - coords[3]) * 0.05
end
self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
end
 
local function createButton(name, object, db)
local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
button.dataObject = object
button.db = db
button:SetFrameStrata("MEDIUM")
button:SetWidth(31); button:SetHeight(31)
button:SetFrameLevel(8)
button:RegisterForClicks("anyUp")
button:RegisterForDrag("LeftButton")
button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
local overlay = button:CreateTexture(nil, "OVERLAY")
overlay:SetWidth(53); overlay:SetHeight(53)
overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
overlay:SetPoint("TOPLEFT")
local background = button:CreateTexture(nil, "BACKGROUND")
background:SetWidth(20); background:SetHeight(20)
background:SetTexture("Interface\\Minimap\\UI-Minimap-Background")
background:SetPoint("TOPLEFT", 7, -5)
local icon = button:CreateTexture(nil, "ARTWORK")
icon:SetWidth(17); icon:SetHeight(17)
icon:SetTexture(object.icon)
icon:SetPoint("TOPLEFT", 7, -6)
button.icon = icon
button.isMouseDown = false
 
icon.UpdateCoord = updateCoord
icon:UpdateCoord()
 
button:SetScript("OnEnter", onEnter)
button:SetScript("OnLeave", onLeave)
button:SetScript("OnClick", onClick)
if not db or not db.lock then
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnDragStop", onDragStop)
end
button:SetScript("OnMouseDown", onMouseDown)
button:SetScript("OnMouseUp", onMouseUp)
 
lib.objects[name] = button
 
if lib.loggedIn then
updatePosition(button)
if not db or not db.hide then button:Show()
else button:Hide() end
end
end
 
-- We could use a metatable.__index on lib.objects, but then we'd create
-- the icons when checking things like :IsRegistered, which is not necessary.
local function check(name)
if lib.notCreated[name] then
createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
lib.notCreated[name] = nil
end
end
 
lib.loggedIn = lib.loggedIn or false
-- Wait a bit with the initial positioning to let any GetMinimapShape addons
-- load up.
if not lib.loggedIn then
local f = CreateFrame("Frame")
f:SetScript("OnEvent", function()
for _, object in pairs(lib.objects) do
updatePosition(object)
if not lib.disabled and (not object.db or not object.db.hide) then object:Show()
else object:Hide() end
end
lib.loggedIn = true
f:SetScript("OnEvent", nil)
f = nil
end)
f:RegisterEvent("PLAYER_LOGIN")
end
 
local function getDatabase(name)
return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
end
 
function lib:Register(name, object, db)
if not object.icon then error("Can't register LDB objects without icons set!") end
if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
if not lib.disabled and (not db or not db.hide) then
createButton(name, object, db)
else
lib.notCreated[name] = {object, db}
end
end
 
function lib:Lock(name)
if not lib:IsRegistered(name) then return end
if lib.objects[name] then
lib.objects[name]:SetScript("OnDragStart", nil)
lib.objects[name]:SetScript("OnDragStop", nil)
end
local db = getDatabase(name)
if db then db.lock = true end
end
 
function lib:Unlock(name)
if not lib:IsRegistered(name) then return end
if lib.objects[name] then
lib.objects[name]:SetScript("OnDragStart", onDragStart)
lib.objects[name]:SetScript("OnDragStop", onDragStop)
end
local db = getDatabase(name)
if db then db.lock = nil end
end
 
function lib:Hide(name)
if not lib.objects[name] then return end
lib.objects[name]:Hide()
end
function lib:Show(name)
if lib.disabled then return end
check(name)
lib.objects[name]:Show()
updatePosition(lib.objects[name])
end
function lib:IsRegistered(name)
return (lib.objects[name] or lib.notCreated[name]) and true or false
end
function lib:Refresh(name, db)
if lib.disabled then return end
check(name)
local button = lib.objects[name]
if db then button.db = db end
updatePosition(button)
if not button.db or not button.db.hide then
button:Show()
else
button:Hide()
end
if not button.db or not button.db.lock then
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnDragStop", onDragStop)
else
button:SetScript("OnDragStart", nil)
button:SetScript("OnDragStop", nil)
end
end
function lib:GetMinimapButton(name)
return lib.objects[name]
end
 
function lib:EnableLibrary()
lib.disabled = nil
for name, object in pairs(lib.objects) do
if not object.db or not object.db.hide then
object:Show()
updatePosition(object)
end
end
for name, data in pairs(lib.notCreated) do
if not data.db or not data.db.hide then
createButton(name, data[1], data[2])
lib.notCreated[name] = nil
end
end
end
 
function lib:DisableLibrary()
lib.disabled = true
for name, object in pairs(lib.objects) do
object:Hide()
end
end
 
v5.1.0-Release/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua New file
0,0 → 1,90
 
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
 
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
 
 
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
 
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
 
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
 
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
 
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
 
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
 
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
 
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
 
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return next, attributestorage[dataobj], nil
end
 
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
 
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
 
return ipairs_iter, attributestorage[dataobj], 0
end
end
v5.1.0-Release/Libs/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
v5.1.0-Release/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
\ No newline at end of file
v5.1.0-Release/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,240
--[[ $Id: CallbackHandler-1.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 5
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
 
if not CallbackHandler then return end -- No upgrade needed
 
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
 
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
 
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
 
local method, ARGS
local function call() method(ARGS) end
 
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
 
return dispatch
]]
 
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
 
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
 
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
 
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
 
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
 
 
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
 
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
 
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
 
registry.recurse = oldrecurse
 
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
 
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
 
method = method or eventname
 
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
 
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
 
local regfunc
 
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2)
end
 
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
 
 
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
 
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
 
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
 
 
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
 
return registry
end
 
 
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
 
v5.1.0-Release/readme.txt New file
0,0 → 1,156
LanguageCycle v4.2
 
 
---What this mod does---
 
LanguageCycle provides a quick way for role-players to know what language their character is speaking and easily change that language. It also allows users to speak a non-default language in most channels, but automatically speak in either Common or Orcish (determined by faction) in party, raid and guild chat, preventing the need to constantly switch languages.
 
 
---What this mod DOES NOT do---
 
This is not a translation mod. It will not allow you to speak or understand any languages which your character does not know.
 
 
---Install---
 
Unzip files to the Interface/AddOns/ folder within your main World of Warcraft folder. This should automatically create two new sub-folders. One folder for LanguageCycle and one for TitanLanguageCycle. If you do not use Titan Panel, you do not need the TitanLanguageCycle folder or files, but they do no harm. The Titan LanguageCycle plugin requires both sets of files.
 
 
---Features---
 
LanguageCycle adds a button and a small pop-up panel to the user interface for selecting which language your character will use. The button displays the currently-selected language. When clicked, your selected language will change to the next available language for your character. e.g. Switching from Common to Darnassian for a Night Elf character. Characters who can only speak one language are unaffected (and have no need for this mod!). Cycling through available languages may also be done via a slash command or a key binding.
 
By default, LanguageCycle will automatically send /party, /raid and /guild messages in the character's base faction language (Common or Orcish). e.g. You can be speaking Darnassian in /say, but your messages to /party will be in Common. This option may be turned off either by deselcting the checkbox or using a slash command.
 
Which language has been selected is saved per character. e.g. Setting Troll as the language for one character will have no affect on any other Troll characters you use.
 
The setting of the /party, /raid and /guild language override is saved, but not per character. e.g. If you turn off the checkbox while playing one character, logging in with a different character will maintain the same setting, and the checkbox will be off.
 
 
---UI Mods---
 
In normal usage, a button appears on the screen. Left-clicking on the button cycles through available languages. When moving the mouse near the button, a small pop-up panel appears around the button with two additional options- A checkbox for /party, /raid and /guild chat language and a close button to hide the entire UI.
 
The checkbox is on by default. Checking it off will allow you to speak your current language in all channels. The text on the button displays in a light green color when this box is unchecked and white when checked.
 
Clicking the close button will hide both the button and the pop-up panel. You can get the UI to reappear by using the slash command "/lc show".
 
The UI may be moved anywhere on your screen by dragging on the text in the pop-up panel.
 
If you do not want the pop-up panel to appear, right-click on the button. Right-clicking does NOT cause the language selection to cycle. In this compact state, the UI may not be dragged elsewhere on your screen. To have the pop-up panel appear again, right-click again.
 
The location and visible status of the button is saved per character.
 
 
---Slash Commands---
 
To cycle through your languages manually, use:
/lc
This is the same as left-clicking on the button (or the Titan Panel button).
 
 
To toggle speaking your faction's base language in /party, /raid and /guild chat, use:
/lc party
/lc group
/lc guild
/lc toggle
Any of the above commands will do the same thing. Each is the same as clicking the checkbox in the pop-up panel (or toggling the Titan Panel auto-translate option).
 
 
To hide or show the visual UI, use:
/lc show
/lc hide
Both commands do the same thing. If the button is visible, they are the same as clicking the close box. If the button is not visible, either command will make it reappear.
 
When the UI is hidden, you can find out what LanguageCycle's current settings are with the command:
/lc status
This displays both your current language and the setting of group/party translation.
 
 
---Key Bindings---
 
A key binding is available for cycling through your available languages. When used, the key binding is the same as left-clicking the button or using the /lc command. Look for "Language Cycle" within your key bindings window.
 
 
---Known Issues---
 
This mod overrides the standard UI language selection menu. Selecting languages with the normal WoW UI will do nothing. If you do not wish to use this mod to control your languages, you should remove it from your Interface/AddOns/ folder. Using the Close box or the /lc hide command to remove the button from your screen is NOT sufficient.
 
At this time, there are no other known issues with either the standard WoW UI or any other third-party mods.
 
 
---Version History---
-4.2.2
Minimap icon should now save its position
Added slashcommand to hide the minimap button
LDB libs are now embedded
-4.2
Updated toc version
Added LDB support
-4.0.1
Fixed depreciated code usage and updated toc
-3.2
Updated toc version for 3.2.2. No code changes, mod still fully functional.
-3.1.0
Updated toc version for patch 3.1, mod still fully functional.
 
-3.0.3
Updated toc version and various comments/texts including this file.
 
-3.0.2d
After getting some help the default UI button works again.
 
-3.0.2c
Stripped all non-functional code to make the mod functional for Patch 3.0.2. UI functionality disabled.
 
-2.03 - Apr. 7, 2008:
Fixed an issue where Blizzard had corrected a typoed function call so LanguageCycle can find the proper function again.
 
-2.02 - Dec. 31, 2006:
Integrated the Titan panel plugin into the core (LanguageCycle) mod rather than keeping it a seperate one, for people who are directory concious.
Integrated a new FuBar plugin so LanguageCycle now supports that aswell. Added a few ACE libraries because of this integration.
Removed old additional TitanPanel plugin as it is no longer needed.
 
-2.01 - Dec. 31, 2006:
Added a few other new channels to the auto-translate feature (battlegrounds for one)
Fixed and Readded the Titanpanel plugin as it seems to be working now.
 
-2.00 - Dec. 26, 2006:
Updated for WoW client 2.x.
Changed a few inner works to ensure playing nicely with Blizzard's new protected calls.
Removed the Titanpanel plugin for now until it can be tested with 2.x.
 
-1.1.10900 - Jan. 5, 2006:
Update TOC number to 10900 for WoW client patch 1.9.0
No other changes
 
-1.1.1800 - Oct. 16, 2005:
Update TOC number to 1800 for WoW client patch 1.8.0
Added Guild Officer channel to auto-translate feature.
 
-1.1.1700 - Sept. 13, 2005:
Update TOC number to 1700 for WoW client patch 1.7.0
No other changes
 
-1.1.1600 - July 12, 2005:
Updated TOC number to 1600 for WoW client patch 1.6.0.
No other changes.
 
-1.1.1500 - June 15, 2005:
Added MyAddons support.
Added Titan Panel plugin.
 
-1.0.1 - June 7, 2005:
Updated TOC number to 1500 for WoW client patch 1.5.0.
Added Raid channel to auto-translation.
 
-1.0.0 - April 11, 2005:
First released version.
 
 
---Contact info---
 
Questions and concerns may be sent to:
aghokala@gmail.com
 
---EOF---