WoWInterface SVN NeedToKnow-Updated

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /branches
    from Rev 63 to Rev 78
    Reverse comparison

Rev 63 → Rev 78

Kitjan/NeedToKnow/NeedToKnow/NeedToKnow_Localization.lua New file
0,0 → 1,274
--[[
 
If you want to be super helpful, you can translate this stuff into whatever non-enUS language you happen to know and we'll credit you. Please post the translations as a ticket on CurseForge.com (http://wow.curseforge.com/addons/need-to-know/tickets/) or email them to us (lieandswell@yahoo.com).
 
Thanks a bunch!
 
--]]
 
NEEDTOKNOW = {};
 
-- Define defaults in enUS
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "Right click bars to configure. More options in the Blizzard interface options menu. Type /needtoknow to lock and enable.";
 
NEEDTOKNOW.RESIZE_TOOLTIP = "Click and drag to change size";
 
NEEDTOKNOW.BARMENU_ENABLE = "Enable bar";
NEEDTOKNOW.BARMENU_CHOOSENAME = "Choose buff/debuff to time";
NEEDTOKNOW.CHOOSENAME_DIALOG = "Enter the name of the buff or debuff to time with this bar"
NEEDTOKNOW.CHOOSE_OVERRIDE_TEXT = "Normally, the name of the aura/item/spell that activated the bar is displayed. By entering text here, you can override that text with something else. Leave this blank to use the default behavior."
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "Unit to monitor";
NEEDTOKNOW.BARMENU_PLAYER = "Player";
NEEDTOKNOW.BARMENU_TARGET = "Target";
NEEDTOKNOW.BARMENU_FOCUS = "Focus";
NEEDTOKNOW.BARMENU_PET = "Pet";
NEEDTOKNOW.BARMENU_VEHICLE = "Vehicle";
NEEDTOKNOW.BARMENU_TARGETTARGET = "Target of Target";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "Bar Type";
NEEDTOKNOW.BARMENU_SPELLID = "Use SpellID";
NEEDTOKNOW.BARMENU_HELPFUL = "Buff";
NEEDTOKNOW.BARMENU_HARMFUL = "Debuff";
NEEDTOKNOW.BARMENU_ONLYMINE = "Only show if cast by self";
NEEDTOKNOW.BARMENU_BARCOLOR = "Bar color";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "Clear settings";
 
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "These options allow you to customize NeedToKnow's timer bars.";
-- NEEDTOKNOW.UIPANEL_SUBTEXT2 = "Bars work when locked. When unlocked, you can move/size bar groups and right click individual bars for more settings. You can also type '/needtoknow' or '/ntk' to lock/unlock.";
NEEDTOKNOW.UIPANEL_BARGROUP = "Group ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "Number of bars";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "Max bar duration";
NEEDTOKNOW.UIPANEL_LOCK = "Lock";
NEEDTOKNOW.UIPANEL_UNLOCK = "Unlock";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "Show and enable this group of bars";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "Set the maximum length of bars for this group (in seconds). Leave empty to set dynamically per bar.";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "Choose the texture graphic for timer bars";
NEEDTOKNOW.CMD_RESET = "reset";
 
NEEDTOKNOW.UIPANEL_CONFIGMODE = "Config mode";
NEEDTOKNOW.UIPANEL_CONFIGMODE_TOOLTIP = "Unlock timer bars and make them configurable";
NEEDTOKNOW.UIPANEL_PLAYMODE = "Play mode";
NEEDTOKNOW.UIPANEL_PLAYMODE_TOOLTIP = "Lock and enable timer bars, making them click-through";
 
NEEDTOKNOW.UIPANEL_APPEARANCE = "Appearance";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "Background color";
NEEDTOKNOW.UIPANEL_BARSPACING = "Bar spacing";
NEEDTOKNOW.UIPANEL_BARPADDING = "Bar padding";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "Bar texture";
NEEDTOKNOW.UIPANEL_BARFONT = "Bar font";
NEEDTOKNOW.UIPANEL_FONT = "Font";
 
NEEDTOKNOW.BARMENU_TOTEM = "Totem";
NEEDTOKNOW.BARMENU_CASTCD = "Spell Cooldown";
NEEDTOKNOW.BARMENU_BUFFCD = "Internal Cooldown";
NEEDTOKNOW.BARMENU_USABLE = "Spell Usable";
NEEDTOKNOW.CMD_HIDE = "hide";
NEEDTOKNOW.CMD_SHOW = "show";
NEEDTOKNOW.BARMENU_TIMEFORMAT = "Time Format";
NEEDTOKNOW.FMT_SINGLEUNIT = "Single unit (2 m)";
NEEDTOKNOW.FMT_TWOUNITS = "Minutes and seconds (01:10)";
NEEDTOKNOW.FMT_FLOAT = "Fractional Seconds (70.1)";
NEEDTOKNOW.BARMENU_VISUALCASTTIME = "Visual Cast Time";
NEEDTOKNOW.BARMENU_VCT_ENABLE = "Enable for this bar";
NEEDTOKNOW.BARMENU_VCT_COLOR = "Overlay color";
NEEDTOKNOW.BARMENU_VCT_SPELL = "Choose cast time by spell";
NEEDTOKNOW.BARMENU_VCT_EXTRA = "Set additional time";
NEEDTOKNOW.BARMENU_MAIN_HAND = "Main Hand";
NEEDTOKNOW.BARMENU_OFF_HAND = "Off Hand";
NEEDTOKNOW.CHOOSE_VCT_SPELL_DIALOG = "Enter the name of a spell (in your spellbook) whose cast time will determine the base length of the visual cast time. If left blank, the aura name will be used as the spell name. To force this to be 0, type 0.";
NEEDTOKNOW.CHOOSE_VCT_EXTRA_DIALOG = "Enter an amount of seconds that will be added to the cast time of the spell. Ex: 1.5";
NEEDTOKNOW.CHOOSE_BLINK_TITLE_DIALOG = "Enter the text to display on the bar when it is blinking.";
NEEDTOKNOW.BUFFCD_DURATION_DIALOG = "Enter the cooldown duration triggered by the buffs watched by this bar.";
NEEDTOKNOW.USABLE_DURATION_DIALOG = "Enter the cooldown duration triggered by the abilities watched by this bar.";
 
 
-- replace with translations, if available
if ( GetLocale() == "deDE" ) then
-- by sp00n and Fxfighter EU-Echsenkessel
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "Rechtsklick auf einen Balken für Einstellungen. Mehr Optionen sind im Blizzard Interface vorhanden. Zum Festsetzen und Aktivieren /needtoknow oder /ntk eingeben.";
NEEDTOKNOW.RESIZE_TOOLTIP = "Klicken und ziehen, um die Größe zu ändern";
NEEDTOKNOW.BARMENU_ENABLE = "Leiste aktivieren";
NEEDTOKNOW.BARMENU_CHOOSENAME = "Buff/Debuff auswählen";
NEEDTOKNOW.CHOOSENAME_DIALOG = "Name des Buffs/Debuffs für diesen Balken angeben"
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "Betroffene Einheit";
NEEDTOKNOW.BARMENU_PLAYER = "Spieler";
NEEDTOKNOW.BARMENU_TARGET = "Ziel";
NEEDTOKNOW.BARMENU_FOCUS = "Fokus";
NEEDTOKNOW.BARMENU_PET = "Begleiter (Pet)";
NEEDTOKNOW.BARMENU_VEHICLE = "Vehicle";
NEEDTOKNOW.BARMENU_TARGETTARGET = "Ziel des Ziels";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "Buff oder Debuff?";
NEEDTOKNOW.BARMENU_HELPFUL = "Buff";
NEEDTOKNOW.BARMENU_HARMFUL = "Debuff";
NEEDTOKNOW.BARMENU_ONLYMINE = "Nur Anzeigen wenn es selbst gezaubert wurde";
NEEDTOKNOW.BARMENU_BARCOLOR = "Farbe des Balken";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "Einstellungen löschen";
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "Diese Einstellungen ändern die Anzahl und die Gruppierung der Balken.";
NEEDTOKNOW.UIPANEL_SUBTEXT2 = "Die Darstellung funktioniert auch bei festgesetzen Balken. Wenn sie freigesetzt sind, können die Gruppierungen verschoben und deren Größe verändert werden. Ein Rechtsklick auf einen Balken zeigt weitere Einstellungsmöglichkeiten an. '/needtoknow' oder '/ntk' kann ebenfalls zum Festsetzen und Freistellen verwendet werden.";
NEEDTOKNOW.UIPANEL_BARGROUP = "Gruppe ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "Anzahl der Balken";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "Max bar duration";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "Balkentextur";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "Background color";
NEEDTOKNOW.UIPANEL_BARSPACING = "Bar spacing";
NEEDTOKNOW.UIPANEL_BARPADDING = "Bar padding";
NEEDTOKNOW.UIPANEL_LOCK = "AddOn sperren";
NEEDTOKNOW.UIPANEL_UNLOCK = "AddOn entsperren";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "Diese Gruppierung aktivieren und anzeigen";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "Set the maximum length of bars for this group (in seconds). Leave empty to set dynamically per bar.";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "Die Textur für die Balken auswählen";
NEEDTOKNOW.CMD_RESET = "reset";
 
elseif ( GetLocale() == "koKR" ) then
-- by metalchoir
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "우?�릭: 메뉴 불러오기\n세부옵션? �기본 ?�터페?�스 설정?�서 가능\n/ntk 명령어로 잠근 후? �애드온 사용가능";
NEEDTOKNOW.RESIZE_TOOLTIP = "드래그: ?�기 변경";
NEEDTOKNOW.BARMENU_ENABLE = "바 사용";
NEEDTOKNOW.BARMENU_CHOOSENAME = "입력: 주문 ?�름";
NEEDTOKNOW.CHOOSENAME_DIALOG = "바? �표시할 버프 ?�는 디버프? �?�름? �입력하세요"
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "유닛 선?";
NEEDTOKNOW.BARMENU_PLAYER = "�본?";
NEEDTOKNOW.BARMENU_TARGET = "�대?";
NEEDTOKNOW.BARMENU_FOCUS = "�주시대?";
NEEDTOKNOW.BARMENU_PET = "�펫";
NEEDTOKNOW.BARMENU_VEHICLE = "탈것";
NEEDTOKNOW.BARMENU_TARGETTARGET = "대?�? �대?";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "�선?: �버프/디버프";
NEEDTOKNOW.BARMENU_SPELLID = "사용 주문 ID";
NEEDTOKNOW.BARMENU_HELPFUL = "버프";
NEEDTOKNOW.BARMENU_HARMFUL = "디버프";
NEEDTOKNOW.BARMENU_ONLYMINE = "?�신? �시전한 것만 보여줌";
NEEDTOKNOW.BARMENU_BARCOLOR = "바 색?";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "�설정 초기화";
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "아래? �옵션?�서 타?�머? �그룹과 ? �그룹별 바 갯수를 설정하실 수 있습니다.";
NEEDTOKNOW.UIPANEL_SUBTEXT2 = "바는 잠근 후? �작?�합니다. 풀렸? �때 바? �?�?�과 ?�기 조절, 그리고 ?�?�? �바? �우?�릭? �함으로? �설정? �하실 수 있습니다. '/needtoknow' ?�는 '/ntk' 명령어를 통해서? �잠금/품 전환? �가능합니다.";
NEEDTOKNOW.UIPANEL_BARGROUP = "그룹 ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "바 갯수";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "Max bar duration";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "바 ?�스처";
NEEDTOKNOW.UIPANEL_BARSPACING = "바 간격";
NEEDTOKNOW.UIPANEL_BARPADDING = "배경 ?�기";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "배경 색?";
NEEDTOKNOW.UIPANEL_LOCK = "�잠금";
NEEDTOKNOW.UIPANEL_UNLOCK = "풀림";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "? �그룹? �바를 표시/사용합니다.";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "Set the maximum length of bars for this group (in seconds). Leave empty to set dynamically per bar.";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "바 ?�스처를 선?�하세요";
NEEDTOKNOW.CMD_RESET = "초기화";
 
elseif ( GetLocale() == "ruRU" ) then
-- by Vlakarados
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "Клик правой кнопкой мыши по полосе для настройки. Больше настроек в Интерфейс / Модификации / NeedToKnow меню. Ввести /needtoknow или /ntk для блокировки и включения.";
NEEDTOKNOW.RESIZE_TOOLTIP = "Кликнуть и тащить для изменения размера";
NEEDTOKNOW.BARMENU_ENABLE = "Включить полосу";
NEEDTOKNOW.BARMENU_CHOOSENAME = "Выбрать бафф/дебафф для слежения";
NEEDTOKNOW.CHOOSENAME_DIALOG = "Введите название баффа/дебаффа для слежения"
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "Юнит слежения";
NEEDTOKNOW.BARMENU_PLAYER = "Игрок";
NEEDTOKNOW.BARMENU_TARGET = "Цель";
NEEDTOKNOW.BARMENU_FOCUS = "Фокус";
NEEDTOKNOW.BARMENU_PET = "Питомец";
NEEDTOKNOW.BARMENU_VEHICLE = "Средство передвижения";
NEEDTOKNOW.BARMENU_TARGETTARGET = "Цель цели";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "Бафф или дебафф?";
NEEDTOKNOW.BARMENU_SPELLID = "Используйте удостоверение личности произношения по буквам";
NEEDTOKNOW.BARMENU_HELPFUL = "Бафф";
NEEDTOKNOW.BARMENU_HARMFUL = "Дебафф";
NEEDTOKNOW.BARMENU_ONLYMINE = "Показывать только наложенные мной";
NEEDTOKNOW.BARMENU_BARCOLOR = "Цвет полосы";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "Очистить настройки";
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "Эти настройки позволяют настроить бафф/дебафф полосы слежения.";
NEEDTOKNOW.UIPANEL_SUBTEXT2 = "Полосы работают только когда заблокированы группы. Можно менять размер и перемещать группы полос и кликнуть правой кнопкой мыши для изменения индивидуальных настроек. Ввести '/needtoknow' или '/ntk' to блокировки/разблокировки.";
NEEDTOKNOW.UIPANEL_BARGROUP = "Группа ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "Количество полос";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "Максимальное время на полосе";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "Текcтура полоc";
NEEDTOKNOW.UIPANEL_BARSPACING = "Промежуток полоc";
NEEDTOKNOW.UIPANEL_BARPADDING = "Уплотнение полоc";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "Цвет фона";
NEEDTOKNOW.UIPANEL_LOCK = "Заблокировать";
NEEDTOKNOW.UIPANEL_UNLOCK = "Разблокировать";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "Показать и включить эту группу полос";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "Указать максимальное время пробега полосы в секундах. Оставить пустым для динамического времени для каждой полойы (полное время = длительность баффа/дебаффа).";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "Выбрать текстуру для полос.";
NEEDTOKNOW.CMD_RESET = "Сброс";
 
elseif ( GetLocale() == "zhCN" ) then
-- by wowui.cn
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "右键点击计时条配置. 更多的选项在暴雪界面选项菜单里. 输入 /needtoknow 来锁定并启用.";
NEEDTOKNOW.RESIZE_TOOLTIP = "点击和拖动来修改计时条尺寸";
NEEDTOKNOW.BARMENU_ENABLE = "启用计时条";
NEEDTOKNOW.BARMENU_CHOOSENAME = "选择需要计时的Buff/Debuff";
NEEDTOKNOW.CHOOSENAME_DIALOG = "输入在这个计时条内计时的Buff或Debuff的精确名字"
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "需要监视的单位";
NEEDTOKNOW.BARMENU_PLAYER = "玩家";
NEEDTOKNOW.BARMENU_TARGET = "目标";
NEEDTOKNOW.BARMENU_FOCUS = "焦点";
NEEDTOKNOW.BARMENU_PET = "宠物";
NEEDTOKNOW.BARMENU_VEHICLE = "载具";
NEEDTOKNOW.BARMENU_TARGETTARGET = "目标的目标";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "Buff还是Debuff?";
NEEDTOKNOW.BARMENU_BUFF = "Buff";
NEEDTOKNOW.BARMENU_DEBUFF = "Debuff";
NEEDTOKNOW.BARMENU_ONLYMINE = "仅显示自身施放的";
NEEDTOKNOW.BARMENU_BARCOLOR = "计时条颜色";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "清除设置";
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "这些选项允许你自定义Buff/Debuff计时条.";
NEEDTOKNOW.UIPANEL_SUBTEXT2 = "计时条锁定后才能正常工作. 当解锁时, 你可以移动或修改计时条分组的大小, 右键点击单独的计时条可以进行更多的设置. 你也可以输入 '/needtoknow' 或 '/ntk' 来锁定/解锁.";
NEEDTOKNOW.UIPANEL_BARGROUP = "分组 ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "计时条数量";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "计时条最大持续时间";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "计时条材质";
NEEDTOKNOW.UIPANEL_BARSPACING = "计时条空距";
NEEDTOKNOW.UIPANEL_BARPADDING = "计时条间距";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "背景颜色";
NEEDTOKNOW.UIPANEL_LOCK = "锁定";
NEEDTOKNOW.UIPANEL_UNLOCK = "解锁";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "显示并启用这个分组的计时条";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "设置这个分组计时条的最大长度 (按秒数). 留空为每个计时条设置不同的数值.";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "选择计时条的材质图像.";
NEEDTOKNOW.CMD_RESET = "重置";
 
elseif ( GetLocale() == "zhTW" ) then
-- by wowui.cn
NEEDTOKNOW.BAR_TOOLTIP1 = "NeedToKnow";
NEEDTOKNOW.BAR_TOOLTIP2 = "右鍵點擊計時條配置. 更多的選項在暴雪介面選項菜單裏. 輸入 /needtoknow 來鎖定並啟用.";
NEEDTOKNOW.RESIZE_TOOLTIP = "點擊和拖動來修改計時條尺寸";
NEEDTOKNOW.BARMENU_ENABLE = "啟用計時條";
NEEDTOKNOW.BARMENU_CHOOSENAME = "選擇需要計時的Buff/Debuff";
NEEDTOKNOW.CHOOSENAME_DIALOG = "輸入在這個計時條內計時的Buff或Debuff的精確名字"
NEEDTOKNOW.BARMENU_CHOOSEUNIT = "需要監視的單位";
NEEDTOKNOW.BARMENU_PLAYER = "玩家";
NEEDTOKNOW.BARMENU_TARGET = "目標";
NEEDTOKNOW.BARMENU_FOCUS = "焦點";
NEEDTOKNOW.BARMENU_PET = "寵物";
NEEDTOKNOW.BARMENU_VEHICLE = "載具";
NEEDTOKNOW.BARMENU_TARGETTARGET = "目標的目標";
NEEDTOKNOW.BARMENU_BUFFORDEBUFF = "Buff還是Debuff?";
NEEDTOKNOW.BARMENU_BUFF = "Buff";
NEEDTOKNOW.BARMENU_DEBUFF = "Debuff";
NEEDTOKNOW.BARMENU_ONLYMINE = "僅顯示自身施放的";
NEEDTOKNOW.BARMENU_BARCOLOR = "計時條顏色";
NEEDTOKNOW.BARMENU_CLEARSETTINGS = "清除設置";
NEEDTOKNOW.UIPANEL_SUBTEXT1 = "這些選項允許妳自定義Buff/Debuff計時條.";
NEEDTOKNOW.UIPANEL_SUBTEXT2 = "計時條鎖定後才能正常工作. 當解鎖時, 妳可以移動或修改計時條分組的大小, 右鍵點擊單獨的計時條可以進行更多的設置. 妳也可以輸入 '/needtoknow' 或 '/ntk' 來鎖定/解鎖.";
NEEDTOKNOW.UIPANEL_BARGROUP = "分組 ";
NEEDTOKNOW.UIPANEL_NUMBERBARS = "計時條數量";
NEEDTOKNOW.UIPANEL_FIXEDDURATION = "計時條最大持續時間";
NEEDTOKNOW.UIPANEL_BARTEXTURE = "計時條材質";
NEEDTOKNOW.UIPANEL_BARSPACING = "計時條空距";
NEEDTOKNOW.UIPANEL_BARPADDING = "計時條間距";
NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR = "背景顏色";
NEEDTOKNOW.UIPANEL_LOCK = "鎖定";
NEEDTOKNOW.UIPANEL_UNLOCK = "解鎖";
NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP = "顯示並啟用這個分組的計時條";
NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION = "設置這個分組計時條的最大長度 (按秒數). 留空為每個計時條設置不同的數值.";
NEEDTOKNOW.UIPANEL_TOOLTIP_BARTEXTURE = "選擇計時條的材質圖像.";
NEEDTOKNOW.CMD_RESET = "重置";
 
end
 
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/NeedToKnow_Options.xml New file
0,0 → 1,615
<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">
 
<Frame name="NeedToKnow_GroupOptionsTemplate" virtual="true">
<Size>
<AbsDimension x="128" y="26"/>
</Size>
<Frames>
<CheckButton name="$parentEnableButton" inherits="InterfaceOptionsCheckButtonTemplate">
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" />
</Anchors>
<HitRectInsets>
<AbsInset left="0" right="-70" top="0" bottom="0"/>
</HitRectInsets>
<Scripts>
<OnLoad>
local text = getglobal(self:GetName().."Text");
text:SetText(NEEDTOKNOW.UIPANEL_BARGROUP..self:GetParent():GetID());
</OnLoad>
<OnClick>
NeedToKnow.GroupEnableButton_OnClick(self);
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_TOOLTIP_ENABLEGROUP, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave>
GameTooltip:Hide();
</OnLeave>
</Scripts>
</CheckButton>
<Frame name="$parentNumberbarsWidget">
<Size>
<AbsDimension x="64" y="32"/>
</Size>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent" relativePoint="LEFT">
<Offset>
<AbsDimension x="125" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentText" inherits="GameFontHighlight" justifyH="CENTER" text="X">
<Anchors>
<Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER" />
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="$parentLeftButton">
<Size>
<AbsDimension x="20" y="20"/>
</Size>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="CENTER">
<Offset>
<AbsDimension x="-8" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
NeedToKnow.NumberbarsButton_OnClick(self, -1);
</OnClick>
</Scripts>
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Up"/>
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Down"/>
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled"/>
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
</Button>
<Button name="$parentRightButton">
<Size>
<AbsDimension x="20" y="20"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="CENTER">
<Offset>
<AbsDimension x="8" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
NeedToKnow.NumberbarsButton_OnClick(self, 1);
</OnClick>
</Scripts>
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Up"/>
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Down"/>
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled"/>
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
</Button>
</Frames>
</Frame>
<EditBox name="$parentFixedDurationBox" numeric="true" letters="3" autoFocus="false">
<Size>
<AbsDimension x="30" y="20"/>
</Size>
<Anchors>
<Anchor point="CENTER" relativeTo="$parentNumberbarsWidget" relativePoint="RIGHT">
<Offset>
<AbsDimension x="40" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentLeft" file="Interface\Common\Common-Input-Border">
<Size>
<AbsDimension x="8" y="20"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="-5" y="0"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0" right="0.0625" top="0" bottom="0.625"/>
</Texture>
<Texture name="$parentRight" file="Interface\Common\Common-Input-Border">
<Size>
<AbsDimension x="8" y="20"/>
</Size>
<Anchors>
<Anchor point="RIGHT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0.9375" right="1.0" top="0" bottom="0.625"/>
</Texture>
<Texture name="$parentMiddle" file="Interface\Common\Common-Input-Border">
<Size>
<AbsDimension x="10" y="20"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"/>
<Anchor point="RIGHT" relativeTo="$parentRight" relativePoint="LEFT"/>
</Anchors>
<TexCoords left="0.0625" right="0.9375" top="0" bottom="0.625"/>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_TOOLTIP_FIXEDDURATION, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave>
GameTooltip:Hide();
</OnLeave>
<OnTabPressed>
if ( IsShiftKeyDown() ) then
local prevGroup = max(1, self:GetParent():GetID() - 1);
_G[self:GetParent():GetParent():GetName().."Group"..prevGroup.."FixedDurationBox"]:SetFocus();
else
local nextGroup = min(NEEDTOKNOW.MAXGROUPS, self:GetParent():GetID() + 1);
_G[self:GetParent():GetParent():GetName().."Group"..nextGroup.."FixedDurationBox"]:SetFocus();
end
</OnTabPressed>
<OnEnterPressed>
EditBox_ClearFocus(self);
</OnEnterPressed>
<OnEscapePressed>
EditBox_ClearFocus(self);
</OnEscapePressed>
<OnTextChanged>
NeedToKnow.FixedDurationEditBox_OnTextChanged(self);
</OnTextChanged>
<OnEditFocusLost>
EditBox_ClearHighlight(self);
</OnEditFocusLost>
<OnEditFocusGained>
EditBox_HighlightText(self);
</OnEditFocusGained>
</Scripts>
<FontString inherits="ChatFontNormal"/>
</EditBox>
</Frames>
</Frame>
 
<Button name="NeedToKnow_ColorButtonTemplate" virtual="true">
<Size>
<AbsDimension x="16" y="16"/>
</Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentSwatch">
<Size>
<AbsDimension x="14" y="14"/>
</Size>
<Anchors>
<Anchor point="CENTER">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Color r="1.0" g="1.0" b="1.0"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<FontString name="$parentLabel" inherits="GameFontHighlight" justifyH="LEFT" justifyV="TOP">
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="RIGHT">
<Offset>
<AbsDimension x="8" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<NormalTexture name="$parentNormalTexture" file="Interface\ChatFrame\ChatFrameColorSwatch"/>
</Button>
 
<Frame name="InterfaceOptionsNeedToKnowPanel" hidden="true" parent="InterfaceOptionsFramePanelContainer">
<Layers>
<Layer level="ARTWORK">
<FontString name="$parentTitle" text="NeedToKnow" inherits="GameFontNormalLarge" justifyH="LEFT" justifyV="TOP">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="16" y="-16"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentVersion" inherits="GameFontNormalLarge" justifyH="LEFT" justifyV="TOP">
<Anchors>
<Anchor point="LEFT" relativeTo="$parentTitle" relativePoint="RIGHT">
<Offset>
<AbsDimension x="4" y="-0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentSubText1" inherits="GameFontHighlightSmall" nonspacewrap="true" maxLines="3" justifyH="LEFT" justifyV="TOP">
<Size>
<AbsDimension y="24" x="0"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentTitle" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-8"/>
</Offset>
</Anchor>
<Anchor point="RIGHT">
<Offset>
<AbsDimension x="-24" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentNumberbarsLabel" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="BOTTOM" relativeTo="$parentSubText1" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="133" y="-28"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentFixedDurationLabel" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="BOTTOM" relativeTo="$parentSubText1" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="203" y="-28"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self.name = "NeedToKnow";
self.default = NeedToKnow.Reset;
self.cancel = NeedToKnow.Cancel;
InterfaceOptions_AddCategory(self);
NeedToKnow.UIPanel_OnLoad(self);
</OnLoad>
<OnShow>
NeedToKnow_OldSettings = CopyTable(NeedToKnow_Settings);
NeedToKnow.UIPanel_OnShow();
</OnShow>
</Scripts>
<Frames>
<Frame name="$parentGroup1" inherits="NeedToKnow_GroupOptionsTemplate" id="1">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentSubText1" relativePoint="BOTTOMLEFT">
<Offset x="8" y="-40"/>
</Anchor>
</Anchors>
</Frame>
<Frame name="$parentGroup2" inherits="NeedToKnow_GroupOptionsTemplate" id="2">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentGroup1" relativePoint="BOTTOMLEFT">
<Offset x="0" y="-8"/>
</Anchor>
</Anchors>
</Frame>
<Frame name="$parentGroup3" inherits="NeedToKnow_GroupOptionsTemplate" id="3">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentGroup2" relativePoint="BOTTOMLEFT">
<Offset x="0" y="-8"/>
</Anchor>
</Anchors>
</Frame>
<Frame name="$parentGroup4" inherits="NeedToKnow_GroupOptionsTemplate" id="4">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentGroup3" relativePoint="BOTTOMLEFT">
<Offset x="0" y="-8"/>
</Anchor>
</Anchors>
</Frame>
<Button name="$parentConfigModeButton" inherits="UIPanelButtonTemplate">
<Size>
<AbsDimension x="128" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="24" y="24"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_CONFIGMODE);
</OnLoad>
<OnClick>
PlaySound("gsTitleOptionOK");
NeedToKnow_Settings["Locked"] = false;
NeedToKnow.Update();
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_CONFIGMODE_TOOLTIP, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave function="GameTooltip_Hide"/>
</Scripts>
<NormalFont inherits="GameFontNormalSmall"/>
<HighlightFont inherits="GameFontHighlightSmall"/>
</Button>
<Button name="$parentPlayModeButton" inherits="UIPanelButtonTemplate">
<Size>
<AbsDimension x="128" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-24" y="24"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_PLAYMODE);
</OnLoad>
<OnClick>
PlaySound("gsTitleOptionOK");
NeedToKnow_Settings["Locked"] = true;
NeedToKnow.Update();
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_PLAYMODE_TOOLTIP, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave function="GameTooltip_Hide"/>
</Scripts>
<NormalFont inherits="GameFontNormalSmall"/>
<HighlightFont inherits="GameFontHighlightSmall"/>
</Button>
</Frames>
</Frame>
 
<Frame name="InterfaceOptionsNeedToKnowAppearancePanel" hidden="true" parent="InterfaceOptionsFramePanelContainer">
<Layers>
<Layer level="ARTWORK">
<FontString name="$parentTitle" text="NeedToKnow" inherits="GameFontNormalLarge" justifyH="LEFT" justifyV="TOP">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="16" y="-16"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentVersion" inherits="GameFontNormalLarge" justifyH="LEFT" justifyV="TOP">
<Anchors>
<Anchor point="LEFT" relativeTo="$parentTitle" relativePoint="RIGHT">
<Offset>
<AbsDimension x="4" y="-0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentSubText1" inherits="GameFontHighlightSmall" nonspacewrap="true" maxLines="3" justifyH="LEFT" justifyV="TOP">
<Size>
<AbsDimension y="24" x="0"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentTitle" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-8"/>
</Offset>
</Anchor>
<Anchor point="RIGHT">
<Offset>
<AbsDimension x="-24" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self.name = NEEDTOKNOW.UIPANEL_APPEARANCE;
self.parent = "NeedToKnow";
self.default = NeedToKnow.Reset;
-- self.cancel = NeedToKnow.Cancel;
-- need different way to handle cancel? users might open appearance panel without opening main panel
InterfaceOptions_AddCategory(self);
NeedToKnow.UIPanel_Appearance_OnLoad(self)
</OnLoad>
<OnShow>
NeedToKnow.UIPanel_Appearance_OnShow();
</OnShow>
<OnHide>
</OnHide>
</Scripts>
<Frames>
<Button name="$parentBackgroundColorButton" inherits="NeedToKnow_ColorButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentSubText1" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="16" y="-16"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Label"]:SetText(NEEDTOKNOW.UIPANEL_BACKGROUNDCOLOR);
self:RegisterForClicks("LeftButtonUp");
</OnLoad>
<OnClick>
NeedToKnow.ChooseColor("BkgdColor");
</OnClick>
</Scripts>
</Button>
<Slider name="$parentBarSpacingSlider" inherits="OptionsSliderTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentBackgroundColorButton" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-32"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_BARSPACING);
</OnLoad>
<OnValueChanged>
NeedToKnow_Settings["BarSpacing"] = value;
NeedToKnow.Update();
</OnValueChanged>
</Scripts>
</Slider>
<Slider name="$parentBarPaddingSlider" inherits="OptionsSliderTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentBarSpacingSlider" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-32"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_BARPADDING);
</OnLoad>
<OnValueChanged>
NeedToKnow_Settings["BarPadding"] = value;
NeedToKnow.Update();
</OnValueChanged>
</Scripts>
</Slider>
<Slider name="$parentBarTextureSlider" inherits="OptionsSliderTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentBarSpacingSlider" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="166" y="0" />
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" inherits="GameFontHighlight">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="40" y="-30"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
</OnLoad>
<OnValueChanged>
NeedToKnow.UpdateBarTextureSlider(self, value);
</OnValueChanged>
</Scripts>
</Slider>
 
<Slider name="$parentBarFontSlider" inherits="OptionsSliderTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentBarTextureSlider" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-30" />
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" inherits="GameFontHighlight">
<Anchors>
<Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-4"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
</OnLoad>
<OnValueChanged>
NeedToKnow.UpdateBarFontSlider(self, value);
</OnValueChanged>
</Scripts>
</Slider>
 
<Button name="$parentConfigModeButton" inherits="UIPanelButtonTemplate">
<Size>
<AbsDimension x="128" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="24" y="24"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_CONFIGMODE);
</OnLoad>
<OnClick>
PlaySound("gsTitleOptionOK");
NeedToKnow_Settings["Locked"] = false;
NeedToKnow.Update();
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_CONFIGMODE_TOOLTIP, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave function="GameTooltip_Hide"/>
</Scripts>
<NormalFont inherits="GameFontNormalSmall"/>
<HighlightFont inherits="GameFontHighlightSmall"/>
</Button>
<Button name="$parentPlayModeButton" inherits="UIPanelButtonTemplate">
<Size>
<AbsDimension x="128" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-24" y="24"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
_G[self:GetName().."Text"]:SetText(NEEDTOKNOW.UIPANEL_PLAYMODE);
</OnLoad>
<OnClick>
PlaySound("gsTitleOptionOK");
NeedToKnow_Settings["Locked"] = true;
NeedToKnow.Update();
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetText(NEEDTOKNOW.UIPANEL_PLAYMODE_TOOLTIP, nil, nil, nil, nil, 1);
</OnEnter>
<OnLeave function="GameTooltip_Hide"/>
</Scripts>
<NormalFont inherits="GameFontNormalSmall"/>
<HighlightFont inherits="GameFontHighlightSmall"/>
</Button>
</Frames>
</Frame>
 
</Ui>
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/NeedToKnow_Options.lua New file
0,0 → 1,900
NEEDTOKNOW.MAXBARSPACING = 24;
NEEDTOKNOW.MAXBARPADDING = 12;
 
local LSM = LibStub("LibSharedMedia-3.0", true);
local textureList = LSM:List("statusbar");
local fontList = LSM:List("font");
 
function NeedToKnow.SlashCommand(cmd)
if ( cmd == NEEDTOKNOW.CMD_RESET ) then
NeedToKnow.Reset();
elseif ( cmd == NEEDTOKNOW.CMD_SHOW ) then
NeedToKnow.Show(true);
elseif ( cmd == NEEDTOKNOW.CMD_HIDE ) then
NeedToKnow.Show(false);
else
NeedToKnow.LockToggle();
end
end
 
function NeedToKnow.LockToggle()
if ( NeedToKnow_Settings["Locked"] ) then
NeedToKnow_Settings["Locked"] = false;
else
NeedToKnow_Settings["Locked"] = true;
end
NeedToKnow.Show(true);
PlaySound("UChatScrollButton");
NeedToKnow.last_cast = {};
NeedToKnow.Update();
end
 
 
-- -----------------------------
-- INTERFACE OPTIONS PANEL: MAIN
-- -----------------------------
 
function NeedToKnow.UIPanel_OnLoad(self)
local panelName = self:GetName();
local numberbarsLabel = _G[panelName.."NumberbarsLabel"];
local fixedDurationLabel = _G[panelName.."FixedDurationLabel"];
_G[panelName.."Version"]:SetText(NEEDTOKNOW.VERSION);
_G[panelName.."SubText1"]:SetText(NEEDTOKNOW.UIPANEL_SUBTEXT1);
numberbarsLabel:SetText(NEEDTOKNOW.UIPANEL_NUMBERBARS);
numberbarsLabel:SetWidth(50);
fixedDurationLabel:SetText(NEEDTOKNOW.UIPANEL_FIXEDDURATION);
fixedDurationLabel:SetWidth(50);
end
 
function NeedToKnow.UIPanel_OnShow()
NeedToKnow_OldSettings = CopyTable(NeedToKnow_Settings);
NeedToKnow.UIPanel_Update();
end
 
function NeedToKnow.UIPanel_Update()
local panelName = "InterfaceOptionsNeedToKnowPanel";
if not _G[panelName]:IsVisible() then return end
 
local settings = NeedToKnow_Settings;
 
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
NeedToKnow.GroupEnableButton_Update(groupID);
NeedToKnow.NumberbarsWidget_Update(groupID);
_G[panelName.."Group"..groupID.."FixedDurationBox"]:SetText(settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["FixedDuration"] or "");
end
end
 
function NeedToKnow.GroupEnableButton_Update(groupID)
local button = _G["InterfaceOptionsNeedToKnowPanelGroup"..groupID.."EnableButton"];
button:SetChecked(NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Enabled"]);
end
 
function NeedToKnow.GroupEnableButton_OnClick(self)
local groupID = self:GetParent():GetID();
if ( self:GetChecked() ) then
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Enabled"] = true;
else
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Enabled"] = false;
end
NeedToKnow.Update();
end
 
function NeedToKnow.NumberbarsWidget_Update(groupID)
local widgetName = "InterfaceOptionsNeedToKnowPanelGroup"..groupID.."NumberbarsWidget";
local text = _G[widgetName.."Text"];
local leftButton = _G[widgetName.."LeftButton"];
local rightButton = _G[widgetName.."RightButton"];
local numberBars = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["NumberBars"];
text:SetText(numberBars);
leftButton:Enable();
rightButton:Enable();
if ( numberBars == 1 ) then
leftButton:Disable();
elseif ( numberBars == NEEDTOKNOW.MAXBARS ) then
rightButton:Disable();
end
end
 
function NeedToKnow.NumberbarsButton_OnClick(self, increment)
local groupID = self:GetParent():GetParent():GetID();
local oldNumber = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["NumberBars"];
if ( oldNumber == 1 ) and ( increment < 0 ) then
return;
elseif ( oldNumber == NEEDTOKNOW.MAXBARS ) and ( increment > 0 ) then
return;
end
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["NumberBars"] = oldNumber + increment;
NeedToKnow.Group_Update(groupID);
NeedToKnow.NumberbarsWidget_Update(groupID);
end
 
function NeedToKnow.FixedDurationEditBox_OnTextChanged(self)
local enteredText = self:GetText();
if enteredText == "" then
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][self:GetParent():GetID()]["FixedDuration"] = nil;
else
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][self:GetParent():GetID()]["FixedDuration"] = enteredText;
end
NeedToKnow.Update();
end
 
function NeedToKnow.Reset()
NeedToKnow_Settings = CopyTable(NEEDTOKNOW.DEFAULTS);
NeedToKnow_Settings["Spec"][1]["Groups"][1]["Enabled"] = true;
NeedToKnow_Settings["Spec"][2]["Groups"][1]["Enabled"] = true;
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
local group = _G["NeedToKnow_Group"..groupID];
group:ClearAllPoints();
group:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", 100, -100 - 100*groupID);
end
NeedToKnow.Update();
NeedToKnow.UIPanel_Update();
NeedToKnow.UIPanel_Appearance_Update();
end
 
function NeedToKnow.Cancel()
NeedToKnow_Settings = CopyTable(NeedToKnow_OldSettings);
NeedToKnow.Update();
end
 
 
-- -----------------------------------
-- INTERFACE OPTIONS PANEL: APPEARANCE
-- -----------------------------------
 
function NeedToKnow.UIPanel_Appearance_OnLoad(self)
local panelName = self:GetName();
_G[panelName.."Version"]:SetText(NEEDTOKNOW.VERSION);
_G[panelName.."SubText1"]:SetText(NEEDTOKNOW.UIPANEL_SUBTEXT1);
end
 
function NeedToKnow.UIPanel_Appearance_OnShow()
NeedToKnow.UIPanel_Appearance_Update();
end
 
function NeedToKnow.UIPanel_Appearance_Update()
local panelName = "InterfaceOptionsNeedToKnowAppearancePanel";
if not _G[panelName]:IsVisible() then return end
 
local settings = NeedToKnow_Settings;
local barSpacingSlider = _G[panelName.."BarSpacingSlider"];
local barPaddingSlider = _G[panelName.."BarPaddingSlider"];
 
-- Mimic the behavior of the context menu, and force the alpha to one in the swatch
local r,g,b = unpack(settings.BkgdColor);
_G[panelName.."BackgroundColorButtonNormalTexture"]:SetVertexColor(r,g,b,1);
 
barSpacingSlider:SetMinMaxValues(0, NEEDTOKNOW.MAXBARSPACING);
barSpacingSlider:SetValue(settings.BarSpacing);
barPaddingSlider:SetMinMaxValues(0, NEEDTOKNOW.MAXBARPADDING);
barPaddingSlider:SetValue(settings.BarPadding);
 
NeedToKnow.UpdateBarTextureDropDown(panelName);
NeedToKnow.UpdateBarFontDropDown(panelName);
end
 
 
function NeedToKnow.UpdateBarTextureSlider(info, value)
getglobal(info:GetName().."Label"):SetText(textureList[value]);
NeedToKnow_Settings["BarTexture"] = textureList[value];
NeedToKnow.Update();
end
 
function NeedToKnow.UpdateBarFontSlider(info, value)
local fontName = fontList[value];
local fontPath = LSM:Fetch("font", fontName);
getglobal(info:GetName().."Label"):SetText(fontName);
NeedToKnow_Settings["BarFont"] = fontPath;
NeedToKnow.Update();
NeedToKnow.UIPanel_Appearance_Update();
end
 
 
function NeedToKnow.ChooseColor(variable)
info = UIDropDownMenu_CreateInfo();
info.r, info.g, info.b, info.opacity = unpack(NeedToKnow_Settings[variable]);
info.opacity = 1 - info.opacity;
info.hasOpacity = true;
info.opacityFunc = NeedToKnow.SetOpacity;
info.swatchFunc = NeedToKnow.SetColor;
info.cancelFunc = NeedToKnow.CancelColor;
info.extraInfo = variable;
-- Not sure if I should leave this state around or not. It seems like the
-- correct strata to have it at anyway, so I'm going to leave it there for now
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG");
OpenColorPicker(info);
end
 
function NeedToKnow.SetColor()
local variable = ColorPickerFrame.extraInfo;
local r,g,b = ColorPickerFrame:GetColorRGB();
NeedToKnow_Settings[variable][1] = r;
NeedToKnow_Settings[variable][2] = g;
NeedToKnow_Settings[variable][3] = b;
NeedToKnow.Update();
NeedToKnow.UIPanel_Appearance_Update();
end
 
function NeedToKnow.SetOpacity()
local variable = ColorPickerFrame.extraInfo;
NeedToKnow_Settings[variable][4] = 1 - OpacitySliderFrame:GetValue();
NeedToKnow.Update();
NeedToKnow.UIPanel_Appearance_Update();
end
 
function NeedToKnow.CancelColor(previousValues)
if ( previousValues ) then
local variable = ColorPickerFrame.extraInfo;
NeedToKnow_Settings[variable] = {previousValues.r, previousValues.g, previousValues.b, previousValues.opacity};
NeedToKnow.Update();
NeedToKnow.UIPanel_Appearance_Update();
end
end
 
function NeedToKnow.UpdateBarTextureDropDown(panelName)
local barTextureSlider = _G[panelName.."BarTextureSlider"];
barTextureSlider:SetMinMaxValues(1, #(textureList));
barTextureSlider:SetValueStep(1);
getglobal(panelName.."BarTextureSliderLow"):SetText('');
getglobal(panelName.."BarTextureSliderHigh"):SetText('');
local textureLabel = getglobal(panelName.."BarTextureSliderLabel");
textureLabel:SetText(NeedToKnow_Settings["BarTexture"]);
local fn = textureLabel:GetFont();
textureLabel:SetFont(fn, 10); -- There's got to be some way to say this in the xml
getglobal(panelName.."BarTextureSliderText"):SetText(NEEDTOKNOW.UIPANEL_BARTEXTURE);
for i=1, #(textureList) do
if textureList[i] == NeedToKnow_Settings.BarTexture then
barTextureSlider:SetValue(i);
end
end
end
 
function NeedToKnow.UpdateBarFontDropDown(panelName)
local barFontSlider = _G[panelName.."BarFontSlider"];
barFontSlider:SetMinMaxValues(1, #(fontList));
barFontSlider:SetValueStep(1);
getglobal(panelName.."BarFontSliderLow"):SetText('');
getglobal(panelName.."BarFontSliderHigh"):SetText('');
getglobal(panelName.."BarFontSliderText"):SetText(NEEDTOKNOW.UIPANEL_BARFONT);
 
for i=1, #(fontList) do
if ( LSM:Fetch("font", fontList[i]) == NeedToKnow_Settings.BarFont ) then
barFontSlider:SetValue(i);
local lbl = getglobal(panelName.."BarFontSliderLabel");
lbl:SetText(fontList[i]);
lbl:SetFont(NeedToKnow_Settings.BarFont, 10);
end
end
end
 
-- --------
-- BAR GUI
-- --------
 
NeedToKnow.CurrentBar = { groupID = 1, barID = 1 }; -- a dirty hack, i know.
 
StaticPopupDialogs["NEEDTOKNOW.CHOOSENAME_DIALOG"] = {
text = NEEDTOKNOW.CHOOSENAME_DIALOG,
button1 = ACCEPT,
button2 = CANCEL,
hasEditBox = 1,
maxLetters = 255,
OnAccept = function(self)
local text = self.editBox:GetText();
local variable = self.variable;
if ( nil ~= variable ) then
NeedToKnow.BarMenu_ChooseName(text, variable);
end
end,
EditBoxOnEnterPressed = function(self)
local text = self:GetParent().editBox:GetText();
local variable = self:GetParent().variable;
if ( nil ~= variable ) then
NeedToKnow.BarMenu_ChooseName(text, variable);
end
self:GetParent():Hide();
end,
EditBoxOnEscapePressed = function(self)
self:GetParent():Hide();
end,
OnHide = function(self)
-- Removed for wow 3.3.5, it seems like there is a focu stack
-- now that obsoletes this anyway. If not, there isn't a
-- single ChatFrameEditBox anymore, there's ChatFrame1EditBox etc.
-- if ( ChatFrameEditBox:IsVisible() ) then
-- ChatFrameEditBox:SetFocus();
-- end
self.editBox:SetText("");
end,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
};
 
NeedToKnow.BarMenu_MoreOptions = {
{ VariableName = "Enabled", MenuText = NEEDTOKNOW.BARMENU_ENABLE },
{ VariableName = "AuraName", MenuText = NEEDTOKNOW.BARMENU_CHOOSENAME, Type = "Dialog", DialogText = "CHOOSENAME_DIALOG" },
{ VariableName = "BuffOrDebuff", MenuText = NEEDTOKNOW.BARMENU_BUFFORDEBUFF, Type = "Submenu" },
{ VariableName = "Options", MenuText = "Settings", Type = "Submenu" },
{},
{ VariableName = "TimeFormat", MenuText = NEEDTOKNOW.BARMENU_TIMEFORMAT, Type = "Submenu" },
{ VariableName = "Show", MenuText = "Show...", Type = "Submenu" }, -- FIXME: Localization
{ VariableName = "VisualCastTime", MenuText = NEEDTOKNOW.BARMENU_VISUALCASTTIME, Type = "Submenu" },
{ VariableName = "BlinkSettings", MenuText = "Blink Settings", Type = "Submenu" }, -- FIXME: Localization
{ VariableName = "BarColor", MenuText = NEEDTOKNOW.BARMENU_BARCOLOR, Type = "Color" },
}
 
NeedToKnow.BarMenu_SubMenus = {
-- the keys on this table need to match the settings variable names
BuffOrDebuff = {
{ Setting = "HELPFUL", MenuText = NEEDTOKNOW.BARMENU_HELPFUL },
{ Setting = "HARMFUL", MenuText = NEEDTOKNOW.BARMENU_HARMFUL },
{ Setting = "TOTEM", MenuText = NEEDTOKNOW.BARMENU_TOTEM },
{ Setting = "CASTCD", MenuText = NEEDTOKNOW.BARMENU_CASTCD },
{ Setting = "BUFFCD", MenuText = NEEDTOKNOW.BARMENU_BUFFCD },
{ Setting = "USABLE", MenuText = NEEDTOKNOW.BARMENU_USABLE },
},
TimeFormat = {
{ Setting = "Fmt_SingleUnit", MenuText = NEEDTOKNOW.FMT_SINGLEUNIT },
{ Setting = "Fmt_TwoUnits", MenuText = NEEDTOKNOW.FMT_TWOUNITS },
{ Setting = "Fmt_Float", MenuText = NEEDTOKNOW.FMT_FLOAT },
},
Unit = {
{ Setting = "player", MenuText = NEEDTOKNOW.BARMENU_PLAYER },
{ Setting = "target", MenuText = NEEDTOKNOW.BARMENU_TARGET },
{ Setting = "targettarget", MenuText = NEEDTOKNOW.BARMENU_TARGETTARGET },
{ Setting = "focus", MenuText = NEEDTOKNOW.BARMENU_FOCUS },
{ Setting = "pet", MenuText = NEEDTOKNOW.BARMENU_PET },
{ Setting = "vehicle", MenuText = NEEDTOKNOW.BARMENU_VEHICLE },
{ Setting = "mhand", MenuText = NEEDTOKNOW.BARMENU_MAIN_HAND },
{ Setting = "ohand", MenuText = NEEDTOKNOW.BARMENU_OFF_HAND },
},
Opt_HELPFUL = {
{ VariableName = "Unit", MenuText = NEEDTOKNOW.BARMENU_CHOOSEUNIT, Type = "Submenu" },
{ VariableName = "bDetectExtends", MenuText = "Track duration increases" }, -- FIXME: Localization
{ VariableName = "OnlyMine", MenuText = NEEDTOKNOW.BARMENU_ONLYMINE },
{ VariableName = "show_all_stacks", MenuText = "Sum stacks from all casters" },
},
Opt_TOTEM = {},
Opt_CASTCD =
{
{ VariableName = "append_cd", MenuText = "Append \"CD\"" }, -- FIXME: Localization
},
Opt_BUFFCD =
{
{ VariableName = "buffcd_duration", MenuText = "Cooldown duration...", Type = "Dialog", DialogText = "BUFFCD_DURATION_DIALOG", Numeric=true },
{ VariableName = "append_cd", MenuText = "Append \"CD\"" }, -- FIXME: Localization
},
Opt_USABLE =
{
{ VariableName = "usable_duration", MenuText = "Usable duration...", Type = "Dialog", DialogText = "USABLE_DURATION_DIALOG", Numeric=true },
{ VariableName = "append_usable", MenuText = "Append \"Usable\"" }, -- FIXME: Localization
},
VisualCastTime = {
{ VariableName = "vct_enabled", MenuText = NEEDTOKNOW.BARMENU_VCT_ENABLE },
{ VariableName = "vct_color", MenuText = NEEDTOKNOW.BARMENU_VCT_COLOR, Type = "Color" },
{ VariableName = "vct_spell", MenuText = NEEDTOKNOW.BARMENU_VCT_SPELL, Type = "Dialog", DialogText = "CHOOSE_VCT_SPELL_DIALOG" },
{ VariableName = "vct_extra", MenuText = NEEDTOKNOW.BARMENU_VCT_EXTRA, Type = "Dialog", DialogText = "CHOOSE_VCT_EXTRA_DIALOG", Numeric=true },
},
Show = {
{ VariableName = "show_icon", MenuText = "Icon" },
{ VariableName = "show_text", MenuText = "Aura Name" },
{ VariableName = "show_count", MenuText = "Stack Count" },
{ VariableName = "show_time", MenuText = "Time Remaining" },
{ VariableName = "show_spark", MenuText = "Spark" },
{ VariableName = "show_mypip", MenuText = "Indicator if mine" },
{ VariableName = "show_text_user", MenuText = "Override Aura Name", Type = "Dialog", DialogText = "CHOOSE_OVERRIDE_TEXT", Checked = function(settings) return "" ~= settings.show_text_user end },
},
BlinkSettings = {
{ VariableName = "blink_enabled", MenuText = NEEDTOKNOW.BARMENU_VCT_ENABLE },
{ VariableName = "blink_label", MenuText = "Bar text while blinking...", Type = "Dialog", DialogText="CHOOSE_BLINK_TITLE_DIALOG" },
{ VariableName = "MissingBlink", MenuText = "Bar color when blinking...", Type = "Color" }, -- FIXME: Localization
{ VariableName = "blink_ooc", MenuText = "Blink out of combat" }, -- FIXME: Localization
{ VariableName = "blink_boss", MenuText = "Blink only for bosses" }, -- FIXME: Localization
},
};
 
NeedToKnow.BarMenu_SubMenus.Opt_HARMFUL = NeedToKnow.BarMenu_SubMenus.Opt_HELPFUL;
 
function NeedToKnow.Bar_OnMouseUp(self, button)
if ( button == "RightButton" ) then
PlaySound("UChatScrollButton");
NeedToKnow.CurrentBar["barID"] = self:GetID();
NeedToKnow.CurrentBar["groupID"] = self:GetParent():GetID();
if not NeedToKnow.DropDown then
NeedToKnow.DropDown = CreateFrame("Frame", "NeedToKnowDropDown", nil, "NeedToKnow_DropDownTemplate")
end
 
-- There's no OpenDropDownMenu that forces it to show in the new place,
-- so we have to check if the first Toggle opened or closed it
ToggleDropDownMenu(1, nil, NeedToKnow.DropDown, "cursor", 0, 0);
if not DropDownList1:IsShown() then
ToggleDropDownMenu(1, nil, NeedToKnow.DropDown, "cursor", 0, 0);
end
end
end
 
function NeedToKnow.BarMenu_AddButton(barSettings, i_desc, i_parent)
info = UIDropDownMenu_CreateInfo();
local item_type = i_desc["Type"];
info.text = i_desc["MenuText"];
info.value = i_desc["VariableName"];
if ( nil == info.value and nil ~= i_desc["Setting"]) then
info.value = i_parent;
item_type = "SetVar";
end;
 
local varSettings = barSettings[info.value];
if ( not varSettings and (item_type == "Check" or item_type == "Color") ) then
print (string.format("NTK: Could not find %s in", info.value), barSettings);
return
end
 
info.hasArrow = false;
local b = i_desc["Checked"]
if b then
if type(b) == "function" then
info.checked = b(barSettings)
else
info.checked = b
end
end
--info.notCheckable = true; -- Doesn't prevent checking, just formats the line differently
info.keepShownOnClick = true;
 
if ( not item_type and not text and not info.value ) then
info.func = NeedToKnow.BarMenu_IgnoreToggle;
info.disabled = true;
elseif ( nil == item_type or item_type == "Check" ) then
info.func = NeedToKnow.BarMenu_ToggleSetting;
info.checked = (nil ~= varSettings and varSettings);
info.notCheckable = false;
elseif ( item_type == "SetVar" ) then
info.func = NeedToKnow.BarMenu_ChooseSetting;
info.value = i_desc["Setting"];
info.checked = (varSettings == info.value);
info.notCheckable = false;
info.keepShownOnClick = false;
elseif ( item_type == "Submenu" ) then
info.hasArrow = true;
--info.notCheckable = true;
-- The above doesn't really do what we want, so do it ourselves
info.func = NeedToKnow.BarMenu_IgnoreToggle;
elseif ( item_type == "Dialog" ) then
info.func = NeedToKnow.BarMenu_ShowNameDialog;
info.keepShownOnClick = false;
info.value = {variable = i_desc.VariableName, text = i_desc.DialogText, numeric = i_desc.Numeric };
elseif ( item_type == "Color" ) then
info.hasColorSwatch = 1;
info.hasOpacity = true;
info.r = varSettings.r;
info.g = varSettings.g;
info.b = varSettings.b;
info.opacity = 1 - varSettings.a;
info.swatchFunc = NeedToKnow.BarMenu_SetColor;
info.opacityFunc = NeedToKnow.BarMenu_SetOpacity;
info.cancelFunc = NeedToKnow.BarMenu_CancelColor;
 
info.func = UIDropDownMenuButton_OpenColorPicker;
info.keepShownOnClick = false;
end
 
UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 
if ( item_type == "Color" ) then
-- Sadly, extraInfo isn't a field propogated to the button
-- Code to get the button copied from UIDropDownMenu_AddButton
local level = UIDROPDOWNMENU_MENU_LEVEL;
local listFrame = _G["DropDownList"..level];
local index = listFrame and (listFrame.numButtons) or 1;
local listFrameName = listFrame:GetName();
local button = _G[listFrameName.."Button"..index];
button.extraInfo = info.value;
end
end
 
function NeedToKnow.BarMenu_Initialize()
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local barSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID];
 
if ( barSettings.MissingBlink.a == 0 ) then
barSettings.blink_enabled = false;
end
NeedToKnow.BarMenu_SubMenus.Options = NeedToKnow.BarMenu_SubMenus["Opt_"..barSettings.BuffOrDebuff];
 
if ( UIDROPDOWNMENU_MENU_LEVEL > 1 ) then
if ( UIDROPDOWNMENU_MENU_VALUE == "VisualCastTime" ) then
-- Create a summary title for the visual cast time submenu
local title = "";
if ( barSettings.vct_spell and "" ~= barSettings.vct_spell ) then
title = title .. barSettings.vct_spell;
end
local fExtra = tonumber(barSettings.vct_extra);
if ( fExtra and fExtra > 0 ) then
if ("" ~= title) then
title = title .. " + ";
end
title = title .. string.format("%0.1fs", fExtra);
end
if ( "" ~= title ) then
local info = UIDropDownMenu_CreateInfo();
info.text = title;
info.isTitle = true;
UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
end
end
local subMenus = NeedToKnow.BarMenu_SubMenus;
for index, value in ipairs(subMenus[UIDROPDOWNMENU_MENU_VALUE]) do
NeedToKnow.BarMenu_AddButton(barSettings, value, UIDROPDOWNMENU_MENU_VALUE);
end
 
if ( false == barSettings.OnlyMine and UIDROPDOWNMENU_MENU_LEVEL == 2 ) then
NeedToKnow.BarMenu_UncheckAndDisable(2, "bDetectExtends", false);
end
return;
end
 
-- show name
if ( barSettings.AuraName ) and ( barSettings.AuraName ~= "" ) then
local info = UIDropDownMenu_CreateInfo();
info.text = barSettings.AuraName;
info.isTitle = true;
UIDropDownMenu_AddButton(info);
end
 
local moreOptions = NeedToKnow.BarMenu_MoreOptions;
for index, value in ipairs(moreOptions) do
NeedToKnow.BarMenu_AddButton(barSettings, moreOptions[index]);
end
 
info = UIDropDownMenu_CreateInfo();
info.disabled = true;
UIDropDownMenu_AddButton(info);
 
-- clear settings
info = UIDropDownMenu_CreateInfo();
info.text = NEEDTOKNOW.BARMENU_CLEARSETTINGS;
info.func = NeedToKnow.BarMenu_ClearSettings;
UIDropDownMenu_AddButton(info);
 
NeedToKnow.BarMenu_UpdateSettings(barSettings);
end
 
function NeedToKnow.BarMenu_IgnoreToggle(self, a1, a2, checked)
local button = NeedToKnow.BarMenu_GetItem(NeedToKnow.BarMenu_GetItemLevel(self), self.value);
if ( button ) then
local checkName = button:GetName() .. "Check";
_G[checkName]:Hide();
button.checked = false;
end
end
 
function NeedToKnow.BarMenu_ToggleSetting(self, a1, a2, checked)
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local barSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID];
barSettings[self.value] = self.checked;
local level = NeedToKnow.BarMenu_GetItemLevel(self);
 
if ( self.value == "OnlyMine" ) then
if ( false == self.checked ) then
NeedToKnow.BarMenu_UncheckAndDisable(level, "bDetectExtends", false);
else
NeedToKnow.BarMenu_EnableItem(level, "bDetectExtends");
NeedToKnow.BarMenu_CheckItem(level, "show_all_stacks", false);
end
elseif ( self.value == "blink_enabled" ) then
if ( true == self.checked and barSettings.MissingBlink.a == 0 ) then
barSettings.MissingBlink.a = 0.5
end
elseif ( self.value == "show_all_stacks" ) then
if ( true == self.checked ) then
NeedToKnow.BarMenu_CheckItem(level, "OnlyMine", false);
end
end
NeedToKnow.Bar_Update(groupID, barID);
end
 
function NeedToKnow.BarMenu_GetItemLevel(i_button)
local path = i_button:GetName();
local levelStr = path:match("%d+");
return tonumber(levelStr);
end
 
function NeedToKnow.BarMenu_GetItem(i_level, i_valueName)
local listFrame = _G["DropDownList"..i_level];
local listFrameName = listFrame:GetName();
local n = listFrame.numButtons;
for index=1,n do
local button = _G[listFrameName.."Button"..index];
local txt = button.value;
if ( txt == i_valueName ) then
return button;
end
end
return nil;
end
 
function NeedToKnow.BarMenu_CheckItem(i_level, i_valueName, i_bCheck)
local button = NeedToKnow.BarMenu_GetItem(i_level, i_valueName);
if ( button ) then
local checkName = button:GetName() .. "Check";
local check = _G[checkName];
if ( i_bCheck ) then
check:Show();
button.checked = true;
else
check:Hide();
button.checked = false;
end
NeedToKnow.BarMenu_ToggleSetting(button);
end
end
 
function NeedToKnow.BarMenu_EnableItem(i_level, i_valueName)
local button = NeedToKnow.BarMenu_GetItem(i_level, i_valueName)
if ( button ) then
button:Enable();
end
end
 
function NeedToKnow.BarMenu_UncheckAndDisable(i_level, i_valueName)
local button = NeedToKnow.BarMenu_GetItem(i_level, i_valueName);
if ( button ) then
NeedToKnow.BarMenu_CheckItem(i_level, i_valueName, false);
button:Disable();
end
end
 
function NeedToKnow.BarMenu_UpdateSettings(barSettings)
local type = barSettings.BuffOrDebuff;
local Opt = NeedToKnow.BarMenu_SubMenus["Opt_"..type];
if ( not Opt ) then Opt = {} end
NeedToKnow.BarMenu_SubMenus.Options = Opt;
local button = NeedToKnow.BarMenu_GetItem(1, "Options");
if button then
local arrow = _G[button:GetName().."ExpandArrow"]
local lbl = ""
if #Opt == 0 then
lbl = lbl .. "No "
button:Disable();
arrow:Hide();
else
button:Enable();
arrow:Show();
end
lbl = lbl .. NEEDTOKNOW["BARMENU_"..type].. " Settings";
button:SetText(lbl);
end
end
 
function NeedToKnow.BarMenu_ChooseSetting(self, a1, a2, checked)
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local barSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID]
barSettings[UIDROPDOWNMENU_MENU_VALUE] = self.value;
NeedToKnow.Bar_Update(groupID, barID);
 
if ( UIDROPDOWNMENU_MENU_VALUE == "BuffOrDebuff" ) then
NeedToKnow.BarMenu_UpdateSettings(barSettings)
end
end
 
-- TODO: There has to be a better way to do this, this has pretty bad user feel
function NeedToKnow.EditBox_Numeric_OnTextChanged(self, isUserInput)
if ( isUserInput ) then
local txt = self:GetText();
local culled = txt:gsub("[^0-9.]",""); -- Remove non-digits
local iPeriod = culled:find("[.]");
if ( nil ~= iPeriod ) then
local before = culled:sub(1, iPeriod);
local after = string.gsub( culled:sub(iPeriod+1), "[.]", "" );
culled = before .. after;
end
if ( txt ~= culled ) then
self:SetText(culled);
end
end
 
if ( NeedToKnow.EditBox_Original_OnTextChanged ) then
NeedToKnow.EditBox_Original_OnTextChanged(self, isUserInput);
end
end
 
function NeedToKnow.BarMenu_ShowNameDialog(self, a1, a2, checked)
StaticPopupDialogs["NEEDTOKNOW.CHOOSENAME_DIALOG"].text = NEEDTOKNOW[self.value.text];
local dialog = StaticPopup_Show("NEEDTOKNOW.CHOOSENAME_DIALOG");
dialog.variable = self.value.variable;
 
local edit = _G[dialog:GetName().."EditBox"];
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local barSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID];
local curval;
if ( dialog.variable ~= "ImportExport" ) then
curval = barSettings[dialog.variable];
-- else
-- curval = NeedToKnow.ExportSettingsToString(barSettings);
end
 
local numeric = self.value.numeric or false;
-- TODO: There has to be a better way to do this, this has pretty bad user feel
if ( nil == NeedToKnow.EditBox_Original_OnTextChanged ) then
NeedToKnow.EditBox_Original_OnTextChanged = edit:GetScript("OnTextChanged");
end
if ( numeric ) then
edit:SetScript("OnTextChanged", NeedToKnow.EditBox_Numeric_OnTextChanged);
else
edit:SetScript("OnTextChanged", NeedToKnow.EditBox_Original_OnTextChanged);
end
 
edit:SetFocus();
edit:SetText(curval);
end
 
function NeedToKnow.BarMenu_ChooseName(text, variable)
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local barSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID];
if ( variable ~= "ImportExport" ) then
barSettings[variable] = text;
-- else
-- NeedToKnow.ImportSettingsFromString(text, barSettings);
end
 
NeedToKnow.Bar_Update(groupID, barID);
end
 
function MemberDump(v, bIndex, filter)
if not v then
print("nil")
return
elseif type(v) == "table" then
print("members")
for index, value in pairs(v) do
if (not filter) or (type(index) == "string" and index:find(filter)) then
print(" ", index, value);
end
end
local mt = getmetatable(v)
if ( mt ) then
print("metatable")
for index, value in pairs(mt) do
if (not filter) or (type(index) == "string" and index:find(filter)) then
print(" ", index, value);
end
end
if ( mt.__index and bIndex) then
print("__index")
for index, value in pairs(mt.__index) do
if (not filter) or (type(index) == "string" and index:find(filter)) then
print(" ", index, value);
end
end
end
end
else
print(v)
end
 
end
 
function NeedToKnow.BarMenu_SetColor()
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local varSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID][ColorPickerFrame.extraInfo];
 
varSettings.r,varSettings.g,varSettings.b = ColorPickerFrame:GetColorRGB();
NeedToKnow.Bar_Update(groupID, barID);
end
 
function NeedToKnow.BarMenu_SetOpacity()
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local varSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID][ColorPickerFrame.extraInfo];
 
varSettings.a = 1 - OpacitySliderFrame:GetValue();
NeedToKnow.Bar_Update(groupID, barID);
end
 
function NeedToKnow.BarMenu_CancelColor(previousValues)
if ( previousValues.r ) then
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
local varSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID][ColorPickerFrame.extraInfo];
 
varSettings.r = previousValues.r;
varSettings.g = previousValues.g;
varSettings.b = previousValues.b;
varSettings.a = 1 - previousValues.opacity;
NeedToKnow.Bar_Update(groupID, barID);
end
end
 
function NeedToKnow.BarMenu_ClearSettings()
local groupID = NeedToKnow.CurrentBar["groupID"];
local barID = NeedToKnow.CurrentBar["barID"];
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Bars"][barID] = CopyTable(NEEDTOKNOW.BAR_DEFAULTS);
NeedToKnow.Bar_Update(groupID, barID);
CloseDropDownMenus();
end
 
 
-- -------------
-- RESIZE BUTTON
-- -------------
 
function NeedToKnow.Resizebutton_OnEnter(self)
local tooltip = _G["GameTooltip"];
GameTooltip_SetDefaultAnchor(tooltip, self);
tooltip:AddLine(NEEDTOKNOW.RESIZE_TOOLTIP, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
tooltip:Show();
end
 
function NeedToKnow.StartSizing(self, button)
local group = self:GetParent();
local groupID = self:GetParent():GetID();
group.oldScale = group:GetScale();
group.oldX = group:GetLeft();
group.oldY = group:GetTop();
-- group:ClearAllPoints();
-- group:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", group.oldX, group.oldY);
self.oldCursorX, self.oldCursorY = GetCursorPosition(UIParent);
self.oldWidth = _G[group:GetName().."Bar1"]:GetWidth();
self:SetScript("OnUpdate", NeedToKnow.Sizing_OnUpdate);
end
 
function NeedToKnow.Sizing_OnUpdate(self)
local uiScale = UIParent:GetScale();
local cursorX, cursorY = GetCursorPosition(UIParent);
local group = self:GetParent();
local groupID = self:GetParent():GetID();
 
-- calculate & set new scale
local newYScale = group.oldScale * (cursorY/uiScale - group.oldY*group.oldScale) / (self.oldCursorY/uiScale - group.oldY*group.oldScale) ;
local newScale = max(0.6, newYScale);
 
-- clamp the scale so the group is a whole number of pixels tall
local bar1 = _G[group:GetName().."Bar1"]
local barHeight = bar1:GetHeight()
local newHeight = newScale * barHeight
newHeight = math.floor(newHeight + 0.0002)
newScale = newHeight / barHeight
group:SetScale(newScale);
 
-- set new frame coords to keep same on-screen position
local newX = group.oldX * group.oldScale / newScale;
local newY = group.oldY * group.oldScale / newScale;
group:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", newX, newY);
 
-- calculate & set new bar width
local newWidth = max(50, ((cursorX - self.oldCursorX)/uiScale + self.oldWidth * group.oldScale)/newScale);
NeedToKnow.SetWidth(groupID, newWidth);
 
end
 
function NeedToKnow.SetWidth(groupID, width)
for barID = 1, NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["NumberBars"] do
local bar = _G["NeedToKnow_Group"..groupID.."Bar"..barID];
local background = _G[bar:GetName().."Background"];
local text = _G[bar:GetName().."Text"];
bar:SetWidth(width);
text:SetWidth(width-60);
NeedToKnow.SizeBackground(bar, bar.settings.show_icon);
end
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Width"] = width; -- move this to StopSizing?
end
 
function NeedToKnow.StopSizing(self, button)
self:SetScript("OnUpdate", nil)
local groupID = self:GetParent():GetID();
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Scale"] = self:GetParent():GetScale();
NeedToKnow.SavePosition(self:GetParent(), groupID);
end
 
function NeedToKnow.SavePosition(group, groupID)
groupID = groupID or group:GetID();
local point, _, relativePoint, xOfs, yOfs = group:GetPoint();
NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]["Position"] = {point, relativePoint, xOfs, yOfs};
end
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/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
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,239
--[[ $Id: CallbackHandler-1.0.lua 60548 2008-02-07 11:04:06Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 3
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}
 
local type = type
local pcall = pcall
local pairs = pairs
local assert = assert
local concat = table.concat
local loadstring = loadstring
local next = next
local select = select
local type = type
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", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(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.
 
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua New file
0,0 → 1,227
--[[
Name: LibSharedMedia-3.0
Revision: $Revision: 53 $
Author: Elkano (elkano@gmx.de)
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com)
Website: http://www.wowace.com/projects/libsharedmedia-3-0/
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons.
Dependencies: LibStub, CallbackHandler-1.0
License: LGPL v2.1
]]
 
local MAJOR, MINOR = "LibSharedMedia-3.0", 90000 + tonumber(("$Revision: 53 $"):match("(%d+)"))
local lib = LibStub:NewLibrary(MAJOR, MINOR)
 
if not lib then return end
 
local _G = getfenv(0)
 
local pairs = _G.pairs
local type = _G.type
 
local band = _G.bit.band
 
local table_insert = _G.table.insert
local table_sort = _G.table.sort
 
local locale = GetLocale()
local locale_is_western
local LOCALE_MASK = 0
lib.LOCALE_BIT_koKR = 1
lib.LOCALE_BIT_ruRU = 2
lib.LOCALE_BIT_zhCN = 4
lib.LOCALE_BIT_zhTW = 8
lib.LOCALE_BIT_western = 128
 
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
 
lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
 
lib.DefaultMedia = lib.DefaultMedia or {}
lib.MediaList = lib.MediaList or {}
lib.MediaTable = lib.MediaTable or {}
lib.MediaType = lib.MediaType or {}
lib.OverrideMedia = lib.OverrideMedia or {}
 
local defaultMedia = lib.DefaultMedia
local mediaList = lib.MediaList
local mediaTable = lib.MediaTable
local overrideMedia = lib.OverrideMedia
 
 
-- create mediatype constants
lib.MediaType.BACKGROUND = "background" -- background textures
lib.MediaType.BORDER = "border" -- border textures
lib.MediaType.FONT = "font" -- fonts
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures
lib.MediaType.SOUND = "sound" -- sound files
 
-- populate lib with default Blizzard data
-- BACKGROUND
if not lib.MediaTable.background then lib.MediaTable.background = {} end
lib.MediaTable.background["Blizzard Dialog Background"] = [[Interface\DialogFrame\UI-DialogBox-Background]]
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]]
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]]
lib.MediaTable.background["Blizzard Parchment"] = [[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]]
lib.MediaTable.background["Blizzard Parchment 2"] = [[Interface\AchievementFrame\UI-Achievement-Parchment]]
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]]
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]]
lib.MediaTable.background["Solid"] = [[Interface\Buttons\WHITE8X8]]
 
-- BORDER
if not lib.MediaTable.border then lib.MediaTable.border = {} end
lib.MediaTable.border["None"] = [[Interface\None]]
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]]
lib.MediaTable.border["Blizzard Dialog Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]]
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]]
 
-- FONT
if not lib.MediaTable.font then lib.MediaTable.font = {} end
local SML_MT_font = lib.MediaTable.font
if locale == "koKR" then
LOCALE_MASK = lib.LOCALE_BIT_koKR
--
SML_MT_font["굵은 글꼴"] = [[Fonts\2002B.TTF]]
SML_MT_font["기본 글꼴"] = [[Fonts\2002.TTF]]
SML_MT_font["데미지 글꼴"] = [[Fonts\K_Damage.TTF]]
SML_MT_font["퀘스트 글꼴"] = [[Fonts\K_Pagetext.TTF]]
--
lib.DefaultMedia["font"] = "기본 글꼴" -- someone from koKR please adjust if needed
--
elseif locale == "zhCN" then
LOCALE_MASK = lib.LOCALE_BIT_zhCN
--
SML_MT_font["伤害数字"] = [[Fonts\ZYKai_C.ttf]]
SML_MT_font["默认"] = [[Fonts\ZYKai_T.ttf]]
SML_MT_font["聊天"] = [[Fonts\ZYHei.ttf]]
--
lib.DefaultMedia["font"] = "默认" -- someone from zhCN please adjust if needed
--
elseif locale == "zhTW" then
LOCALE_MASK = lib.LOCALE_BIT_zhTW
--
SML_MT_font["提示訊息"] = [[Fonts\bHEI00M.ttf]]
SML_MT_font["聊天"] = [[Fonts\bHEI01B.ttf]]
SML_MT_font["傷害數字"] = [[Fonts\bKAI00M.ttf]]
SML_MT_font["預設"] = [[Fonts\bLEI00D.ttf]]
--
lib.DefaultMedia["font"] = "預設" -- someone from zhTW please adjust if needed
 
elseif locale == "ruRU" then
LOCALE_MASK = lib.LOCALE_BIT_ruRU
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
else
LOCALE_MASK = lib.LOCALE_BIT_western
locale_is_western = true
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
end
 
-- STATUSBAR
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]]
lib.DefaultMedia.statusbar = "Blizzard"
 
-- SOUND
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
lib.MediaTable.sound["None"] = [[Interface\Quiet.mp3]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input.
lib.DefaultMedia.sound = "None"
 
local function rebuildMediaList(mediatype)
local mtable = mediaTable[mediatype]
if not mtable then return end
if not mediaList[mediatype] then mediaList[mediatype] = {} end
local mlist = mediaList[mediatype]
-- list can only get larger, so simply overwrite it
local i = 0
for k in pairs(mtable) do
i = i + 1
mlist[i] = k
end
table_sort(mlist)
end
 
function lib:Register(mediatype, key, data, langmask)
if type(mediatype) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype))
end
if type(key) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key))
end
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end
mediatype = mediatype:lower()
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end
local mtable = mediaTable[mediatype]
if mtable[key] then return false end
 
mtable[key] = data
rebuildMediaList(mediatype)
self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key)
return true
end
 
function lib:Fetch(mediatype, key, noDefault)
local mtt = mediaTable[mediatype]
local overridekey = overrideMedia[mediatype]
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil
 
return result
end
 
function lib:IsValid(mediatype, key)
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
end
 
function lib:HashTable(mediatype)
return mediaTable[mediatype]
end
 
function lib:List(mediatype)
if not mediaTable[mediatype] then
return nil
end
if not mediaList[mediatype] then
rebuildMediaList(mediatype)
end
return mediaList[mediatype]
end
 
function lib:GetGlobal(mediatype)
return overrideMedia[mediatype]
end
 
function lib:SetGlobal(mediatype, key)
if not mediaTable[mediatype] then
return false
end
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil
self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype])
return true
end
 
function lib:GetDefault(mediatype)
return defaultMedia[mediatype]
end
 
function lib:SetDefault(mediatype, key)
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
defaultMedia[mediatype] = key
return true
else
return false
end
end
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/libs/LibSharedMedia-3.0/lib.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="LibSharedMedia-3.0.lua" />
</Ui>
\ No newline at end of file Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/libs/Changelog-LibSharedMedia-3.0-2.txt New file
0,0 → 1,222
------------------------------------------------------------------------
r56 | elkano | 2008-10-30 10:28:00 +0000 (Thu, 30 Oct 2008) | 1 line
Changed paths:
A /tags/2 (from /trunk:55)
 
tagging r55 for release/embedding
------------------------------------------------------------------------
r55 | arrowmaster | 2008-10-28 11:11:06 +0000 (Tue, 28 Oct 2008) | 1 line
Changed paths:
A /trunk/lib.xml
 
revert commit 54 by FUCKING DUMBASS Jncl, NEVER TOUCH THIS PROJECT AGAIN FUCKING DUMBASS
------------------------------------------------------------------------
r54 | jncl | 2008-10-28 11:02:15 +0000 (Tue, 28 Oct 2008) | 2 lines
Changed paths:
D /trunk/lib.xml
 
LibSharedMedia-3.0: Removed lib.xml from root level
- Current packaged version 50 has an incorrect TOC, but the one in the SVN is correct, so forcing a new package
------------------------------------------------------------------------
r53 | elkano | 2008-10-23 13:45:10 +0000 (Thu, 23 Oct 2008) | 1 line
Changed paths:
M /trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
added a type check for mediatype and key to :Register
------------------------------------------------------------------------
r52 | arrowmaster | 2008-10-14 21:30:05 +0000 (Tue, 14 Oct 2008) | 1 line
Changed paths:
M /tags/1
M /tags/1/CallbackHandler-1.0/CallbackHandler-1.0.lua
M /tags/1/LibSharedMedia-3.0.toc
M /tags/1/LibStub/LibStub.lua
M /tags/1/tests
M /tags/1/tests/LibSharedMedia-3.0 tests.lua
M /tags/1/tests/wow_api.lua
M /trunk
M /trunk/.pkgmeta
M /trunk/CallbackHandler-1.0/CallbackHandler-1.0.lua
M /trunk/LibSharedMedia-3.0.toc
M /trunk/LibStub/LibStub.lua
A /trunk/lib.xml
M /trunk/tests
M /trunk/tests/LibSharedMedia-3.0 tests.lua
M /trunk/tests/wow_api.lua
 
Add lib.xml back to base directory since removing it broke some externals, and fix various svn properties
------------------------------------------------------------------------
r51 | durcyn | 2008-10-14 20:59:32 +0000 (Tue, 14 Oct 2008) | 1 line
Changed paths:
M /trunk/LibSharedMedia-3.0.toc
 
LibSharedMedia-3.0: if we're going to nuke the root lib.xml, maybe the toc should refer to the child lib.xml, no?
------------------------------------------------------------------------
r49 | elkano | 2008-10-14 11:43:31 +0000 (Tue, 14 Oct 2008) | 1 line
Changed paths:
M /trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0: added some additional default media
------------------------------------------------------------------------
r48 | elkano | 2008-10-14 11:25:18 +0000 (Tue, 14 Oct 2008) | 5 lines
Changed paths:
M /trunk/.pkgmeta
M /trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
M /trunk/LibSharedMedia-3.0.toc
D /trunk/lib.xml
A /trunk/tests
A /trunk/tests/LibSharedMedia-3.0 tests.lua
A /trunk/tests/wow_api.lua
 
LibSharedMedia-3.0
- removed base folder lib.xml by now they should all have changed to the subfolder
- added some test code as separate file
- cleaned up ruRU code
- fixed TOC for WoW 3.x
------------------------------------------------------------------------
r47 | nevcairiel | 2008-10-12 11:40:04 +0000 (Sun, 12 Oct 2008) | 1 line
Changed paths:
M /trunk/LibSharedMedia-3.0.toc
 
Patch 3.0 prep: Remove LoD from Libraries that have no load manager (LoD+OptDep Bug)
------------------------------------------------------------------------
r46 | nevcairiel | 2008-10-09 21:53:54 +0000 (Thu, 09 Oct 2008) | 1 line
Changed paths:
M /trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
WoWAce Post-Processing: Virtually inflate Library Revision numbers for proper upgrade path
------------------------------------------------------------------------
r45 | ackis | 2008-10-04 06:04:47 +0000 (Sat, 04 Oct 2008) | 1 line
Changed paths:
M /trunk/.pkgmeta
 
Fake commit to see if this will be packaged
------------------------------------------------------------------------
r44 | root | 2008-09-29 21:29:16 +0000 (Mon, 29 Sep 2008) | 1 line
Changed paths:
A /trunk/.pkgmeta
 
Facilitate WowAce-on-CurseForge transition
------------------------------------------------------------------------
r42 | root | 2008-09-29 20:58:19 +0000 (Mon, 29 Sep 2008) | 1 line
Changed paths:
D /tmp/trunk/LibSharedMedia-3.0
A /trunk (from /tmp/trunk/LibSharedMedia-3.0:41)
 
Importing old repo data under /trunk
------------------------------------------------------------------------
r41 | StingerSoft | 2008-09-20 09:45:25 +0000 (Sat, 20 Sep 2008) | 2 lines
Changed paths:
M /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0
- added ruRU local
------------------------------------------------------------------------
r34 | helium | 2008-03-31 10:09:02 +0000 (Mon, 31 Mar 2008) | 2 lines
Changed paths:
M /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
 
LibSharedMedia-3.0
- TOC 20400
------------------------------------------------------------------------
r33 | arrowmaster | 2008-03-27 12:26:53 +0000 (Thu, 27 Mar 2008) | 1 line
Changed paths:
A /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0
A /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
A /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0/lib.xml
D /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
M /tmp/trunk/LibSharedMedia-3.0/lib.xml
 
LibSharedMedia-3.0: move library to a sub directory so libs don't get included when using externals, leaving an extra lib.xml for backwards compat
------------------------------------------------------------------------
r31 | nevcairiel | 2008-03-25 00:53:46 +0000 (Tue, 25 Mar 2008) | 1 line
Changed paths:
M /tmp/trunk/LibSharedMedia-3.0/CallbackHandler-1.0/CallbackHandler-1.0.lua
 
LibSharedMedia-3.0: - update callbackhandler
------------------------------------------------------------------------
r29 | elkano | 2008-03-04 11:13:28 +0000 (Tue, 04 Mar 2008) | 1 line
Changed paths:
M /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
 
LibSharedMedia-3.0: fixed slashes in toc
------------------------------------------------------------------------
r28 | elkano | 2008-03-04 10:35:57 +0000 (Tue, 04 Mar 2008) | 1 line
Changed paths:
M /tmp/trunk/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0: adding the magic keyword
------------------------------------------------------------------------
r27 | elkano | 2008-03-04 10:34:07 +0000 (Tue, 04 Mar 2008) | 1 line
Changed paths:
A /tmp/trunk/LibSharedMedia-3.0 (from /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0:26)
 
LibSharedMedia-3.0: moving to trunk
------------------------------------------------------------------------
r26 | elkano | 2008-02-26 07:52:48 +0000 (Tue, 26 Feb 2008) | 1 line
Changed paths:
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0: rearranged some code so upgrades will always overwrite default data (allowing updates to it)
------------------------------------------------------------------------
r24 | elkano | 2008-02-21 11:55:51 +0000 (Thu, 21 Feb 2008) | 1 line
Changed paths:
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0: now rebuilds media list after sth new was registered
------------------------------------------------------------------------
r23 | elkano | 2008-02-18 08:42:23 +0000 (Mon, 18 Feb 2008) | 3 lines
Changed paths:
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/CallbackHandler-1.0
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/CallbackHandler-1.0/CallbackHandler-1.0.lua
D /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/CallbackHandler-1.0.lua
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibStub
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibStub/LibStub.lua
D /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibStub.lua
 
LibSharedMedia-3.0
- changing name shown to "Lib: SharedMedia-3.0"
- move LS and CBH to subdirectories
------------------------------------------------------------------------
r22 | nevcairiel | 2008-02-18 08:36:16 +0000 (Mon, 18 Feb 2008) | 2 lines
Changed paths:
D /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua (from /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua:20)
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/lib.xml (from /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/lib.xml:20)
 
LibSharedMedia-3.0
- or maybe not
------------------------------------------------------------------------
r21 | nevcairiel | 2008-02-18 08:14:05 +0000 (Mon, 18 Feb 2008) | 2 lines
Changed paths:
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0/LibSharedMedia-3.0.lua (from /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua:20)
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0/lib.xml (from /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/lib.xml:20)
D /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
D /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/lib.xml
 
LibSharedMedia-3.0
- update layout to the library standard, so embeds dont get the libraries with it
------------------------------------------------------------------------
r19 | elkano | 2008-02-05 14:40:25 +0000 (Tue, 05 Feb 2008) | 1 line
Changed paths:
M /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/CallbackHandler-1.0.lua
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibStub.lua
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/lib.xml
 
LibSharedMedia-3.0: add LibStub, CallBackHandler, toc and xml files
------------------------------------------------------------------------
r17 | elkano | 2008-02-05 14:08:16 +0000 (Tue, 05 Feb 2008) | 3 lines
Changed paths:
A /tmp/branches/LibSharedMedia-3.0/Elkano
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0
A /tmp/branches/LibSharedMedia-3.0/Elkano/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
 
LibSharedMedia-3.0
- pushing version
- updating my code
------------------------------------------------------------------------
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/readme.txt New file
0,0 → 1,122
 
--------------------
NeedToKnow
by Kitjan
--------------------
 
 
NeedToKnow allows you to monitor specific buffs and debuffs of your choosing as timer bars that always appear in a consistent place on your screen in a consistent color. It's especially useful for monitoring frequently used short-duration buffs and debuffs. For example, a rogue could configure NeedToKnow to show timer bars for Slice and Dice, Rupture, and their own stack of Deadly Poison VII. A death knight could use it to track their own diseases on a mob. NeedToKnow also works with procs and on-use trinkets. The number, size, position, and appearance of timer bars are all customizable.
 
 
------------
Instructions
------------
 
General options are available in the Blizzard interface options menu. You can type "/needtoknow" or "/ntk" to lock/unlock the addon. To configure individual bars, right click them while unlocked. Bars work while locked.
 
When entering your settings, be careful with your spelling and capitalization. Also remember that buffs and debuffs sometimes have different names than the items and abilities that apply them. The Death Knight ability Icy Touch, for example, applies a DoT called Frost Fever.
 
 
----------
Change log
----------
 
2.8.0
- Added the ability to track increases in spell duration, especially useful for dps druids
- Marked as being a 3.3 addon
- Fixed: Took advantage of a new 3.3 API to get the spell id of active buffs and debuffs. Bars that check spellid should be much more reliable and, for example, be able to tell the difference between the two different Death's Verdict procs
- Fixed: Totem timing is much more accurate
- Fixed: Visual cast times now updates based on changes in haste and other casting-time-affecting abilities
 
2.7.1
- Fixed: Accidentally removed the background color picker
 
2.7.0
- Added options for how the time text is formatted. The current style is the default, with mm:ss and ss.t as other options
- Added "visual cast time" overlay which can be used to tell when there's less than some critical amount of time left on an aura
- Hid the spark when the aura lasts longer than the bar (either an infinite duration, or using the Max duration feature.)
- Hid the time text when the aura has an infinite duration
 
2.6.0
- Added support for a new "Buff or Debuff" type: Totem. Type in the name of the totem to watch for (can be a partial string.)
- Fixed a parse error in the DE localization
- Slightly improved performance of "target of target"
- Added two new /ntk options: show and hide. They can be used to temporarily show and hide the ntk groups.
 
2.5.2
-Changed event parsing to try to be more robust (see autobot's errors)
 
2.5.1
-Trying a different strategy for identifying "only cast by me" spells
-When editing the watched auras, the edit field starts with the current value
-Configuring by SpellID is automatically detected and does not need a menu item checked
 
2.5
-Fixed ToT issue
-Added support for SpellID
 
2.4.3
-Added SharedMedia support, uses LibSharedMedia-3.0
-Greatly improved performance
 
2.4.2
-Fixed a bug with the multiple buffs per line
-Fixed a small bug with resize button showing
-Optimized performance slightly
 
2.4.1
 
-Fixed character restriction on buff names, no accepts up to 255 characters.
-Added Russian localization
 
2.4
 
-Brought up to 3.2 API standards
-Added multiple buffs/debuffs per bar
-Dual-Specialization support
 
Version 2.2
- Added option to show bars with a fixed maximum duration
- Fixed an issue with targetoftarget
- Added koKR localization. Thanks, metalchoir!
- Added deDE localization. Thanks, sp00n & Fxfighter!
 
Version 2.1
- Updated for WoW 3.1
- Can now track spells cast by player's pet or vehicle
- Can now track buffs/debuffs on player's vehicle
- Added options for background color, bar spacing, bar padding, bar opacity
- Fixed a problem with buff charges not showing as consumed
 
Version 2.0.1
- Updated for WoW 3.0
- Can now track (de)buffs applied by others
- Added option to only show buffs/debuffs if applied by self
 
Version 2.0
- Added support for monitoring debuffs
- Added support for variable numbers of bars
- Added support for separate groups of bars
- Added support for monitoring buffs/debuffs on target, focus, pet, or target of target
- Bars are now click-through while locked
- Reminder icons have been been greatly expanded in functionality and split off into their own addon: TellMeWhen
- Cleaner bar graphics
- Users of older versions will need to re-enter settings
 
Version 1.2
- Updated for WoW 2.4 API changes
 
Version 1.1.1
- Icons should now work properly with item cooldowns.
- Reset button should now work properly when you first use the AddOn.
 
Version 1.1
- Icons will now show when reactive abilities (Riposte, Execute, etc.) are available.
- Added options for bar color and texture.
- Added graphical user interface. Most slash commands gone.
- Added localization support. Translations would be much appreciated.
- Users of older version will need to re-enter settings.
 
Version 1.0
- Hello world!
 
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/NeedToKnow.xml New file
0,0 → 1,209
<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="NeedToKnow_Localization.lua"/>
<Script file="NeedToKnow.lua"/>
<Script file="NeedToKnow_Options.lua"/>
 
<Frame name="NeedToKnow_DropDownTemplate" inherits="UIDropDownMenuTemplate" virtual="true">
<Anchors>
<Anchor point="TOP"/>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(self, NeedToKnow.BarMenu_Initialize, "MENU");
</OnLoad>
<OnShow>
UIDropDownMenu_Initialize(self, NeedToKnow.BarMenu_Initialize, "MENU");
</OnShow>
</Scripts>
</Frame>
 
<Frame name="NeedToKnow_GroupTemplate" virtual="true">
<Size>
<AbsDimension x="1" y="1"/>
</Size>
<Layers>
<Layer level="BACKGROUND">
<Texture setAllPoints="true">
<Color r="0" g="0" b="0" a="0"/>
</Texture>
</Layer>
</Layers>
<Frames>
<Button name="$parentResizeButton" frameStrata="HIGH">
<Size>
<AbsDimension x="20" y="20"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT"/>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentTexture" file="Interface\AddOns\NeedToKnow\Textures\Resize">
<Size>
<AbsDimension x="10" y="10"/>
</Size>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad>
getglobal(self:GetName().."Texture"):SetVertexColor(0.6, 0.6, 0.6);
</OnLoad>
<OnMouseDown>
NeedToKnow.StartSizing(self, button);
</OnMouseDown>
<OnMouseUp>
NeedToKnow.StopSizing(self, button);
</OnMouseUp>
<OnEnter>
NeedToKnow.Resizebutton_OnEnter(self);
getglobal(self:GetName().."Texture"):SetVertexColor(1, 1, 1);
</OnEnter>
<OnLeave>
GameTooltip:Hide();
getglobal(self:GetName().."Texture"):SetVertexColor(0.6, 0.6, 0.6);
</OnLeave>
</Scripts>
</Button>
</Frames>
</Frame>
 
<Frame name="NeedToKnow_BarTemplate" drawLayer="BORDER" toplevel="true" enableMouse="true" virtual="true">
<Size>
<AbsDimension x="271" y="18"/>
</Size>
<BarTexture file="Interface\PaperDollInfoFrame\UI-Character-Skills-Bar"/>
<BarColor r="1.0" g="0.7" b="0.0" a="1.0"/>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentBackground" setAllPoints="true">
<Color r="1" g="1" b="1" a="1"/>
<Size>
<AbsDimension x="277" y="24"/>
</Size>
<Anchors>
<Anchor point="CENTER">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level="BORDER">
<Texture name="$parentTexture">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
<AbsDimension x="0" y="-0"/>
</Anchor>
<Anchor point="BOTTOM" relativeTo="$parent" relativePoint="BOTTOM">
<AbsDimension x="-0" y="0"/>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="$parentText" inherits="GameFontHighlight" justifyH="LEFT">
<Size>
<AbsDimension x="180" y="16"/>
</Size>
<Anchors>
<Anchor point="LEFT">
<Offset>
<AbsDimension x="10" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentTime" inherits="GameFontHighlight" justifyH="RIGHT">
<Size>
<AbsDimension x="40" y="16"/>
</Size>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-10" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<Texture name="$parentSpark" file="Interface\CastingBar\UI-CastingBar-Spark" alphaMode="ADD">
<Size>
<AbsDimension x="32" y="60"/>
</Size>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent" relativePoint="RIGHT"/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self:RegisterForDrag("LeftButton");
</OnLoad>
<OnEnter>
local tooltip = _G["GameTooltip"];
tooltip:SetOwner(self:GetParent(), "ANCHOR_TOPLEFT");
tooltip:AddLine(NEEDTOKNOW.BAR_TOOLTIP1, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b, 1);
tooltip:AddLine(NEEDTOKNOW.BAR_TOOLTIP2, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
tooltip:Show();
</OnEnter>
<OnLeave>
GameTooltip:Hide();
</OnLeave>
<OnMouseUp>
NeedToKnow.Bar_OnMouseUp(self, button);
</OnMouseUp>
<OnSizeChanged>
NeedToKnow.Bar_OnSizeChanged(self)
</OnSizeChanged>
<OnDragStart>
self:GetParent():StartMoving();
</OnDragStart>
<OnDragStop>
self:GetParent():StopMovingOrSizing();
NeedToKnow.SavePosition(self:GetParent(), self:GetParent():GetID());
</OnDragStop>
</Scripts>
</Frame>
 
<Frame name="NeedToKnow_Group1" inherits="NeedToKnow_GroupTemplate" toplevel="true" movable="true" parent="UIParent" id="1">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="100" y="-200"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="NeedToKnow_Group2" inherits="NeedToKnow_GroupTemplate" toplevel="true" movable="true" parent="UIParent" id="2">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="100" y="-300"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="NeedToKnow_Group3" inherits="NeedToKnow_GroupTemplate" toplevel="true" movable="true" parent="UIParent" id="3">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="100" y="-400"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="NeedToKnow_Group4" inherits="NeedToKnow_GroupTemplate" toplevel="true" movable="true" parent="UIParent" id="4">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="100" y="-500"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
 
</Ui>
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/NeedToKnow.lua New file
0,0 → 1,1588
-- ----------------------
-- NeedToKnow
-- by Kitjan, lieandswell
-- ----------------------
 
 
if not trace then trace = print end
 
-- -------------
-- ADDON GLOBALS
-- -------------
 
NeedToKnow = {}
 
-- NEEDTOKNOW = {} is defined in the localization file, which must be loaded before this file
 
NEEDTOKNOW.VERSION = "3.1.7"
NEEDTOKNOW.MAXGROUPS = 4
NEEDTOKNOW.MAXBARS = 6
NEEDTOKNOW.UPDATE_INTERVAL = 0.05
NEEDTOKNOW.CURRENTSPEC = 1
 
-- Get the localized name of spell 75, which is "Auto Shot" in US English
NEEDTOKNOW.AUTO_SHOT = GetSpellInfo(75)
 
-- COMBAT_LOG_EVENT_UNFILTERED events where select(6,...) is the caster, 9 is the spellid, and 10 is the spell name
-- (used for Target-of-target monitoring)
NEEDTOKNOW.AURAEVENTS = {
SPELL_AURA_APPLIED = true,
SPELL_AURA_REMOVED = true,
SPELL_AURA_APPLIED_DOSE = true,
SPELL_AURA_REMOVED_DOSE = true,
SPELL_AURA_REFRESH = true,
SPELL_AURA_BROKEN = true,
SPELL_AURA_BROKEN_SPELL = true
}
 
 
NEEDTOKNOW.BAR_DEFAULTS = {
Enabled = true,
AuraName = "",
Unit = "player",
BuffOrDebuff = "HELPFUL",
OnlyMine = true,
BarColor = { r=0.6, g=0.6, b=0.6, a=1.0 },
MissingBlink = { r=0.9, g=0.1, b=0.1, a=0.5 },
TimeFormat = "Fmt_SingleUnit",
vct_enabled = false,
vct_color = { r=0.6, g=0.6, b=0.0, a=0.3 },
vct_spell = "",
vct_extra = 0,
bDetectExtends = false,
show_text = true,
show_count = true,
show_time = true,
show_spark = true,
show_icon = false,
show_mypip = false,
show_all_stacks = false,
show_text_user = "",
blink_enabled = false,
blink_ooc = true,
blink_boss = false,
blink_label = "",
buffcd_duration = 0,
usable_duration = 0,
append_cd = true,
append_usable = false,
}
NEEDTOKNOW.GROUP_DEFAULTS = {
Enabled = false,
NumberBars = 3,
Scale = 1.0,
Width = 270,
Bars = {},
Position = { "TOPLEFT", "TOPLEFT", 100, -100 },
FixedDuration = nil,
}
NEEDTOKNOW.DEFAULTS = {
Version = NEEDTOKNOW.VERSION,
Locked = false,
BarTexture = "BantoBar",
BarFont = "DEFAULT",
BkgdColor = { 0, 0, 0, 0.8 },
BarSpacing = 3,
BarPadding = 3,
Spec = {},
}
NEEDTOKNOW.SPEC_DEFAULTS = {
Groups = {},
}
 
for barID = 1, NEEDTOKNOW.MAXBARS do
NEEDTOKNOW.GROUP_DEFAULTS["Bars"][barID] = NEEDTOKNOW.BAR_DEFAULTS
end
 
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
NEEDTOKNOW.SPEC_DEFAULTS["Groups"][groupID] = NEEDTOKNOW.GROUP_DEFAULTS
end
 
for specID = 1, 2 do
NEEDTOKNOW.DEFAULTS["Spec"][specID] = NEEDTOKNOW.SPEC_DEFAULTS
end
 
function NeedToKnow.Test(stuff)
if ( stuff ) then
DEFAULT_CHAT_FRAME:AddMessage("NeedToKnow test: "..stuff)
else
DEFAULT_CHAT_FRAME:AddMessage("NeedToKnow test: "..self:GetName())
end
end
 
-- -------------------
-- SharedMedia Support
-- -------------------
 
NeedToKnow.LSM = LibStub("LibSharedMedia-3.0", true)
 
if not NeedToKnow.LSM:Fetch("statusbar", "Aluminum", true) then NeedToKnow.LSM:Register("statusbar", "Aluminum", [[Interface\Addons\NeedToKnow\Textures\Aluminum.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Armory", true) then NeedToKnow.LSM:Register("statusbar", "Armory", [[Interface\Addons\NeedToKnow\Textures\Armory.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "BantoBar", true) then NeedToKnow.LSM:Register("statusbar", "BantoBar", [[Interface\Addons\NeedToKnow\Textures\BantoBar.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "DarkBottom", true) then NeedToKnow.LSM:Register("statusbar", "DarkBottom", [[Interface\Addons\NeedToKnow\Textures\Darkbottom.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Default", true) then NeedToKnow.LSM:Register("statusbar", "Default", [[Interface\Addons\NeedToKnow\Textures\Default.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Flat", true) then NeedToKnow.LSM:Register("statusbar", "Flat", [[Interface\Addons\NeedToKnow\Textures\Flat.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Glaze", true) then NeedToKnow.LSM:Register("statusbar", "Glaze", [[Interface\Addons\NeedToKnow\Textures\Glaze.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Gloss", true) then NeedToKnow.LSM:Register("statusbar", "Gloss", [[Interface\Addons\NeedToKnow\Textures\Gloss.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Graphite", true) then NeedToKnow.LSM:Register("statusbar", "Graphite", [[Interface\Addons\NeedToKnow\Textures\Graphite.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Minimalist", true) then NeedToKnow.LSM:Register("statusbar", "Minimalist", [[Interface\Addons\NeedToKnow\Textures\Minimalist.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Otravi", true) then NeedToKnow.LSM:Register("statusbar", "Otravi", [[Interface\Addons\NeedToKnow\Textures\Otravi.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Smooth", true) then NeedToKnow.LSM:Register("statusbar", "Smooth", [[Interface\Addons\NeedToKnow\Textures\Smooth.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Smooth v2", true) then NeedToKnow.LSM:Register("statusbar", "Smooth v2", [[Interface\Addons\NeedToKnow\Textures\Smoothv2.tga]]) end
if not NeedToKnow.LSM:Fetch("statusbar", "Striped", true) then NeedToKnow.LSM:Register("statusbar", "Striped", [[Interface\Addons\NeedToKnow\Textures\Striped.tga]]) end
 
-- ---------------
-- EXECUTIVE FRAME
-- ---------------
 
function NeedToKnow.ExecutiveFrame_OnEvent(self, event, ...)
if ( event == "ADDON_LOADED" and select(1,...) == "NeedToKnow") then
 
if ( not NeedToKnow_Settings ) then
NeedToKnow_Settings = CopyTable(NEEDTOKNOW.DEFAULTS)
NeedToKnow_Settings["Spec"][1]["Groups"][1]["Enabled"] = true
NeedToKnow_Settings["Spec"][2]["Groups"][1]["Enabled"] = true
else
NeedToKnow.SafeUpgrade()
end
 
if ( not NeedToKnow_Settings.BarFont or NeedToKnow_Settings["BarFont"] == "DEFAULT" ) then
NeedToKnow_Settings["BarFont"] = GameFontHighlight:GetFont()
end
 
if ( not NeedToKnow_Visible ) then
NeedToKnow_Visible = true
end
 
NeedToKnow.last_cast = {} -- [spell][guidTarget] = { time, dur }
NeedToKnow.nSent = 0
NeedToKnow.totem_drops = {} -- array 1-4 of precise times the totems appeared
 
SlashCmdList["NEEDTOKNOW"] = NeedToKnow.SlashCommand
SLASH_NEEDTOKNOW1 = "/needtoknow"
SLASH_NEEDTOKNOW2 = "/ntk"
 
NeedToKnow.Update()
NeedToKnow.UIPanel_Update()
else
local fnName = "ExecutiveFrame_"..event
local fn = NeedToKnow[fnName]
if ( fn ) then
fn(...)
end
end
end
 
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SUCCEEDED(unit, spell, rank)
if unit == "player" then
local r = NeedToKnow.last_cast[spell]
if ( r and r.state == 1 ) then
r.state = 2
 
-- A little extra safety just in case we get two SUCCEEDED entries
-- before we get the combat log events for them (though I don't
-- think this is possible.)
NeedToKnow.last_success = spell
 
-- We need the actual target, which we can only get from the combat log.
-- Thankfully, the combat log event always comes after this one, so we
-- don't need to register for the combat log for long at all.
NeedToKnow_ExecutiveFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
 
if ( NeedToKnow.nSent > 1 ) then
NeedToKnow.nSent = NeedToKnow.nSent - 1
else
NeedToKnow.nSent = 0
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
end
end
end
end
 
function NeedToKnow.ExecutiveFrame_COMBAT_LOG_EVENT_UNFILTERED(time, event, guidCaster, ...)
-- the time that's passed in appears to be time of day, not game time like everything else.
time = GetTime()
-- TODO: Is checking r.state sufficient or must event be checked instead?
if ( guidCaster == NeedToKnow.guidPlayer ) then
local guidTarget, _, _, _, spell = select(3, ...)
local r = NeedToKnow.last_cast[spell]
if ( r and r.state == 2) then
r.state = 0
-- record this spellcast
if ( not r[guidTarget] ) then
r[guidTarget] = { time = time, dur = 0 }
else
r[guidTarget].time = time
r[guidTarget].dur = 0
end
 
-- Use this event to expire some targets. This should limit us to
-- two combats' worth of targets (since GC doesn't happen in combat)
for kG, vG in pairs(r) do
if ( type(vG) == "table" and ( vG.time + 300 < time ) ) then
r[kG] = nil
end
end
end
 
if ( spell == NeedToKnow.last_success ) then
-- We saw our spell, we can disconnect from the spam hose
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
end
end
 
function NeedToKnow.ExecutiveFrame_PLAYER_LOGIN()
-- save group positions if upgrading from version that used layout-local.txt
if ( not NeedToKnow_Settings.OldVersion or
NeedToKnow_Settings.OldVersion < "2.1" ) then
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
NeedToKnow.SavePosition(_G["NeedToKnow_Group"..groupID], groupID)
end
 
elseif (NeedToKnow_Settings["Version"] < "2.4") then
NeedToKnow.UIPanel_Update()
end
 
NeedToKnow.guidPlayer = UnitGUID("player")
NEEDTOKNOW.CURRENTSPEC = GetActiveTalentGroup()
 
local _, player_CLASS = UnitClass("player")
if player_CLASS == "DEATHKNIGHT" then
NeedToKnow.is_DK = 1
end
 
NeedToKnow.Update()
NeedToKnow.UIPanel_Update()
end
 
function NeedToKnow.ExecutiveFrame_PLAYER_TALENT_UPDATE()
NEEDTOKNOW.CURRENTSPEC = GetActiveTalentGroup()
NeedToKnow.Update()
NeedToKnow.UIPanel_Update()
end
 
function NeedToKnow.ExecutiveFrame_COMMENTATOR_ENTER_WORLD()
NeedToKnow.Update()
end
 
 
local function SetStatusBarValue(bar,texture,value,value0)
local pct0 = 0
if value0 then
pct0 = value0 / bar.max_value
if pct0 > 1 then pct0 = 1 end
end
 
local pct = value / bar.max_value
texture.cur_value = value
if pct > 1 then pct = 1 end
local w = (pct-pct0) * bar:GetWidth()
if w < 1 then
texture:Hide()
else
texture:SetWidth(w)
texture:SetTexCoord(pct0,0, pct0,1, pct,0, pct,1)
texture:Show()
end
end
 
 
function NeedToKnow.SafeUpgrade()
-- If there had been an error during the previous upgrade, NeedToKnow_Settings
-- may be in an inconsistent, halfway state.
local bCorruptUpgrade = false
if ( NeedToKnow_Settings["Spec"] ) then
for idxSpec = 1,2 do
local specSettings = NeedToKnow_Settings.Spec[idxSpec]
if ( not specSettings or not specSettings.Groups ) then
bCorruptUpgrade = true
else
for idxGroup = 1,NEEDTOKNOW.MAXGROUPS do
local groupSettings = specSettings.Groups[idxGroup]
if not groupSettings then
bCorruptUpgrade = true
end
end
end
end
if ( not bCorruptUpgrade and NeedToKnow_Settings["Version"] < "2.4" ) then
NeedToKnow_Settings.OldVersion = NeedToKnow_Settings["Version"]
NeedToKnow_Settings["Version"] = NEEDTOKNOW.VERSION
end
end
 
if ( bCorruptUpgrade or NeedToKnow_Settings["Version"] < "2.0" ) then -- total settings clear if v1.x
print("Old NeedToKnow settings not compatible with current version... starting from scratch")
NeedToKnow_Settings = CopyTable(NEEDTOKNOW.DEFAULTS)
NeedToKnow_Settings["Spec"][1]["Groups"][1]["Enabled"] = true
NeedToKnow_Settings["Spec"][2]["Groups"][1]["Enabled"] = true
 
-- if before dual spec support, copy old settings to both specs
elseif (NeedToKnow_Settings["Version"] < "2.4") then
local tempSettings = CopyTable(NeedToKnow_Settings)
NeedToKnow.Reset()
NeedToKnow_Settings["Locked"] = tempSettings["Locked"]
NeedToKnow_Settings["BarTexture"] = tempSettings["BarTexture"]
NeedToKnow_Settings["BkgdColor"] = tempSettings["BkgdColor"]
NeedToKnow_Settings["BarSpacing"] = tempSettings["BarSpacing"]
NeedToKnow_Settings["BarPadding"] = tempSettings["BarPadding"]
NeedToKnow_Settings["Version"] = tempSettings["Version"]
 
for i = 1, NEEDTOKNOW.MAXGROUPS do
NeedToKnow_Settings["Spec"][1]["Groups"][i] = tempSettings["Groups"][i]
NeedToKnow_Settings["Spec"][2]["Groups"][i] = tempSettings["Groups"][i]
end
end
NeedToKnow_Settings.OldVersion = NeedToKnow_Settings["Version"]
NeedToKnow_Settings["Version"] = NEEDTOKNOW.VERSION
 
-- Add any new settings
for iS,vS in ipairs(NeedToKnow_Settings["Spec"]) do
for kD, vD in pairs(NEEDTOKNOW.SPEC_DEFAULTS) do
if nil == vS[kD] then
vS[kD] = NeedToKnow.deepcopy(vD)
end
end
for iG,vG in ipairs(vS["Groups"]) do
for kD, vD in pairs(NEEDTOKNOW.GROUP_DEFAULTS) do
if nil == vG[kD] then
vG[kD] = NeedToKnow.deepcopy(vD)
end
end
for iB, vB in ipairs(vG["Bars"]) do
if nil == vB.blink_enabled and vB.MissingBlink then
vB.blink_enabled = vB.MissingBlink.a > 0
end
for kD, vD in pairs(NEEDTOKNOW.BAR_DEFAULTS) do
if nil == vB[kD] then
vB[kD] = NeedToKnow.deepcopy(vD)
end
end
end
end
end
end
 
-- Copies anything (int, table, whatever). Unlike CopyTable, deepcopy can
-- recreate a recursive reference structure (CopyTable will stack overflow.)
-- Copied from http://lua-users.org/wiki/CopyTable
function NeedToKnow.deepcopy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
 
function NeedToKnow.Update()
if (UnitExists("player")) then
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
NeedToKnow.Group_Update(groupID)
end
end
end
 
function NeedToKnow.Show(bShow)
NeedToKnow_Visible = bShow
for groupID = 1, NEEDTOKNOW.MAXGROUPS do
local groupName = "NeedToKnow_Group"..groupID
local group = _G[groupName]
local groupSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]
 
if (NeedToKnow_Visible and groupSettings.Enabled) then
group:Show()
else
group:Hide()
end
end
end
 
do
local executiveFrame = CreateFrame("Frame", "NeedToKnow_ExecutiveFrame")
executiveFrame:SetScript("OnEvent", NeedToKnow.ExecutiveFrame_OnEvent)
executiveFrame:RegisterEvent("ADDON_LOADED")
executiveFrame:RegisterEvent("PLAYER_LOGIN")
executiveFrame:RegisterEvent("PLAYER_TALENT_UPDATE")
executiveFrame:RegisterEvent("COMMENTATOR_ENTER_WORLD")
end
 
 
 
-- ------
-- GROUPS
-- ------
 
function NeedToKnow.Group_Update(groupID)
local groupName = "NeedToKnow_Group"..groupID
local group = _G[groupName]
local groupSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]
 
for barID = 1, groupSettings.NumberBars do
local barName = groupName.."Bar"..barID
local bar = _G[barName] or CreateFrame("Frame", barName, group, "NeedToKnow_BarTemplate")
bar:SetID(barID)
 
if ( barID > 1 ) then
bar:SetPoint("TOP", _G[groupName.."Bar"..(barID-1)], "BOTTOM", 0, -NeedToKnow_Settings.BarSpacing)
else
bar:SetPoint("TOPLEFT", group, "TOPLEFT")
end
 
NeedToKnow.Bar_Update(groupID, barID)
 
if ( not groupSettings.Enabled ) then
NeedToKnow.ClearScripts(bar)
end
end
for barID = groupSettings.NumberBars+1, NEEDTOKNOW.MAXBARS do
local bar = _G[groupName.."Bar"..barID]
if ( bar ) then
bar:Hide()
NeedToKnow.ClearScripts(bar)
end
end
 
local resizeButton = _G[groupName.."ResizeButton"]
resizeButton:SetPoint("BOTTOMRIGHT", groupName.."Bar"..groupSettings.NumberBars, "BOTTOMRIGHT", 8, -8)
if ( NeedToKnow_Settings["Locked"] ) then
resizeButton:Hide()
else
resizeButton:Show()
end
 
-- Early enough in the loading process (before PLAYER_LOGIN), we might not
-- know the position yet
if groupSettings.Position then
group:ClearAllPoints()
local point, relativePoint, xOfs, yOfs = unpack(groupSettings.Position)
group:SetPoint(point, UIParent, relativePoint, xOfs, yOfs)
group:SetScale(groupSettings.Scale)
end
 
if ( NeedToKnow_Visible and groupSettings.Enabled ) then
group:Show()
else
group:Hide()
end
end
 
 
 
-- ----
-- BARS
-- ----
 
-- Called when the configuration of the bar has changed, when the addon
-- is loaded or when ntk is locked and unlocked
function NeedToKnow.Bar_Update(groupID, barID)
local barName = "NeedToKnow_Group"..groupID.."Bar"..barID
local bar = _G[barName]
local background = _G[barName.."Background"]
bar.spark = _G[barName.."Spark"]
bar.text = _G[barName.."Text"]
bar.time = _G[barName.."Time"]
bar.bar1 = _G[barName.."Texture"]
 
local groupSettings = NeedToKnow_Settings["Spec"][NEEDTOKNOW.CURRENTSPEC]["Groups"][groupID]
local barSettings = groupSettings["Bars"][barID]
bar.auraName = barSettings.AuraName
if ( barSettings.BuffOrDebuff == "BUFFCD" or
barSettings.BuffOrDebuff == "TOTEM" or
barSettings.BuffOrDebuff == "USABLE" or
barSettings.BuffOrDebuff == "CASTCD")
then
barSettings.Unit = "player"
end
 
-- Split the spell names
bar.spells = {}
for barSpell in bar.auraName:gmatch("([^,]+),*") do
barSpell = strtrim(barSpell)
table.insert(bar.spells, barSpell)
end
 
-- split the user name overrides
bar.spell_names = {}
for un in barSettings.show_text_user:gmatch("([^,]+),*") do
un = strtrim(un)
table.insert(bar.spell_names, un)
end
 
-- Look for certain special "spell" names
barSettings.bAutoShot = nil
if ( barSettings.BuffOrDebuff == "CASTCD" ) then
for idx, barSpell in ipairs(bar.spells) do
if ( barSpell == "Auto Shot" or
barSpell == NEEDTOKNOW.AUTO_SHOT or
barSpell == "75" )
then
barSettings.bAutoShot = true
end
end
end
 
bar.settings = barSettings
bar.unit = barSettings.Unit
bar.nextUpdate = GetTime() + NEEDTOKNOW.UPDATE_INTERVAL
 
bar.fixedDuration = tonumber(groupSettings.FixedDuration)
 
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
bar.bar1:SetTexture(NeedToKnow.LSM:Fetch("statusbar", NeedToKnow_Settings["BarTexture"]))
if ( bar.bar2 ) then
bar.bar2:SetTexture(NeedToKnow.LSM:Fetch("statusbar", NeedToKnow_Settings["BarTexture"]))
end
local fontPath = NeedToKnow_Settings["BarFont"]
if ( fontPath ) then
-- TODO: I'd like to get that 12 from something rather than hard-code it
bar.text:SetFont(fontPath, 12)
bar.time:SetFont(fontPath, 12)
end
 
bar:SetWidth(groupSettings.Width)
bar.text:SetWidth(groupSettings.Width-60)
NeedToKnow.SizeBackground(bar, barSettings.show_icon)
 
background:SetHeight(bar:GetHeight() + 2*NeedToKnow_Settings["BarPadding"])
background:SetVertexColor(unpack(NeedToKnow_Settings["BkgdColor"]))
 
-- Set up the Visual Cast Time overlay. It isn't a part of the template
-- because most bars won't use it and thus don't need to pay the cost of
-- a hidden frame
if ( barSettings.vct_enabled ) then
if ( nil == bar.vct ) then
bar.vct = bar:CreateTexture(barName.."VisualCast", "ARTWORK")
bar.vct:SetPoint("TOPLEFT", bar, "TOPLEFT")
end
local argb = barSettings.vct_color
bar.vct:SetTexture(argb.r, argb.g, argb.b, argb.a )
bar.vct:SetBlendMode("ADD")
bar.vct:SetHeight(bar:GetHeight())
elseif (nil ~= bar.vct) then
bar.vct:Hide()
end
 
if ( barSettings.show_icon ) then
if ( not bar.icon ) then
bar.icon = bar:CreateTexture(bar:GetName().."Icon", "ARTWORK")
end
local size = bar:GetHeight()
bar.icon:SetWidth(size)
bar.icon:SetHeight(size)
bar.icon:ClearAllPoints()
bar.icon:SetPoint("TOPRIGHT", bar, "TOPLEFT", -NeedToKnow_Settings["BarPadding"], 0)
bar.icon:Show()
elseif (bar.icon) then
bar.icon:Hide()
end
 
if ( NeedToKnow_Settings["Locked"] ) then
-- Set up the bar to be functional
bar:EnableMouse(0)
local enabled = barSettings.Enabled
if ( enabled and barSettings.BuffOrDebuff == "BUFFCD" ) then
local dur = tonumber(barSettings.buffcd_duration)
if (not dur or dur < 1) then
print("Internal cooldown bar watching",barSettings.AuraName,"did not set a cooldown duration. Disabling the bar")
enabled = false
end
end
 
if ( enabled ) then
NeedToKnow.SetScripts(bar)
-- Events were cleared while unlocked, so need to check the bar again now
NeedToKnow.Bar_AuraCheck(bar)
else
NeedToKnow.ClearScripts(bar)
bar:Hide()
end
else
NeedToKnow.ClearScripts(bar)
-- Set up the bar to be configured
bar:EnableMouse(1)
 
bar.bar1:SetVertexColor(barSettings.BarColor.r, barSettings.BarColor.g, barSettings.BarColor.b)
bar.bar1:SetAlpha(barSettings.BarColor.a)
bar:Show()
bar.spark:Hide()
bar.time:Hide()
if ( bar.icon ) then
bar.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
end
if ( bar.vct ) then
bar.vct:SetWidth( bar:GetWidth() / 16)
bar.vct:Show()
end
if ( bar.bar2 ) then
bar.bar2:Hide()
end
 
local txt=""
if ( barSettings.show_mypip ) then
txt = txt.."* "
end
 
if ( barSettings.show_text ) then
if "" ~= barSettings.show_text_user then
txt = barSettings.show_text_user
else
txt = txt .. bar.auraName
end
 
if ( barSettings.append_cd
and (barSettings.BuffOrDebuff == "CASTCD"
or barSettings.BuffOrDebuff == "BUFFCD") )
then
txt = txt .. " CD"
elseif ( barSettings.append_usable
and barSettings.BuffOrDebuff == "USABLE" )
then
txt = txt .. " Usable"
end
if ( barSettings.bDetectExtends == true ) then
txt = txt .. " + 3s"
end
end
bar.text:SetText(txt)
 
if ( barSettings.Enabled ) then
bar:SetAlpha(1)
else
bar:SetAlpha(0.4)
end
end
end
 
function NeedToKnow.SetScripts(bar)
bar:SetScript("OnEvent", NeedToKnow.Bar_OnEvent)
bar:SetScript("OnUpdate", NeedToKnow.Bar_OnUpdate)
 
if ( "TOTEM" == bar.settings.BuffOrDebuff ) then
bar:RegisterEvent("PLAYER_TOTEM_UPDATE")
elseif ( "CASTCD" == bar.settings.BuffOrDebuff ) then
if ( bar.settings.bAutoShot ) then
bar:RegisterEvent("START_AUTOREPEAT_SPELL")
bar:RegisterEvent("STOP_AUTOREPEAT_SPELL")
end
bar:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
elseif ( "USABLE" == bar.settings.BuffOrDebuff ) then
bar:RegisterEvent("SPELL_UPDATE_USABLE")
elseif ( "mhand" == bar.settings.Unit or "ohand" == bar.settings.Unit ) then
bar:RegisterEvent("UNIT_INVENTORY_CHANGED")
elseif ( bar.unit == "targettarget" ) then
-- WORKAROUND: PLAYER_TARGET_CHANGED happens immediately, UNIT_TARGET every couple seconds
bar:RegisterEvent("PLAYER_TARGET_CHANGED")
bar:RegisterEvent("UNIT_TARGET")
-- WORKAROUND: Don't get UNIT_AURA for targettarget
bar:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
bar:RegisterEvent("UNIT_AURA")
if ( bar.unit == "focus" ) then
bar:RegisterEvent("PLAYER_FOCUS_CHANGED")
elseif ( bar.unit == "target" ) then
bar:RegisterEvent("PLAYER_TARGET_CHANGED")
end
end
 
if bar.settings.bDetectExtends or NeedToKnow.is_DK then
bar:RegisterEvent("UNIT_SPELLCAST_SENT")
end
if not bar.settings.blink_ooc then
bar:RegisterEvent("PLAYER_REGEN_DISABLED")
bar:RegisterEvent("PLAYER_REGEN_ENABLED")
end
end
 
function NeedToKnow.ClearScripts(bar)
bar:SetScript("OnEvent", nil)
bar:SetScript("OnUpdate", nil)
bar:UnregisterEvent("PLAYER_TARGET_CHANGED")
bar:UnregisterEvent("PLAYER_FOCUS_CHANGED")
bar:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
bar:UnregisterEvent("PLAYER_TOTEM_UPDATE")
bar:UnregisterEvent("UNIT_AURA")
bar:UnregisterEvent("UNIT_INVENTORY_CHANGED")
bar:UnregisterEvent("UNIT_TARGET")
bar:UnregisterEvent("UNIT_SPELLCAST_SENT")
bar:UnregisterEvent("PLAYER_REGEN_DISABLED")
bar:UnregisterEvent("PLAYER_REGEN_ENABLED")
bar:UnregisterEvent("START_AUTOREPEAT_SPELL")
bar:UnregisterEvent("STOP_AUTOREPEAT_SPELL")
bar:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
end
 
function NeedToKnow.Bar_OnSizeChanged(self)
if (self.bar1.cur_value) then SetStatusBarValue(self, self.bar1, self.bar1.cur_value) end
if (self.bar2) then SetStatusBarValue(self, self.bar2, self.bar2.cur_value, self.bar1.cur_value) end
end
 
function NeedToKnow.Bar_OnEvent(self, event, ...)
if ( event == "COMBAT_LOG_EVENT_UNFILTERED") then
local combatEvent = select(2, ...)
 
if ( NEEDTOKNOW.AURAEVENTS[combatEvent] ) then
local guidTarget = select(6, ...)
if ( guidTarget == UnitGUID(self.unit) ) then
local idSpell, nameSpell = select(9, ...)
if (self.auraName:find(idSpell) or
self.auraName:find(nameSpell))
then
NeedToKnow.Bar_AuraCheck(self)
end
end
elseif ( combatEvent == "UNIT_DIED" ) and ( select(6, ...) == UnitGUID(self.unit) ) then
NeedToKnow.Bar_AuraCheck(self)
end
elseif ( event == "PLAYER_TOTEM_UPDATE" ) or
( event == "ACTIONBAR_UPDATE_COOLDOWN" ) or
( event == "SPELL_UPDATE_USABLE" ) or
( event == "PLAYER_REGEN_ENABLED" ) or
( event == "PLAYER_REGEN_DISABLED" )
then
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_AURA" ) and ( select(1, ...) == self.unit ) then
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_INVENTORY_CHANGED" and select(1, ...) == "player" ) then
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "PLAYER_TARGET_CHANGED" ) or ( event == "PLAYER_FOCUS_CHANGED" ) then
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_TARGET" and select(1, ...) == "target" ) then
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_SPELLCAST_SENT" ) then
local unit, spell = select(1, ...)
if ( self.settings.bDetectExtends ) then
if unit == "player" and self.buffName == spell then
local r = NeedToKnow.last_cast[spell]
if ( r and r.state == 0 ) then
r.state = 1
NeedToKnow.nSent = NeedToKnow.nSent + 1
NeedToKnow_ExecutiveFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
end
end
end
if NeedToKnow.is_DK then
-- TODO: I hate that DKs have to pay this memory cost for every "spell" they ever cast
if unit == "player" then
if not NeedToKnow.last_sent then
NeedToKnow.last_sent = {}
end
NeedToKnow.last_sent[spell] = GetTime()
end
end
elseif ( event == "START_AUTOREPEAT_SPELL" ) then
self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
elseif ( event == "STOP_AUTOREPEAT_SPELL" ) then
self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
elseif ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
local caster, spell = select(1,...)
if ( self.settings.bAutoShot and caster == "player" and spell == NEEDTOKNOW.AUTO_SHOT ) then
local interval = UnitRangedDamage("player")
self.tAutoShotCD = interval
self.tAutoShotExpires = GetTime() + interval
NeedToKnow.Bar_AuraCheck(self)
end
end
end
 
-- AuraCheck calls on this to compute the "text" of the bar
-- It is separated out like this in part to be hooked by other addons
function NeedToKnow.ComputeBarText(buffName, count, extended)
local text
if ( count > 1 ) then
text = buffName.." ["..count.."]"
else
text = buffName
end
if ( extended and extended > 1 ) then
text = text .. string.format(" + %.0fs", extended)
end
return text
end
 
-- Called by NeedToKnow.UpdateVCT, which is called from AuraCheck and possibly
-- by Bar_Update depending on vct_refresh. In addition to refactoring out some
-- code from the long AuraCheck, this also provides a convenient hook for other addons
function NeedToKnow.ComputeVCTDuration(bar)
local vct_duration = 0
 
local spellToTime = bar.settings.vct_spell
if ( nil == spellToTime or "" == spellToTime ) then
spellToTime = bar.buffName
end
local _, _, _, _, _, _, castTime = GetSpellInfo(spellToTime)
 
if ( castTime ) then
vct_duration = castTime / 1000
bar.vct_refresh = true
else
bar.vct_refresh = false
end
 
if ( bar.settings.vct_extra ) then
vct_duration = vct_duration + bar.settings.vct_extra
end
return vct_duration
end
 
function NeedToKnow.UpdateVCT(bar)
local vct_duration = NeedToKnow.ComputeVCTDuration(bar)
 
local dur = bar.fixedDuration or bar.duration
if ( dur ) then
vct_width = (vct_duration * bar:GetWidth()) / dur
if (vct_width > bar:GetWidth()) then
vct_width = bar:GetWidth()
end
else
vct_width = 0
end
 
if ( vct_width > 1 ) then
bar.vct:SetWidth(vct_width)
bar.vct:Show()
else
bar.vct:Hide()
end
end
 
function NeedToKnow.SizeBackground(bar, i_show_icon)
local background = _G[bar:GetName() .. "Background"]
local bgWidth = bar:GetWidth() + 2*NeedToKnow_Settings["BarPadding"]
local y = NeedToKnow_Settings["BarPadding"]
local x = -y
background:ClearAllPoints()
 
if ( i_show_icon ) then
local iconExtra = bar:GetHeight() + NeedToKnow_Settings["BarPadding"]
bgWidth = bgWidth + iconExtra
x = x - iconExtra
end
background:SetWidth(bgWidth)
background:SetPoint("TOPLEFT", bar, "TOPLEFT", x, y)
end
 
function NeedToKnow.CreateBar2(bar)
if ( not bar.bar2 ) then
local n = bar:GetName() .. "Bar2"
bar.bar2 = bar:CreateTexture(n, "BORDER")
bar.bar2:SetPoint("TOPLEFT", bar.bar1, "TOPRIGHT")
bar.bar2:SetPoint("BOTTOM", bar, "BOTTOM")
bar.bar2:SetWidth(bar:GetWidth())
end
end
 
function NeedToKnow.ConfigureVisibleBar(bar, count, extended)
local text = ""
if ( bar.settings.show_icon and bar.iconPath and bar.icon ) then
bar.icon:SetTexture(bar.iconPath)
bar.icon:Show()
NeedToKnow.SizeBackground(bar, true)
elseif bar.icon then
bar.icon:Hide()
NeedToKnow.SizeBackground(bar, false)
end
 
bar.bar1:SetVertexColor(bar.settings.BarColor.r, bar.settings.BarColor.g, bar.settings.BarColor.b)
bar.bar1:SetAlpha(bar.settings.BarColor.a)
if ( bar.max_expirationTime and bar.max_expirationTime ~= bar.expirationTime ) then
NeedToKnow.CreateBar2(bar)
bar.bar2:SetTexture(bar.bar1:GetTexture())
bar.bar2:SetVertexColor(bar.settings.BarColor.r, bar.settings.BarColor.g, bar.settings.BarColor.b)
bar.bar2:SetAlpha(bar.settings.BarColor.a * 0.5)
bar.bar2:Show()
elseif (bar.bar2) then
bar.bar2:Hide()
end
 
local txt = ""
if ( bar.settings.show_mypip ) then
txt = txt .. "* "
end
 
if ( bar.settings.show_text ) then
local n = bar.buffName
if "" ~= bar.settings.show_text_user then
local idx=bar.idxName
if idx > #bar.spell_names then idx = #bar.spell_names end
n = bar.spell_names[idx]
end
local c = count
if not bar.settings.show_count then
c = 1
end
txt = txt .. NeedToKnow.ComputeBarText(n, c, extended)
end
if ( bar.settings.append_cd
and (bar.settings.BuffOrDebuff == "CASTCD"
or bar.settings.BuffOrDebuff == "BUFFCD") )
then
txt = txt .. " CD"
elseif (bar.settings.append_usable and bar.settings.BuffOrDebuff == "USABLE" ) then
txt = txt .. " Usable"
end
bar.text:SetText(txt)
 
-- Is this an aura with a finite duration?
local vct_width = 0
if ( bar.duration > 0 ) then
-- Configure the main status bar
local duration = bar.fixedDuration or bar.duration
bar.max_value = duration
 
-- Determine the size of the visual cast bar
if ( bar.settings.vct_enabled ) then
NeedToKnow.UpdateVCT(bar)
end
 
-- Force an update to get all the bars to the current position (sharing code)
-- This will call UpdateVCT again, but that seems ok
bar.nextUpdate = -NEEDTOKNOW.UPDATE_INTERVAL
NeedToKnow.Bar_OnUpdate(bar, 0)
 
bar.time:Show()
else
-- Hide the time text and spark for auras with "infinite" duration
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
if bar.bar2 then SetStatusBarValue(bar,bar.bar2,1) end
 
bar.time:Hide()
bar.spark:Hide()
 
if ( bar.vct ) then
bar.vct:Hide()
end
end
end
 
function NeedToKnow.ConfigureBlinkingBar(bar)
local settings = bar.settings
if ( not bar.blink ) then
bar.blink=true
bar.blink_phase=1
bar.bar1:SetVertexColor(settings.MissingBlink.r, settings.MissingBlink.g, settings.MissingBlink.b)
bar.bar1:SetAlpha(settings.MissingBlink.a)
end
bar.text:SetText(settings.blink_label)
bar.time:Hide()
bar.spark:Hide()
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
 
if ( bar.icon ) then
bar.icon:Hide()
NeedToKnow.SizeBackground(bar, false)
end
if ( bar.bar2 ) then
bar.bar2:Hide()
end
end
 
function NeedToKnow.GetUtilityTooltips()
if ( not NeedToKnow_Tooltip1 ) then
for idxTip = 1,2 do
local ttname = "NeedToKnow_Tooltip"..idxTip
local tt = CreateFrame("GameTooltip", ttname)
tt:SetOwner(UIParent, "ANCHOR_NONE")
tt.left = {}
-- Most of the tooltip lines share the same text widget,
-- But we need to query the third one for cooldown info
tt.right1 = tt:CreateFontString()
tt.right1:SetFontObject(GameFontNormal)
tt.right3 = tt:CreateFontString()
tt.right3:SetFontObject(GameFontNormal)
for i = 1, 30 do
tt.left[i] = tt:CreateFontString()
tt.left[i]:SetFontObject(GameFontNormal)
if i ~= 3 then
tt:AddFontStrings(tt.left[i], tt.right1)
else
tt:AddFontStrings(tt.left[i], tt.right3)
end
end
end
end
local tt1,tt2 = NeedToKnow_Tooltip1, NeedToKnow_Tooltip2
 
tt1:ClearLines()
tt2:ClearLines()
return tt1,tt2
end
 
function NeedToKnow.DetermineTempEnchantFromTooltip(i_invID)
local tt1,tt2 = NeedToKnow.GetUtilityTooltips()
 
tt1:SetInventoryItem("player", i_invID)
local n,h = tt1:GetItem()
 
tt2:SetHyperlink(h)
 
-- Look for green lines present in tt1 that are missing from tt2
local nLines1, nLines2 = tt1:NumLines(), tt2:NumLines()
local i1, i2 = 1,1
while ( i1 <= nLines1 ) do
local txt1 = tt1.left[i1]
if ( txt1:GetTextColor() ~= 0 ) then
i1 = i1 + 1
elseif ( i2 <= nLines2 ) then
local txt2 = tt2.left[i2]
if ( txt2:GetTextColor() ~= 0 ) then
i2 = i2 + 1
elseif (txt1:GetText() == txt2:GetText()) then
i1 = i1 + 1
i2 = i2 + 1
else
break
end
else
break
end
end
if ( i1 <= nLines1 ) then
local line = tt1.left[i1]:GetText()
local paren = line:find("[(]")
if ( paren ) then
line = line:sub(1,paren-2)
end
return line
end
end
 
 
 
-- Looks at the tooltip for the given spell to see if a cooldown
-- is listed with a duration in seconds. Longer cooldowns don't
-- need this logic, so we don't need to do unit conversion
function NeedToKnow.DetermineShortCooldownFromTooltip(spell)
if not NeedToKnow.short_cds then
NeedToKnow.short_cds = {}
end
if not NeedToKnow.short_cds[spell] then
-- Figure out what a cooldown in seconds should look like
local ref = SecondsToTime(10):lower()
local unit_ref = ref:match("10 (.+)")
 
-- Get the number and unit of the cooldown from the tooltip
local tt1 = NeedToKnow.GetUtilityTooltips()
tt1:SetHyperlink( GetSpellLink(spell) )
local cd = tt1.right3:GetText()
local n_cd, unit_cd
if cd then
cd = cd:lower()
n_cd, unit_cd = cd:match("(%d+) (.+) ")
end
 
-- unit_ref will be "|4sec:sec;" in english, so do a find rather than a ==
if not n_cd then
-- If we couldn't parse the tooltip, assume there's no cd
NeedToKnow.short_cds[spell] = 0
elseif unit_ref:find(unit_cd) then
NeedToKnow.short_cds[spell] = tonumber(n_cd)
else
-- Not a short cooldown. Record it as a minute
NeedToKnow.short_cds[spell] = 60
end
end
 
return NeedToKnow.short_cds[spell]
end
 
 
-- Called whenever the state of auras on the bar's unit may have changed
function NeedToKnow.Bar_AuraCheck(bar)
local buffName, count, duration, expirationTime, caster, iconPath
local idxName = 0
local all_stacks
local settings = bar.settings
local bUnitExists, isWeapon
if ( settings.BuffOrDebuff == "CASTCD" or
settings.BuffOrDebuff == "BUFFCD" or
settings.BuffOrDebuff == "USABLE" or
settings.BuffOrDebuff == "TOTEM" )
then
bUnitExists = true
else
if ( "mhand" == settings.Unit or
"ohand" == settings.Unit )
then
isWeapon = true
bUnitExists = true
else
bUnitExists = UnitExists(bar.unit)
end
end
 
-- Determine if the bar should be showing anything
if ( bUnitExists ) then
 
local mainHandEnchantName, mainHandEnchantRank, offHandEnchantName, offHandEnchantRank
local hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges
if ( isWeapon ) then
hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges = GetWeaponEnchantInfo()
if ( hasMainHandEnchant and "mhand" == settings.Unit ) then
mainHandEnchantName, mainHandEnchantRank = NeedToKnow.DetermineTempEnchantFromTooltip(16)
end
if ( hasOffHandEnchant and "ohand" == settings.Unit ) then
offHandEnchantName, offHandEnchantRank = NeedToKnow.DetermineTempEnchantFromTooltip(17)
end
end
 
for idx, barSpell in ipairs(bar.spells) do
idxName = idx
local filter = settings.BuffOrDebuff
local _, nDigits = barSpell:find("^%d+")
local isSpellID = ( nDigits == barSpell:len() )
 
if ( settings.BuffOrDebuff == "TOTEM" ) then
local spellName, spellRank, spellIconPath
if ( isSpellID ) then
spellName, spellRank, spellIconPath = GetSpellInfo(barSpell)
end
for iSlot=1, 4 do
local haveTotem, totemName, startTime, totemDuration, totemIcon = GetTotemInfo(iSlot)
local sComp = barSpell
if isSpellID then sComp = spellName end
if ( totemName and totemName:find(sComp) ) then
-- WORKAROUND: The startTime reported here is both cast to an int and off by
-- a latency meaning it can be significantly low. So we cache the GetTime
-- that the totem actually appeared, so long as GetTime is reasonably close to
-- startTime (since the totems may have been out for awhile before this runs.)
if ( not NeedToKnow.totem_drops[iSlot] or
NeedToKnow.totem_drops[iSlot] < startTime )
then
local precise = GetTime()
if ( precise - startTime > 1 ) then
precise = startTime + 1
end
NeedToKnow.totem_drops[iSlot] = precise
end
buffName = totemName
duration = totemDuration
expirationTime = NeedToKnow.totem_drops[iSlot] + duration
iconPath = totemIcon
count = 1
caster = "player"
break
end
end
elseif isWeapon then
if ( "mhand" == settings.Unit and mainHandEnchantName and mainHandEnchantName:find(barSpell) ) then
buffName = mainHandEnchantName
count = mainHandCharges
if ( count < 1 ) then count = 1 end
duration = 1800
expirationTime = GetTime() + mainHandExpiration/1000
caster = "player"
elseif ( "ohand" == settings.Unit and offHandEnchantName and offHandEnchantName:find(barSpell) ) then
buffName = offHandEnchantName
count = offHandCharges
if ( not count or count < 1 ) then count = 1 end
duration = 1800
expirationTime = GetTime() + offHandExpiration/1000
caster = "player"
end
elseif settings.BuffOrDebuff == "CASTCD" then
local spellName=barSpell, spellRank, spellIconPath
local spellPower=0
if isSpellID or NeedToKnow.is_DK then
spellName, spellRank, spellIconPath, _, _, spellPower = GetSpellInfo(barSpell)
end
if ( settings.bAutoShot and (barSpell == "Auto Shot" or barSpell == NEEDTOKNOW.AUTO_SHOT or barSpell == "75") ) then
local tNow = GetTime()
if ( bar.tAutoShotExpires and bar.tAutoShotExpires > tNow ) then
buffName = NEEDTOKNOW.AUTO_SHOT
count = 1
duration = bar.tAutoShotCD
expirationTime = bar.tAutoShotExpires
caster = "player"
end
else
local tNow = GetTime()
local start, cd_len, should_cooldown = GetSpellCooldown(barSpell)
local is_spell = true
if not start then
start, cd_len = GetItemCooldown(barSpell)
is_spell = false
end
 
if is_spell and start and start > 0 then
if 0 == should_cooldown then
-- Filter out conditions like Stealth while stealthed
start = nil
elseif spellPower == 5 then -- Rune
-- Filter out rune cooldown artificially extending the cd
if cd_len <= 10 then
if bar.expirationTime and tNow < bar.expirationTime then
-- We've already seen the correct CD for this; keep using it
start = bar.expirationTime - bar.duration
cd_len = bar.duration
elseif NeedToKnow.last_sent and NeedToKnow.last_sent[barSpell] and NeedToKnow.last_sent[barSpell] > (tNow - 1.5) then
-- We think the spell was just cast, and a CD just started but it's short.
-- Look at the tooltip to tell what the correct CD should be. If it's supposed
-- to be short (Ghoul Frenzy, Howling Blast), then start a CD bar
cd_len = NeedToKnow.DetermineShortCooldownFromTooltip(barSpell)
if cd_len == 0 or cd_len > 10 then
start = nil
end
else
start = nil
end
end
end
end
 
-- filter out the GCD, we only care about actual spell CDs
if cd_len <= 1.5 then
if not bar.expirationTime or bar.expirationTime < tNow then
start = nil
else
start = bar.expirationTime - bar.duration
cd_len = bar.duration
end
end
 
if start and cd_len then
local tEnd = start + cd_len
if ( tEnd > tNow + 0.1 ) then
if is_spell then
buffName, _, iconPath = GetSpellInfo(barSpell)
else
buffName, _, _, _, _, _, _, _, _, iconPath = GetItemInfo(barSpell)
end
if not buffName then buffName = barSpell end
 
count = 1
duration = cd_len
expirationTime = tEnd
cast = "player"
end
end
end
elseif settings.BuffOrDebuff == "USABLE" then
local _, nDigits = barSpell:find("^%d+")
local isSpellID = ( nDigits == barSpell:len() )
local key = barSpell
if ( isSpellID ) then key = tonumber(barSpell) end
if ( not key ) then key = "" end
local spellName
spellName, _, iconPath = GetSpellInfo(key)
if ( spellName ) then
local isUsable, notEnoughMana = IsUsableSpell(spellName)
if (isUsable or notEnoughMana) then
duration = settings.usable_duration
buffName = spellName
count = 1
local tNow = GetTime()
if ( not bar.expirationTime or
(bar.expirationTime > 0 and bar.expirationTime < tNow - 0.01) )
then
duration = settings.usable_duration
expirationTime = tNow + duration
else
duration = bar.duration
expirationTime = bar.expirationTime
end
end
end
else
if settings.OnlyMine then
filter = filter .. "|PLAYER"
end
 
if isSpellID then
-- WORKAROUND: The second parameter to UnitAura can't be a spellid, so I have
-- to walk them all
local barID = tonumber(barSpell)
local j = 1
while true do
local buffRank, spellID
buffName, buffRank, iconPath, count, _, duration, expirationTime, caster, _, _, spellID = UnitAura(bar.unit, j, filter)
if (not buffName) then
break
end
 
if (spellID == barID) then
break
else
duration = nil
end
j=j+1
end
else
buffName, _ , iconPath, count, _, duration, expirationTime, caster = UnitAura(bar.unit, barSpell, nil, filter)
end
end
 
if ( duration ) then
if not count or count < 1 then
count = 1
end
 
if ( settings.show_all_stacks ) then
if ( not all_stacks ) then
all_stacks =
{
min =
{
buffName = "",
duration = 0,
expirationTime = 0,
iconPath = "",
caster = ""
},
max =
{
duration = 0,
expirationTime = 0,
},
total = 0
}
end
 
all_stacks.total = all_stacks.total + count
if ( 0 == all_stacks.min.expirationTime or all_stacks.min.expirationTime > expirationTime ) then
all_stacks.min.idxName = idxName
all_stacks.min.buffName = buffName
all_stacks.min.caster = caster
all_stacks.min.duration = duration
all_stacks.min.expirationTime = expirationTime
all_stacks.min.iconPath = iconPath
end
if ( 0 == all_stacks.max.expirationTime or all_stacks.max.expirationTime < expirationTime ) then
all_stacks.max.duration = duration
all_stacks.max.expirationTime = expirationTime
end
else
break
end
end
end
end
 
if ( all_stacks ) then
idxName = all_stacks.min.idxName
buffName = all_stacks.min.buffName
caster = all_stacks.min.caster
duration = all_stacks.max.duration
expirationTime = all_stacks.min.expirationTime
iconPath = all_stacks.min.iconPath
count = all_stacks.total
end
 
-- There is an aura this bar is watching! Set it up
duration = tonumber(duration)
if ( settings.BuffOrDebuff == "BUFFCD" ) then
local tNow = GetTime()
count = 1 -- Seeing the charges on the CD bar violated least surprise for me
if ( duration ) then
local tStart = expirationTime - duration
duration = tonumber(settings.buffcd_duration)
expirationTime = tStart + duration
if ( expirationTime <= tNow ) then
duration = nil
end
elseif ( bar.expirationTime and bar.expirationTime > tNow + 0.1 ) then
duration = bar.duration
expirationTime = bar.expirationTime
buffName = bar.buffName
iconPath = bar.iconPath
end
end
 
if ( duration ) then
-- Handle duration increases
local extended
if (settings.bDetectExtends) then
local curStart = expirationTime - duration
local guidTarget = UnitGUID(bar.unit)
if ( not NeedToKnow.last_cast[buffName] ) then
NeedToKnow.last_cast[buffName] = { state=0 }
end
local r = NeedToKnow.last_cast[buffName]
 
if ( not r[guidTarget] ) then
r[guidTarget] = { time=curStart, dur=duration }
elseif ( r[guidTarget].dur == 0 ) then
r[guidTarget].dur = duration
else
local rStart = r[guidTarget]
extended = expirationTime - rStart.time - rStart.dur
if ( extended > 1 ) then
duration = rStart.dur
end
end
end
 
--bar.duration = tonumber(bar.fixedDuration) or duration
bar.duration = duration
 
bar.expirationTime = expirationTime
bar.idxName = idxName
bar.buffName = buffName
bar.iconPath = iconPath
if ( all_stacks and all_stacks.max.expirationTime ~= expirationTime ) then
bar.max_expirationTime = all_stacks.max.expirationTime
else
bar.max_expirationTime = nil
end
 
-- Mark the bar as not blinking before calling ConfigureVisibleBar,
-- since it calls OnUpdate which checks bar.blink
bar.blink=false
NeedToKnow.ConfigureVisibleBar(bar, count, extended)
bar:Show()
else
if (settings.bDetectExtends and bar.buffName) then
if ( NeedToKnow.last_cast[bar.buffName] ) then
local guidTarget = UnitGUID(bar.unit)
if guidTarget then
local r = NeedToKnow.last_cast[bar.buffName]
r[guidTarget] = nil
end
end
end
bar.buffName = nil
bar.duration = nil
bar.expirationTime = nil
 
local bBlink = false
if settings.blink_enabled and settings.MissingBlink.a > 0 and bUnitExists and not UnitIsDead(bar.unit) then
bBlink = (bar.unit == "player") or
(settings.BuffOrDebuff == "HELPFUL") == (nil ~= UnitIsFriend("player", bar.unit))
end
if ( bBlink and not settings.blink_ooc ) then
if not UnitAffectingCombat("player") then
bBlink = false
end
end
if ( bBlink and settings.blink_boss ) then
local lvl = UnitLevel(bar.unit)
if not lvl or lvl > 0 then
bBlink = false
end
end
if ( bBlink ) then
NeedToKnow.ConfigureBlinkingBar(bar)
bar:Show()
else
bar.blink=false
bar:Hide()
end
end
end
 
function NeedToKnow.Fmt_SingleUnit(i_fSeconds)
return string.format(SecondsToTimeAbbrev(i_fSeconds))
end
 
function NeedToKnow.Fmt_TwoUnits(i_fSeconds)
if ( i_fSeconds < 6040 ) then
local nMinutes, nSeconds
nMinutes = floor(i_fSeconds / 60)
nSeconds = floor(i_fSeconds - nMinutes*60)
return string.format("%02d:%02d", nMinutes, nSeconds)
else
string.format(SecondsToTimeAbbrev(i_fSeconds))
end
end
 
function NeedToKnow.Fmt_Float(i_fSeconds)
return string.format("%0.1f", i_fSeconds)
end
 
function NeedToKnow.Bar_OnUpdate(self, elapsed)
local now = GetTime()
if ( now > self.nextUpdate ) then
self.nextUpdate = now + NEEDTOKNOW.UPDATE_INTERVAL
 
if ( self.blink ) then
self.blink_phase = self.blink_phase + NEEDTOKNOW.UPDATE_INTERVAL
if ( self.blink_phase >= 2 ) then
self.blink_phase = 0
end
local a = self.blink_phase
if ( a > 1 ) then
a = 2 - a
end
 
self.bar1:SetVertexColor(self.settings.MissingBlink.r, self.settings.MissingBlink.g, self.settings.MissingBlink.b)
self.bar1:SetAlpha(self.settings.MissingBlink.a * a)
return
end
 
-- WORKAROUND: Although the existence of the enchant is correct at UNIT_INVENTORY_CHANGED
-- the expiry time is not yet correct. So we update the expiration every update :(
local origUnit = self.settings.Unit
if ( origUnit == "mhand" ) then
-- The expiry time doesn't update right away, so we have to poll it
local mhEnchant, mhExpire = GetWeaponEnchantInfo()
if ( mhExpire ) then
self.expirationTime = GetTime() + mhExpire/1000
end
elseif ( origUnit == "ohand" ) then
local _, _, _, ohEnchant, ohExpire = GetWeaponEnchantInfo()
if ( ohExpire ) then
self.expirationTime = GetTime() + ohExpire/1000
end
end
 
if ( self.duration > 0 ) then
local duration = self.fixedDuration or self.duration
local bar1_timeLeft = self.expirationTime - GetTime()
if ( bar1_timeLeft < 0 ) then
if ( self.settings.BuffOrDebuff == "CASTCD" or
self.settings.BuffOrDebuff == "BUFFCD" )
then
NeedToKnow.Bar_AuraCheck(self)
return
end
bar1_timeLeft = 0
end
SetStatusBarValue(self, self.bar1, bar1_timeLeft);
if ( self.settings.show_time ) then
local fn = NeedToKnow[self.settings.TimeFormat]
local oldText = self.time:GetText()
local newText
if ( fn ) then
newText = fn(bar1_timeLeft)
else
newText = string.format(SecondsToTimeAbbrev(bar1_timeLeft))
end
 
if ( newText ~= oldText ) then
self.time:SetText(newText)
end
else
self.time:SetText("")
end
 
if ( self.settings.show_spark and bar1_timeLeft <= duration ) then
self.spark:SetPoint("CENTER", self, "LEFT", self:GetWidth()*bar1_timeLeft/duration, 0)
self.spark:Show()
else
self.spark:Hide()
end
 
if ( self.max_expirationTime ) then
local bar2_timeLeft = self.max_expirationTime - GetTime()
SetStatusBarValue(self, self.bar2, bar2_timeLeft, bar1_timeLeft)
end
 
if ( self.vct_refresh ) then
NeedToKnow.UpdateVCT(self)
end
end
end
end
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/NeedToKnow.toc New file
0,0 → 1,16
## Interface: 30300
## X-Compatible-With: 40000
## Title: NeedToKnow
## Author: Kitjan, lieandswell
## Version: 3.1.7
## Notes: Timer bars for buffs, debuffs, cooldowns, etc.
## X-Credits: Bilt, Fxfighter EU-Echsenkessel, metalchoir, sp00n, Vlakarados, wowui.cn
## X-Category: Buffs, Combat
## OptionalDeps: LibStub,LibSharedMedia-3.0
## DefaultState: enabled
## SavedVariablesPerCharacter: NeedToKnow_Settings
libs\LibStub\LibStub.lua
libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
libs\LibSharedMedia-3.0\lib.xml
NeedToKnow.xml
NeedToKnow_Options.xml
Property changes : Added: svn:eol-style + native
Kitjan/NeedToKnow/NeedToKnow/Textures/Armory.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Smooth.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Striped.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Resize.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Smoothv2.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Glaze.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Graphite.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Otravi.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/DarkBottom.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Default.blp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Flat.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Minimalist.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Aluminum.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/Gloss.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow/Textures/BantoBar.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
Kitjan/NeedToKnow/NeedToKnow Property changes : Added: svn:mergeinfo Merged /branches/Kitjan/NeedToKnow:r58-60 Merged /branches/lieandswell/NeedToKnow:r60-63