Quantcast
WoWInterface: SVN - Notes - Path Comparison - / Rev 1 and / Rev 2

WoWInterface SVN Notes

Compare Revisions

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

Rev 1 → Rev 2

branches/WotLK/Notes/Notes.xml New file
0,0 → 1,1575
<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/C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
<Script file="Notes.lua"/>
<Script file="Notes_Export.lua"/>
 
<Font name="NotesSmallButtonText" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight>
<AbsValue val="9"/>
</FontHeight>
</Font>
<Font name="NotesLargeButtonText" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight>
<AbsValue val="11"/>
</FontHeight>
</Font>
 
<Button name="NotesSmallButtonTemplate" inherits="UIPanelButtonTemplate" virtual="true">
<Size>
<AbsDimension x="68" y="14"/>
</Size>
<NormalFont inherits="NotesSmallButtonText"/>
<PushedFont inherits="NotesSmallButtonText"/>
<HighlightFont inherits="NotesSmallButtonText"/>
<DisabledFont inherits="NotesSmallButtonText"/>
</Button>
<Button name="NotesLargeButtonTemplate" inherits="UIPanelButtonTemplate" virtual="true">
<Size>
<AbsDimension x="122" y="18"/>
</Size>
<NormalFont inherits="NotesLargeButtonText"/>
<PushedFont inherits="NotesLargeButtonText"/>
<HighlightFont inherits="NotesLargeButtonText"/>
<DisabledFont inherits="NotesLargeButtonText"/>
</Button>
<CheckButton name="NotesCheckButtonTemplate" inherits="OptionsCheckButtonTemplate" checked="false" virtual="true">
<Size>
<AbsDimension x="15" y="15"/>
</Size>
</CheckButton>
 
<Button name="PrevPageButtonTemplate" virtual="true">
<Size>
<AbsDimension x="25" y="25"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="$parentText" inherits="GameFontNormalSmall" justifyH="LEFT" text="PREV">
<Anchors>
<Anchor point="LEFT" relativePoint="RIGHT"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<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="NextPageButtonTemplate" virtual="true">
<Size>
<AbsDimension x="25" y="25"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="$parentText" inherits="GameFontNormalSmall" justifyH="RIGHT" text="NEXT">
<Anchors>
<Anchor point="RIGHT" relativePoint="LEFT"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<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>
<Button name="CommButtonTemplate" virtual="true">
<Size>
<AbsDimension x="22" y="22"/>
</Size>
<NormalTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Down"/>
<PushedTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Down"/>
<DisabledTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Disabled"/>
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
</Button>
 
<Button name="NotesIconFrame" frameStrata="MEDIUM" parent="Minimap" enableMouse="true" movable="true" hidden="false">
<Size>
<AbsDimension x="33" y="33"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="-15" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture name="NotesIconFrame_Icon" file="Interface\Icons\INV_Misc_Book_09">
<Size>
<AbsDimension x="19" y="19"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="7" y="-6"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0.075" right="0.925" top="0.075" bottom="0.925"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<Texture name="NotesIconFrame_Border" file="Interface\Minimap\MiniMap-TrackingBorder">
<Size>
<AbsDimension x="56" y="56"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT"/>
</Anchors>
</Texture>
</Layer>
</Layers>
<HighlightTexture alphaMode="ADD" file="Interface\Minimap\UI-Minimap-ZoomButton-Highlight"/>
<Scripts>
<OnLoad>
this:RegisterForClicks("LeftButtonUp","RightButtonUp")
this:RegisterForDrag("LeftButton")
</OnLoad>
<OnEnter>
GameTooltip:SetOwner(NotesIconFrame,"ANCHOR_LEFT")
GameTooltip:ClearLines()
GameTooltip:AddLine("Notes")
GameTooltip:AddLine("Version: 1.4",.5,.5,.5)
 
GameTooltip:AddLine("Click: Toggle UI",.8,.8,.8,1)
GameTooltip:AddLine("Drag: Move button",.8,.8,.8,1)
GameTooltip:Show()
</OnEnter>
<OnMouseDown>
NotesIconFrame_Icon:SetTexCoord(0,1,0,1)
</OnMouseDown>
<OnMouseUp>
NotesIconFrame_Icon:SetTexCoord(.075,.925,.075,.925)
</OnMouseUp>
<OnLeave>
GameTooltip_SetDefaultAnchor(GameTooltip,UIParent)
GameTooltip:Hide()
</OnLeave>
<OnDragStart>
this:LockHighlight()
Notes_IconDrag = true
</OnDragStart>
<OnDragStop>
this:UnlockHighlight()
Notes_IconDrag = false
NotesIconFrame_Icon:SetTexCoord(.075,.925,.075,.925)
</OnDragStop>
<OnClick>
Notes_UIToggle()
NotesIconFrame_Icon:SetTexCoord(.075,.925,.075,.925)
</OnClick>
<OnUpdate>
Notes_IconMove()
</OnUpdate>
</Scripts>
</Button>
<Button name="NotesNoteTemplate" virtual="true">
<Size>
<AbsDimension x="295" y="16"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="$parent_Text" inherits="GameFontNormal" wraponspaces="false" justifyH="LEFT" text="entry" width="15"/>
<FontString name="$parent_Description" inherits="GameFontDisableSmall" wraponspaces="false" justifyH="RIGHT" text="decription"/>
</Layer>
<Layer level="OVERLAY">
<Texture name="$parent_BookIcon" hidden="true" alphaMode="ADD">
<Size>
<AbsDimension x="15" y="15"/>
</Size>
<Anchors>
<Anchor point="LEFT">
<Offset>
<AbsDimension x="1" y="0"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0.075" right="0.925" top="0.075" bottom="0.925"/>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnClick>
Notes_ToggleSelected(this:GetName());
</OnClick>
<OnEnter>
getglobal(this:GetName().."_Text"):SetTextColor(1,1,1);
</OnEnter>
<OnLeave>
local setcolor = Notes_GetColor(this:GetName())
getglobal(this:GetName().."_Text"):SetTextColor(setcolor[1],setcolor[2],setcolor[3]);
</OnLeave>
</Scripts>
<NormalTexture name="$parentNTex" file="Interface\QuestFrame\UI-QuestTitleHighlight"/>
<PushedTexture file="Interface\QuestFrame\UI-QuestTitleHighlight"/>
</Button>
 
<Button name="NotesTOCTemplate" virtual="true">
<Size>
<AbsDimension x="290" y="14"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="$parent_Text" inherits="GameFontBlack" wraponspaces="false" justifyH="LEFT" text="Page X) LUA - Some Script Here" width="15"/>
</Layer>
</Layers>
<Scripts>
<OnClick>
Notes_ToggleTOCSelected(this:GetName());
</OnClick>
<OnEnter>
getglobal(this:GetName().."_Text"):SetTextColor(0,0,0,.5);
getglobal(this:GetName().."_Text"):SetShadowColor(0,0,0,.1);
</OnEnter>
<OnLeave>
getglobal(this:GetName().."_Text"):SetTextColor(0,0,0,1);
getglobal(this:GetName().."_Text"):SetShadowColor(0,0,0,0);
</OnLeave>
<OnLoad>
getglobal(this:GetName().."_Text"):SetTextColor(0,0,0,1);
getglobal(this:GetName().."_Text"):SetShadowColor(0,0,0,0);
</OnLoad>
</Scripts>
</Button>
 
 
 
 
 
 
 
<Frame name="NotesNoteScrollTemplate" enableMouse="true" virtual="true">
<Size>
<AbsDimension x="310" y="110.5"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="15" y="-169.5"/>
</Offset>
</Anchor>
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<BackgroundInsets>
<AbsInset left="4" right="4" top="4" bottom="4" />
</BackgroundInsets>
<TileSize>
<AbsValue val="16" />
</TileSize>
<EdgeSize>
<AbsValue val="16" />
</EdgeSize>
</Backdrop>
<Scripts>
<OnShow>
Notes_PrepUndo()
Notes_FixHiddenPages()
Notes_SortNotes()
Notes_ScrollBarUpdate()
</OnShow>
</Scripts>
<Frames>
<ScrollFrame name="$parentNoteScrollBar" inherits="FauxScrollFrameTemplate" hidden="true">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="0" y="-8"/>
</Offset>
</Anchor>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-5.5" y="8"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnVerticalScroll>
FauxScrollFrame_OnVerticalScroll(16, Notes_ScrollBarUpdate);
</OnVerticalScroll>
<OnShow>
Notes_ScrollBarUpdate()
</OnShow>
</Scripts>
</ScrollFrame>
 
<Button name="$parentNote1" inherits="NotesNoteTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNoteScrollBar" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="8" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Button>
<Button name="$parentNote2" inherits="NotesNoteTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNote1" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="$parentNote3" inherits="NotesNoteTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNote2" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="$parentNote4" inherits="NotesNoteTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNote3" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="$parentNote5" inherits="NotesNoteTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNote4" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
 
</Frames>
</Frame>
 
 
<ScrollFrame name="NotesScrollTextFrameTemplate" inherits="UIPanelScrollFrameTemplate" virtual="true">
<Size>
<AbsDimension x="310" y="259"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="9.5" y="-96"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="$parentTop" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
<Size>
<AbsDimension x="30" y="50"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="$parentScrollBarScrollUpButton">
<Offset>
<AbsDimension x="0" y="5"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="1" right="1" top="1" bottom="1"/>
</Texture>
<Texture file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
<Size>
<AbsDimension x="31" y="0"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativeTo="$parentScrollBarScrollDownButton">
<Offset>
<AbsDimension x="50" y="-2"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="1" right="1" top="1" bottom="1"/>
</Texture>
</Layer>
</Layers>
<ScrollChild>
<Frame enableMouse="true">
<Size>
<AbsDimension x="300" y="200"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Frames>
<EditBox name="NotesTextEditBox" letters="7500" multiLine="true" enableMouse="true" autoFocus="false">
<Size>
<AbsDimension x="290" y="200"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="15" y="-5"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnEscapePressed>
this:ClearFocus()
</OnEscapePressed>
<OnTextChanged>
local scrollBar = getglobal(this:GetParent():GetParent():GetName().."ScrollBar")
this:GetParent():GetParent():UpdateScrollChildRect();
local min;
local max;
min, max = scrollBar:GetMinMaxValues();
 
if ( max > 0 and (this.max ~= max) and 13 > max-NotesText:GetVerticalScroll()) then
this.max = max;
scrollBar:SetValue(max);
end
Notes_SaveNote()
</OnTextChanged>
<OnClick>
this:SetFocus();
</OnClick>
</Scripts>
<FontString inherits="GameFontBlack"/>
</EditBox>
</Frames>
<Scripts>
<OnMouseUp>
NotesTextEditBox:SetFocus();
</OnMouseUp>
</Scripts>
</Frame>
</ScrollChild>
</ScrollFrame>
 
 
<Frame name="NotesTOCScrollTemplate" enableMouse="true" virtual="true">
<Size>
<AbsDimension x="310" y="275"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTitleEditFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-52.5" y="6"/>
</Offset>
</Anchor>
</Anchors>
<Frames>
<ScrollFrame name="NotesTOCScrollBar" inherits="FauxScrollFrameTemplate" hidden="true">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="0" y="-6"/>
</Offset>
</Anchor>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-7" y="10"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnVerticalScroll>
FauxScrollFrame_OnVerticalScroll(16, Notes_TOCScrollBarUpdate);
</OnVerticalScroll>
<OnShow>
Notes_TOCScrollBarUpdate()
</OnShow>
</Scripts>
</ScrollFrame>
 
<Button name="NotesTOCTitle" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOCScrollBar" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="8" y="-2"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."_Text"):SetText("[SOME BOOK] - Table of Contents");
</OnLoad>
<OnClick>
</OnClick>
<OnEnter>
</OnEnter>
</Scripts>
</Button>
 
<Button name="NotesTOCBlank" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOCTitle" relativePoint="BOTTOMLEFT"/>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."_Text"):SetText("");
</OnLoad>
<OnClick>
</OnClick>
<OnEnter>
</OnEnter>
</Scripts>
</Button>
 
<Button name="NotesTOC1" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOCBlank" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC2" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC1" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC3" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC2" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC4" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC3" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC5" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC4" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC6" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC5" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC7" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC6" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC8" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC7" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC9" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC8" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC10" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC9" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC11" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC10" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC12" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC11" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC13" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC12" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC14" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC13" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC15" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC14" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
<Button name="NotesTOC16" inherits="NotesTOCTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesTOC15" relativePoint="BOTTOMLEFT"/>
</Anchors>
</Button>
</Frames>
</Frame>
 
 
<Frame name="NotesFrameTemplate" virtual="true">
<Size>
<AbsDimension x="384" y="512"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="0" y="-104"/>
</Offset>
</Anchor>
</Anchors>
<HitRectInsets>
<AbsInset left="0" right="35" top="0" bottom="75"/>
</HitRectInsets>
<Layers>
<Layer level="BACKGROUND">
<Texture file="Interface\Spellbook\Spellbook-Icon">
<Size>
<AbsDimension x="58" y="58"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="8" y="-8"/>
</Offset>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level="BORDER">
<Texture file="Interface\QuestFrame\UI-QuestLog-TopLeft">
<Size>
<AbsDimension x="256" y="256"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT"/>
</Anchors>
</Texture>
<Texture file="Interface\QuestFrame\UI-QuestLog-TopRight">
<Size>
<AbsDimension x="128" y="256"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT"/>
</Anchors>
</Texture>
<Texture file="Interface\QuestFrame\UI-QuestLog-BotLeft">
<Size>
<AbsDimension x="256" y="256"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Texture>
<Texture file="Interface\QuestFrame\UI-QuestLog-BotRight">
<Size>
<AbsDimension x="128" y="256"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Texture>
<FontString name="$parentTitleText" inherits="GameFontHighlight" text="Notes">
<Size>
<AbsDimension x="300" y="15"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="$parent" relativePoint="TOP">
<Offset>
<AbsDimension x="-10" y="-17"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="NotesCloseButton" inherits="UIPanelCloseButton">
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="-30" y="-8"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_UIToggle()
</OnClick>
</Scripts>
</Button>
<CheckButton name="NotesIconCheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="true">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Map Button")
</OnLoad>
<OnClick>
Notes_IconToggle()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="60" y="-2"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
 
 
 
<Button name="NotesDeleteButton" inherits="NotesSmallButtonTemplate" text="Delete">
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="-38" y="-36"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_DeleteAndRebuild()
</OnClick>
</Scripts>
</Button>
<Button name="NotesDuplicateButton" inherits="NotesSmallButtonTemplate" text="Duplicate">
<Anchors>
<Anchor point="RIGHT" relativeTo="NotesDeleteButton" relativePoint="LEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_CopySelected();
</OnClick>
</Scripts>
</Button>
<Button name="NotesCompileButton" inherits="NotesSmallButtonTemplate" text="Compile">
<Anchors>
<Anchor point="RIGHT" relativeTo="NotesDuplicateButton" relativePoint="LEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_CompileOrExtractSelected();
</OnClick>
</Scripts>
</Button>
<Button name="NotesNewButton" inherits="NotesSmallButtonTemplate" text="New Note">
<Anchors>
<Anchor point="RIGHT" relativeTo="NotesCompileButton" relativePoint="LEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_NewNote();
</OnClick>
</Scripts>
</Button>
 
<CheckButton name="NotesSyncCheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="false">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Sync")
</OnLoad>
<OnClick>
Notes_SyncSelected()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesNewButton" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="2"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
<CheckButton name="NotesLockedCheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="false">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Locked")
</OnLoad>
<OnClick>
Notes_LockedSelected()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOP" relativeTo="NotesSyncCheckButton" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="0" y="4"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
 
<CheckButton name="NotesLUACheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="false">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("LUA Mode")
</OnLoad>
<OnClick>
Notes_LUAUIToggle()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOPRIGHT" relativeTo="NotesDeleteButton" relativePoint="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-70" y="2"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
 
<Button name="NotesStopPrintButton" inherits="NotesLargeButtonTemplate" text="Stop Printing">
<Size>
<AbsDimension x="104" y="18"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="18" y="56"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_StopPrinting();
</OnClick>
</Scripts>
</Button>
<Button name="NotesCommButton" inherits="CommButtonTemplate" virtual="true">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesStopPrintButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-4" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_CommUIToggle()
</OnClick>
</Scripts>
</Button>
 
<Button name="NotesUndoButton" inherits="NotesLargeButtonTemplate" text="Undo Changes">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesCommButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="1" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_RevertSelected()
</OnClick>
</Scripts>
</Button>
<Button name="NotesExitButton" inherits="NotesLargeButtonTemplate" text="Exit">
<Size>
<AbsDimension x="77" y="18"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesUndoButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="1" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_UIToggle()
</OnClick>
</Scripts>
</Button>
</Frames>
</Frame>
 
 
<Frame name="NotesTitleEditBoxTemplate" enableMouse="true" virtual="true">
<Size>
<AbsDimension x="250" y="20"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="-65" y="-259"/>
</Offset>
</Anchor>
</Anchors>
<Frames>
<EditBox name="NotesTitleEditBox" letters="80" autoFocus="false">
<Size>
<AbsDimension x="250" y="20"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT"/>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="NotesTitleGroupBorderLeft" file="Interface\ChatFrame\UI-ChatInputBorder-Left">
<Size>
<AbsDimension x="60" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT">
<Offset>
<AbsDimension x="-60" y="0"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0" right="0.2" top="0" bottom="1.0"/>
</Texture>
<Texture name="NotesTitleGroupBorderMid" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
<Size>
<AbsDimension x="200" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesTitleGroupBorderLeft" relativePoint="RIGHT"/>
</Anchors>
<TexCoords left="0.4" right=".6" top="0" bottom="1.0"/>
</Texture>
<Texture name="NotesTitleGroupBorderRight" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
<Size>
<AbsDimension x="55" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesTitleGroupBorderMid" relativePoint="RIGHT"/>
</Anchors>
<TexCoords left="0.8" right="1.0" top="0" bottom="1.0"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<FontString inherits="GameFontNormal" text="Title: " justifyH="LEFT">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesTitleGroupBorderLeft">
<Offset>
<AbsDimension x="20" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<FontString inherits="ChatFontNormal"></FontString>
<Scripts>
<OnClick>
this:SetFocus();
</OnClick>
<OnEnterPressed>
NotesTextEditBox:SetFocus();
</OnEnterPressed>
<OnTabPressed>
NotesTextEditBox:SetFocus();
</OnTabPressed>
<OnEscapePressed>
this:ClearFocus()
</OnEscapePressed>
<OnTextChanged>
Notes_SaveNote()
</OnTextChanged>
<OnMouseUp>
NotesTitleEditBox:SetFocus();
</OnMouseUp>
</Scripts>
</EditBox>
</Frames>
</Frame>
 
 
<Frame name="NotesLuaFrameTemplate" enableMouse="true" virtual="true" hidden="true">
<Size>
<AbsDimension x="330" y="46"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesBGFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="16" y="56"/>
</Offset>
</Anchor>
</Anchors>
<Backdrop bgFile="Interface\TutorialFrame\TutorialFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="32"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Frames>
<Button name="NotesExecuteButton" inherits="NotesLargeButtonTemplate" text="Run LUA">
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="5" y="6"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_ExecuteSelected();
</OnClick>
</Scripts>
</Button>
<Button name="NotesLUASetupButton" inherits="NotesLargeButtonTemplate" text="Add LUA Book">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesExecuteButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-2" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_AddLUASetupNote();
</OnClick>
</Scripts>
</Button>
<Button name="NotesLUACloseButton" inherits="NotesLargeButtonTemplate" text="Exit LUA">
<Size>
<AbsDimension x="77" y="18"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesLUASetupButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-1" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_LUAUIToggle("hide")
</OnClick>
</Scripts>
</Button>
<EditBox name="NotesMacroEditBox" letters="40" virtual="true" enableMouse="true" autoFocus="false" hidden="true">
<Size>
<AbsDimension x="300" y="20"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="55" y="23"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString inherits="GameFontNormal" text="Macro: " justifyH="LEFT">
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="-45" y="5"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<FontString inherits="GameFontHighlightSmall"/>
<Scripts>
<OnTextChanged>
this:ClearFocus()
Notes_SetButtonState()
</OnTextChanged>
<OnClick>
this:SetFocus();
</OnClick>
<OnEnterPressed>
this:ClearFocus();
</OnEnterPressed>
<OnEscapePressed>
this:ClearFocus();
</OnEscapePressed>
</Scripts>
</EditBox>
</Frames>
</Frame>
 
<Frame name="NotesBookFrameTemplate" enableMouse="true" virtual="true" hidden="true">
<Size>
<AbsDimension x="330" y="32"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesBGFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="16" y="55"/>
</Offset>
</Anchor>
</Anchors>
<Backdrop bgFile="Interface\TutorialFrame\TutorialFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="32"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Frames>
<Button name="NotesPrevPageButton" inherits="PrevPageButtonTemplate" virtual="true">
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="3" y="3"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_LoadPrevPage();
</OnClick>
</Scripts>
</Button>
<Button name="NotesNextPageButton" inherits="NextPageButtonTemplate" virtual="true">
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-3" y="3"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_LoadNextPage();
</OnClick>
</Scripts>
</Button>
<Button name="NotesGoPageButton" inherits="NotesSmallButtonTemplate" text="Index">
<Size>
<AbsDimension x="57" y="18"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="54" y="7"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
if NotesTOC:IsVisible() then
Notes_GoToPage(NotesCurPageNumText:GetNumber())
else
Notes_GoToPage(0)
end
</OnClick>
</Scripts>
</Button>
 
<Button name="NotesReorderPageButton" inherits="NotesSmallButtonTemplate" text="Reorder">
<Size>
<AbsDimension x="57" y="18"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-58" y="7"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_ReorderPage(NotesCurPageNumText:GetNumber())
</OnClick>
</Scripts>
</Button>
<EditBox name="NotesCurPageNumText" numeric="true" letters="3" enableMouse="true" autoFocus="false" justifyH="RIGHT">
<Size>
<AbsDimension x="25" y="20"/>
</Size>
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="2" y="6"/>
</Offset>
</Anchor>
</Anchors>
<FontString inherits="GameFontHighlight" justifyH="RIGHT"/>
<Scripts>
<OnClick>
this:SetFocus();
</OnClick>
<OnEnterPressed>
this:ClearFocus();
Notes_GoToPage(NotesCurPageNumText:GetNumber())
</OnEnterPressed>
<OnEscapePressed>
this:ClearFocus();
</OnEscapePressed>
</Scripts>
</EditBox>
</Frames>
<Layers>
<Layer level="ARTWORK">
<FontString name="NotesPageLabel" inherits="GameFontNormal" text="Page: " justifyH="RIGHT">
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="-27" y="10"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="NotesPageSlash" inherits="GameFontNormal" text="/" justifyH="LEFT">
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="20" y="10"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="NotesMaxPageNumText" inherits="GameFontNormal" justifyH="LEFT">
<Size>
<AbsDimension x="28" y="12"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesPageSlash" relativePoint="RIGHT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
 
 
<Frame name="NotesCommFrameTemplate" enableMouse="true" virtual="true" hidden="true">
<Size>
<AbsDimension x="330" y="50"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesBGFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="16" y="55"/>
</Offset>
</Anchor>
</Anchors>
<Backdrop bgFile="Interface\TutorialFrame\TutorialFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="32"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Frames>
<Button name="NotesCommSendButton" inherits="NotesLargeButtonTemplate" text="Print Note">
<Size>
<AbsDimension x="77" y="17"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="6" y="-24"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_PrintSelected()
</OnClick>
</Scripts>
</Button>
<Frame name="NotesCommDropDown" inherits="UIDropDownMenuTemplate" enableMouse="true" hidden="false">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesCommSendButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="0" y="-2"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" inherits="GameFontNormalSmall" text="to" justifyH="RIGHT">
<Anchors>
<Anchor point="RIGHT" relativePoint="LEFT">
<Offset>
<AbsDimension x="15" y="2"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
<Frame name="NotesChanSelectDropDown" inherits="UIDropDownMenuTemplate" enableMouse="true" hidden="false">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesCommDropDown" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-28" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
<EditBox name="NotesWhisperEditBox" letters="30" autoFocus="false">
<Size>
<AbsDimension x="120" y="20"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesCommDropDown" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-3" y="2"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="NotesWhisperGroupBorderLeft" file="Interface\ChatFrame\UI-ChatInputBorder-Left">
<Size>
<AbsDimension x="26" y="28"/>
</Size>
<Anchors>
<Anchor point="LEFT">
<Offset>
<AbsDimension x="-12" y="0"/>
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0" right="0.1" top="0" bottom="1.0"/>
</Texture>
<Texture name="NotesWhisperGroupBorderMid" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
<Size>
<AbsDimension x="90" y="28"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesWhisperGroupBorderLeft" relativePoint="RIGHT"/>
</Anchors>
<TexCoords left="0.4" right=".6" top="0" bottom="1.0"/>
</Texture>
<Texture name="NotesWhisperGroupBorderRight" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
<Size>
<AbsDimension x="22" y="28"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesWhisperGroupBorderMid" relativePoint="RIGHT"/>
</Anchors>
<TexCoords left="0.9" right="1.0" top="0" bottom="1.0"/>
</Texture>
</Layer>
</Layers>
<FontString inherits="GameFontHighlightSmall"></FontString>
<Scripts>
<OnClick>
this:SetFocus();
</OnClick>
<OnEnterPressed>
this:ClearFocus();
</OnEnterPressed>
<OnEscapePressed>
this:ClearFocus();
</OnEscapePressed>
<OnMouseUp>
NotesWhisperEditBox:SetFocus();
</OnMouseUp>
<OnTextChanged>
Notes_SetButtonState(1)
</OnTextChanged>
</Scripts>
</EditBox>
<EditBox name="NotesPrintMacroEditBox" letters="40" virtual="true" enableMouse="true" autoFocus="false" hidden="true">
<Size>
<AbsDimension x="270" y="20"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="55" y="-2"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString inherits="GameFontNormal" text="Macro: " justifyH="LEFT">
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="-45" y="5"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<FontString inherits="GameFontHighlightSmall"/>
<Scripts>
<OnTextChanged>
this:ClearFocus()
Notes_SetButtonState()
</OnTextChanged>
<OnClick>
this:SetFocus();
</OnClick>
<OnEnterPressed>
this:ClearFocus();
</OnEnterPressed>
<OnEscapePressed>
this:ClearFocus();
</OnEscapePressed>
</Scripts>
</EditBox>
<CheckButton name="NotesCommSpeedCheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="false">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Speed")
</OnLoad>
<OnClick>
Notes_CommSpeedUIToggle()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="-37" y="-4"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
<Slider name="NotesCommSpeedSlider" inherits="OptionsSliderTemplate">
<Size>
<AbsDimension x="236" y="17" />
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-10" y="15" />
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString inherits="GameFontNormal" text="Max Delay: [Medium]" name="NotesCommSpeedLabel" justifyH="LEFT">
<Size>
<AbsDimension x="160" y="15"/>
</Size>
<Anchors>
<Anchor point="RIGHT" relativePoint="LEFT">
<Offset>
<AbsDimension x="2" y="-4"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnShow>
getglobal(this:GetName().."Low"):SetText("Off");
getglobal(this:GetName().."High"):SetText("Long");
this:SetMinMaxValues(0, 20);
this:SetValueStep(4);
this:SetScale(.8);
</OnShow>
<OnValueChanged>
Notes_PrintMaxInterval = this:GetValue()
Notes_SetButtonState(1)
</OnValueChanged>
</Scripts>
</Slider>
</Frames>
</Frame>
 
 
 
 
 
 
 
 
 
<Frame name="NotesFrame" toplevel="true" enableMouse="true" movable="true" parent="UIParent" hidden="true">
<Scripts>
<OnLoad>
Notes_ScrollBarUpdate()
this:RegisterForDrag("LeftButton");
tinsert(UISpecialFrames,this:GetName());
</OnLoad>
<OnDragStart>
this:StartMoving();
this.isMoving = true;
</OnDragStart>
<OnDragStop>
this:StopMovingOrSizing();
this.isMoving = false;
</OnDragStop>
</Scripts>
 
<Size>
<AbsDimension x="384" y="442"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Frames>
<Frame name="NotesBGFrame" inherits="NotesFrameTemplate" hidden="false"/>
<Frame name="Notes" inherits="NotesNoteScrollTemplate" hidden="false"/>
 
<Frame name="NotesTitleEditFrame" inherits="NotesTitleEditBoxTemplate" hidden="false"/>
<ScrollFrame name="NotesText" inherits="NotesScrollTextFrameTemplate" hidden="false"/>
<Frame name="NotesBookFrame" inherits="NotesBookFrameTemplate" hidden="false"/>
<Frame name="NotesTOC" inherits="NotesTOCScrollTemplate" hidden="true"/>
 
<Frame name="NotesCommFrame" inherits="NotesCommFrameTemplate" hidden="false">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesBookFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="4"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="NotesLuaFrame" inherits="NotesLuaFrameTemplate" hidden="false">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesCommFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="4"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
</Frames>
</Frame>
 
<Frame name="NotesEvents" toplevel="false" enableMouse="false" movable="false" parent="UIParent" hidden="false">
<Size>
<AbsDimension x="1" y="1"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT"/>
</Anchors>
<Scripts>
<OnLoad>
Notes_OnLoad();
</OnLoad>
<OnEvent>
Notes_ListenEvent();
Notes_OnEvent();
</OnEvent>
<OnUpdate>
Notes_ParseCache()
Notes_OnUpdate();
</OnUpdate>
</Scripts>
</Frame>
</Ui>
 
branches/WotLK/Notes/Notes.lua New file
0,0 → 1,2538
--[[
Notes by Vincent, Silver Hand
Original Author: Andersen, Silvermoon
use /notes to show the GUI
]]--
 
--[[
Table of Contents:
A) Variables
B) Notes Selection Functions
C) Notes Note Functions
D) LUA Functions
E) UI Update Functions
F) UI Functions
G) Sync Functions
H) Notes Sorting Functions
I) General Tools Functions
J) Dropdown UI Functions
K) Book UI Functions
]]--
 
--function p(m) Notes_Print(m) end
--function t(m) return Notes_DataToString(m) end
 
------------------------------------------
-- A) Variables
 
Notes_Notes = {}
Notes_Import = {}
 
Notes_Selected = nil
Notes_MultiSelect = {}
 
local Notes_Undo = {}
local Notes_SelectedAtLastUpdate = nil
local Notes_MultiSelectCountAtLastUpdate = 0
local Notes_LoadID = nil
local Notes_BookID = nil
local Notes_BookPages = {}
local Notes_BookPage = 0
local Notes_TotalPages = 0
local Notes_TOCPageData = {};
 
local Notes_LastUpdateTime = nil
local Notes_PrintMinLength=15
local Notes_PrintMaxLength=180
local Notes_PrintMaxChunkLength=220
 
local Notes_PrintMinInterval=1
Notes_PrintMaxInterval=12
local Notes_PrintInterval = Notes_PrintMaxInterval
 
 
local Notes_PrintCache = {}
local Notes_CacheIndex = 1
local Notes_Listening = {}
local Notes_ListenStack = {}
local Notes_ListenBook = {}
 
local Notes_LUASetupNote = {"LUA - Start Up","--Notes LUA Setup READ ME.\n\n--[[Notes can organize and execute multiple LUA scripts. This setup file should help a new Notes user take advantage of Notes's LUA functionality. Keep in mind that you must press the Run LUA button on this note when you start WoW and every time you make a change if you want to use the LUA functions defined here. Unlock this note to modify it.\n\nEntering LUA mode: type /lua or /noteslua\nRunning LUA notes in macros: In LUA mode, any selected note will display text that you can copy and paste into a macro. This uses the RunNote() function.]]--\n\n--[[OnEvent commands: Uncomment the following function and register some events to run OnEvent commands. ]]--\n\n\n--NotesEvents:RegisterEvent('CHAT_MSG_WHISPER')\n--Notes_OnEvent = function()\n-- doEventStuff()\n--end\n\n\n--[[OnUpdate commands: Uncomment the following function and register some events to run OnEvent commands. ]]--\n\n\n--Notes_OnUpdate = function()\n-- doUpdateStuff()\n--end\n\n"}
 
local Notes_TitleLen = 25
local Notes_DescrLen = 25
local Notes_TOCTitleLen = 30
local Notes_ColorNormal = {1,.82,0}
local Notes_ColorSync = {.7,1,.3}
local Notes_ColorLocked = {.52,.52,.52}
local Notes_ColorSyncLocked = {.4,.5,.7}
local Notes_ColorBook = {1,.5,.1}
local Notes_ColorBookSync = {1,.1,0}
local Notes_ColorBookLocked = {.52,.52,.52}
local Notes_ColorBookSyncLocked = {.6,0,.4}
 
Notes_IconDrag = false
Notes_IconPos = {nil,nil}
 
Notes_CommMode = false
Notes_CommSpeedMode = false
Notes_LUAMode = false
Notes_ExportMode = false
Notes_ShowIcon = 1
Notes_SelectedComm = 1
Notes_SelectedChan = 1
 
Notes_ChanList = {}
local Notes_CommModes = {
{"Guild", function(msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"GUILD") end,
function() return Notes_InGuild() end,
"GUILD",
function() return "Guild" end,
function(sender) return Notes_InGuild(sender) end},
 
{"Party", function(msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"PARTY") end,
function() return (Notes_InParty() and not Notes_InRaid()) or (Notes_InRaid() and (IsRaidLeader() or IsRaidOfficer())) end,
"PARTY",
function() return "Party" end,
function(sender) return Notes_InParty(sender) end},
 
{"Raid", function(msg) Notes_RaidPrint(msg) end,
function() return Notes_InRaid() and (IsRaidLeader() or IsRaidOfficer()) end,
"RAID",
function() return "Raid" end,
function(sender) return Notes_InRaid(sender) end},
 
{"RaidWarning", function (msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"RAID_WARNING") end,
function() return Notes_InRaid() and (IsRaidLeader() or IsRaidOfficer()) end,
"RAID",
function() return "RaidWarning" end,
function(sender) return Notes_InRaid(sender) end},
 
{"Battleground",function(msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"BATTLEGROUND") end,
function() return Notes_InBattlefield() end,
"RAID",
function() return "Battleground" end,
function(sender) return Notes_InRaid(sender) end},
 
{"Say", function(msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"SAY") end,
function() return true end,
nil,
function() return "Say" end,
function() return nil end},
 
{"Self", function(msg) Notes_Print(msg) end,
function() UnitName("target") return true end,
nil,
function() return "Self" end,
function() return nil end},
 
{"Target", function(msg) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"WHISPER",GetDefaultLanguage("player"),UnitName("target")) end,
function() return UnitName("target") and UnitIsPlayer("target") end,
"WHISPER",
function() return UnitName("target") end,
function(tar) return Notes_InGuild(sender) or Notes_InRaid(sender) end},
 
{"Whisper", function(msg,tar) ChatThrottleLib:SendChatMessage("NORMAL","",msg,"WHISPER",GetDefaultLanguage("player"),tar) end,
function() local text=NotesWhisperEditBox:GetText() return text and strlen(text)>0 end,
"WHISPER",
function() local text=NotesWhisperEditBox:GetText() if strlen(text)>0 then return text end end,
function(sender,tar) return (Notes_InGuild(sender) or Notes_InRaid(sender)) and tar==strlower(UnitName("player")) end},
 
{"Channel", function(msg,chan)
if not chan then return end
local index = GetChannelName(chan)
if index ~= nil and index ~= 0 then
ChatThrottleLib:SendChatMessage("NORMAL","",msg,"CHANNEL",GetDefaultLanguage("player"),index)
end end,
function() return true end,"CHANNEL",
function() if Notes_ChanList[Notes_SelectedChan] then return Notes_ChanList[Notes_SelectedChan][2] end end,
function(sender,chan) return (Notes_InGuild(sender) or Notes_InParty(sender) or Notes_InRaid(sender)) and Notes_InTable(Notes_ChanList,chan,3) end}
}
 
-- Binding Variables
BINDING_HEADER_NOTESHEADER = "Notes";
BINDING_NAME_NOTESTOGGLE = "Toggle Notes";
BINDING_NAME_NOTESICONTOGGLE = "Toggle Notes Map Icon";
 
------------------------------------------
-- B) Notes Selection Functions
--[[
Notes_ToggleSelected - Register that we've selected a new note
Notes_SortAndReselect - Wrapper for Notes_SortNotes that fixes the selection after sorting
Notes_SortNotes - Alphabetize the notes
]]--
function Notes_ToggleSelected(button)
local dirtyflag = nil
 
if button ~= nil then
local num = button
if getglobal(button) then
num = tonumber(strsub(button,-1))
end
local toselect = num + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
 
if Notes_Selected and type(Notes_Notes[Notes_Selected]["book"])~="string" and IsShiftKeyDown() then
local idx = Notes_InTable(Notes_MultiSelect,toselect)
if toselect == Notes_Selected and getn(Notes_MultiSelect) > 0 then
Notes_Selected = Notes_MultiSelect[getn(Notes_MultiSelect)]
table.remove(Notes_MultiSelect,getn(Notes_MultiSelect))
 
elseif idx then
table.remove(Notes_MultiSelect,idx)
dirtyflag = true
 
else
local tar = num + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
local start,finish
if Notes_Selected <= tar then
start = Notes_Selected
finish = tar-1
else
start = tar+1
finish = Notes_Selected
end
 
for i=start,finish do
if not Notes_InTable(Notes_MultiSelect,i) then
table.insert(Notes_MultiSelect,i)
end
end
Notes_Selected = num + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
end
 
elseif Notes_Selected and type(Notes_Notes[Notes_Selected]["book"])~="string" and IsControlKeyDown() then
local idx = Notes_InTable(Notes_MultiSelect,toselect)
if toselect == Notes_Selected and getn(Notes_MultiSelect) > 0 then
Notes_Selected = Notes_MultiSelect[getn(Notes_MultiSelect)]
table.remove(Notes_MultiSelect,getn(Notes_MultiSelect))
 
elseif idx then
table.remove(Notes_MultiSelect,idx)
dirtyflag = true
 
else
table.insert(Notes_MultiSelect,Notes_Selected)
Notes_Selected = num + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
end
 
else
Notes_MultiSelect = {}
Notes_Selected = toselect
end
else
Notes_MultiSelect = {}
Notes_Selected = nil
Notes_LoadID = nil
Notes_BookID = nil
Notes_BookPages = {}
Notes_BookPage = 0
Notes_SelectedAtLastUpdate = nil
end
 
Notes_LoadSelected()
Notes_ScrollBarUpdate(dirtyflag)
end
 
function Notes_SortAndReselect(mids)
Notes_FixHiddenPages()
Notes_SortNotes()
 
if mids and getn(mids) > 0 then
Notes_MultiSelect = {}
for i=1,getn(mids) do
midx = Notes_GetNoteIndex(mids[i])
if midx then
table.insert(Notes_MultiSelect,midx)
end
end
end
 
Notes_Selected = Notes_GetNoteIndex(Notes_LoadID)
 
if Notes_Selected and Notes_BookPage == 0 then
local tarscroll = (tonumber(Notes_Selected)-1)*16
local minscroll = (0+FauxScrollFrame_GetOffset(NotesNoteScrollBar))*16
local maxscroll = (4+FauxScrollFrame_GetOffset(NotesNoteScrollBar))*16
local offset = nil
 
if tarscroll < minscroll then
offset = -2
elseif tarscroll > maxscroll then
offset = -4
end
 
if offset then
NotesNoteScrollBarScrollBar:SetValue((tonumber(Notes_Selected)+offset)*16)
end
end
end
 
function Notes_SortNotes()
table.sort(Notes_Notes,Notes_HashNatTitleSort)
Notes_ScrollBarUpdate()
end
 
------------------------------------------
-- C) Notes Note Functions
--[[
Notes_MakeNoteID - Make a new random ID
Notes_NewNote - Create a new note
Notes_SaveNote - Save new data entered in the UI to the table
Notes_CopySelected - Duplicate the selected
Notes_LoadSelected - Load the selected note into the edit buffer
Notes_LoadEmpty - Empty the edit buffer
Notes_DeleteSelected - wrapper for Notes_DeleteAndRebuild
Notes_DeleteAndRebuild - Remove a note from the table
Notes_RevertSelected - Revert changes to the selected note to the last time the UI was shown
Notes_PrepUndo - Populate the undo table with the correct data.
Notes_SyncSelected - Mark the selected note as sync for syncing purposes
Notes_LockedSelected - Lock the selected note
Notes_CompileOrExtractSelected - Master control switch for compiling/extracting from notebooks
Notes_CompileSelected - Compile the selected notes into a book/add notes into an existing book
Notes_ExtractSelected - Extract a page from a book and rebuild the book's index
]]--
 
function Notes_MakeNoteID()
return time()..random(1000)
end
 
function Notes_NewNote(title,text,sync,locked,id,book,bookname,overwrite,syncoverwrite)
if title == nil or title == "" then title = Notes_FindNextInSequence("New Note #1") end
if text == nil then text = "" end
if id == nil then id = Notes_MakeNoteID() end
if sync == nil then sync = false end
if locked == nil then locked = false end
if book == nil or (type(book)~="string" and type(book)~="table") then book = false end
if overwrite == nil then overwrite = false end
if syncoverwrite == nil then syncoverwrite = false end
 
local newNote = {}
newNote["title"] = title
newNote["text"] = text
newNote["id"] = id
newNote["sync"] = sync
newNote["locked"] = locked
newNote["book"] = book
 
local newUndoNote = {}
newUndoNote["title"] = title
newUndoNote["text"] = text
newUndoNote["id"] = id
newUndoNote["sync"] = sync
newUndoNote["locked"] = locked
newUndoNote["book"] = book
newUndoNote["undo"] = false
 
local oldidx = Notes_GetNoteIndex(id)
if oldidx then
if not overwrite then return 2-- Print "tried to overwrite existing note?"
else
 
if Notes_Notes[oldidx]["locked"] then
return 2
 
elseif syncoverwrite and not Notes_Notes[oldidx]["sync"] then
return 1
 
else
Notes_Notes[oldidx]["title"] = newNote["title"]
Notes_Notes[oldidx]["text"] = newNote["text"]
Notes_Notes[oldidx]["sync"] = newNote["sync"]
Notes_Notes[oldidx]["locked"] = newNote["locked"]
Notes_Notes[oldidx]["book"] = newNote["book"]
if Notes_Selected == oldidx then
Notes_LoadSelected()
end
end
end
else
table.insert(Notes_Notes,newNote)
end
 
Notes_Undo[newNote["id"]] = newUndoNote
 
if not overwrite then
Notes_Selected = Notes_GetNoteIndex(newNote["id"])
Notes_MultiSelect = {}
Notes_LoadSelected()
end
 
local bookidx = nil
if type(book) == "string" then
bookidx = Notes_GetNoteIndex(book)
if not bookidx then
if not bookname then bookname = Notes_FindNextInSequence("New Book #1") end
Notes_NewNote(bookname,"",false,false,book,{id})
else
table.insert(Notes_Notes[bookidx]["book"],id)
Notes_MultiSelect = {}
Notes_LoadSelected(bookidx)
end
end
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate()
return 0
end
 
function Notes_SaveNote()
local title = NotesTitleEditBox:GetText()
local text = NotesTextEditBox:GetText()
 
if not Notes_Selected then
if strlen(title) > 0 or strlen(text) > 0 then
Notes_NewNote(title,text)
return
 
elseif strlen(title) == 0 and strlen(text) == 0 then
return
end
end
 
local isbook = type(Notes_Notes[Notes_Selected]["book"]) == "table"
local bookidx = Notes_GetNoteIndex(Notes_BookID)
local booklock = not isbook and bookidx and Notes_Notes[bookidx]["locked"]
 
if Notes_Notes[Notes_Selected]["locked"] or booklock then
NotesTitleEditBox:SetText(Notes_Notes[Notes_Selected]["title"])
 
if isbook then Notes_CreateIndexPage() --NotesTextEditBox:SetText(Notes_CreateIndexPage(text))
else NotesTextEditBox:SetText(Notes_Notes[Notes_Selected]["text"]) end
return
end
 
Notes_Notes[Notes_Selected]["title"] = title
if isbook then Notes_CreateIndexPage() --NotesTextEditBox:SetText(Notes_CreateIndexPage(text))
else Notes_Notes[Notes_Selected]["text"] = text end
 
if Notes_Undo[Notes_LoadID]["undo"] == false then
if(strlen(Notes_Undo[Notes_LoadID]["title"]) ~= strlen(Notes_Notes[Notes_Selected]["title"]) or
strlen(Notes_Undo[Notes_LoadID]["text"]) ~= strlen(Notes_Notes[Notes_Selected]["text"])) then
Notes_Undo[Notes_LoadID]["undo"] = true
end end
 
Notes_ScrollBarUpdate()
end
 
function Notes_CopySelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index or not Notes_Notes[index] then return end
 
local mids = {}
if not idx then
for i=1,getn(mindex) do
table.insert(mids,Notes_Notes[mindex[i]]["id"])
end
end
 
if type(Notes_Notes[index]["book"]) ~= "table" then
local copyNote = {}
copyNote["title"] = Notes_FindNextInSequence(Notes_Notes[index]["title"].." Copy #1")
copyNote["text"] = Notes_Notes[index]["text"]
copyNote["id"] = Notes_MakeNoteID()
copyNote["sync"] = Notes_Notes[index]["sync"]
copyNote["locked"] = Notes_Notes[index]["locked"]
 
for i=1,getn(Notes_Notes) do
if Notes_Notes[i]["id"] == copyNote["id"] then
return
end
end
 
table.insert(Notes_Notes,copyNote)
 
Notes_Undo[copyNote["id"]] = copyNote
Notes_Undo[copyNote["id"]]["undo"] = false
end
 
if not idx then
 
if getn(mindex) > 0 then
for i=1,getn(mindex) do
Notes_CopySelected(mindex[i])
end
end
 
Notes_SortAndReselect(mids)
Notes_ScrollBarUpdate()
end
end
 
function Notes_LoadSelected(idx)
local index = Notes_Selected
if idx then index = idx end
 
if not index or not Notes_Notes[index] then return Notes_LoadEmpty() end
 
if type(Notes_Notes[index]["book"])=="table" then
Notes_BookID = Notes_Notes[index]["id"]
Notes_BookPages = Notes_Notes[index]["book"]
Notes_BookPage = 0
 
Notes_CreateIndexPage()
NotesTitleEditBox:SetText(Notes_Notes[index]["title"])
Notes_LoadID = Notes_Notes[index]["id"]
else
NotesTextEditBox:SetText(Notes_Notes[index]["text"])
NotesTitleEditBox:SetText(Notes_Notes[index]["title"])
Notes_LoadID = Notes_Notes[index]["id"]
 
if type(Notes_Notes[index]["book"])~="string" then
Notes_BookID = nil
Notes_BookPage = 0
Notes_BookPages = {}
else
Notes_MultiSelect = {}
end
end
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate()
end
 
function Notes_LoadEmpty()
Notes_MultiSelect = {}
Notes_Selected = nil
Notes_LoadID = nil
Notes_BookID = nil
Notes_BookPages = {}
Notes_BookPage = 0
Notes_SelectedAtLastUpdate = nil
 
NotesTextEditBox:SetText("")
NotesTitleEditBox:SetText("")
 
NotesTOC:Hide()
NotesText:Show()
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate()
end
 
function Notes_RevertSelected()
if Notes_Selected and Notes_Undo[Notes_LoadID]["undo"] == true then
 
Notes_Notes[Notes_Selected]["title"] = Notes_Undo[Notes_LoadID]["title"]
Notes_Notes[Notes_Selected]["text"] = Notes_Undo[Notes_LoadID]["text"]
Notes_Notes[Notes_Selected]["sync"] = Notes_Undo[Notes_LoadID]["sync"]
Notes_Notes[Notes_Selected]["locked"] = Notes_Undo[Notes_LoadID]["locked"]
Notes_Notes[Notes_Selected]["book"] = Notes_Undo[Notes_LoadID]["book"]
Notes_Undo[Notes_LoadID]["undo"] = false
 
Notes_LoadSelected()
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate()
end
end
 
function Notes_PrepUndo()
Notes_TotalPages = 0
Notes_Undo = {}
for i=1,getn(Notes_Notes) do
Notes_Undo[Notes_Notes[i]["id"]]={}
Notes_Undo[Notes_Notes[i]["id"]]["id"] = Notes_Notes[i]["id"]
Notes_Undo[Notes_Notes[i]["id"]]["title"] = Notes_Notes[i]["title"]
Notes_Undo[Notes_Notes[i]["id"]]["text"] = Notes_Notes[i]["text"]
Notes_Undo[Notes_Notes[i]["id"]]["sync"] = Notes_Notes[i]["sync"]
Notes_Undo[Notes_Notes[i]["id"]]["locked"] = Notes_Notes[i]["locked"]
Notes_Undo[Notes_Notes[i]["id"]]["book"] = Notes_Notes[i]["book"]
Notes_Undo[Notes_Notes[i]["id"]]["undo"] = false
end
end
 
function Notes_FixHiddenPages()
Notes_TotalPages = 0
for i=1,getn(Notes_Notes) do
if type(Notes_Notes[i]["book"]) == "string" then
Notes_TotalPages = Notes_TotalPages + 1
end
end
end
 
function Notes_SyncSelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index or not Notes_Notes[index] then return end
 
local ispage = type(Notes_Notes[index]["book"]) == "string"
local bookidx = Notes_GetNoteIndex(Notes_BookID)
local booksync = ispage and bookidx and Notes_Notes[bookidx]["sync"]
local booklock = ispage and bookidx and Notes_Notes[bookidx]["locked"]
 
if booksync and not Notes_Notes[index]["sync"] then
Notes_Notes[index]["sync"] = 1
else
Notes_Notes[index]["sync"] = NotesSyncCheckButton:GetChecked()
end
 
if not idx then
if getn(mindex) > 0 then
for i=1,getn(mindex) do
Notes_SyncSelected(mindex[i])
end
end
Notes_ScrollBarUpdate(1)
end
end
 
function Notes_LockedSelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index or not Notes_Notes[index] then return end
 
local ispage = type(Notes_Notes[index]["book"]) == "string"
local bookidx = Notes_GetNoteIndex(Notes_BookID)
local booklock = ispage and bookidx and Notes_Notes[bookidx]["locked"]
 
if booklock then
NotesLockedCheckButton:SetChecked(1) --SetChecked(Notes_Notes[index]["locked"])
else
Notes_Notes[index]["locked"] = NotesLockedCheckButton:GetChecked()
end
 
if not idx then
if not booklock and getn(mindex) > 0 then
for i=1,getn(mindex) do
Notes_LockedSelected(mindex[i])
end
end
Notes_ScrollBarUpdate(1)
end
end
 
function Notes_DeleteSelected(idx,midx)
return Notes_DeleteAndRebuild(idx,midx)
end
 
function Notes_DeleteAndRebuild(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index or not Notes_Notes[index] then return end
 
local newmid = nil
 
local deletestack = {}
local selectstack = {}
local newNotes_Notes = {}
 
if not Notes_Notes[index]["locked"] then
table.insert(selectstack,index)
end
if getn(mindex) > 0 then
for i=1,getn(mindex) do
if not Notes_Notes[mindex[i]]["locked"] then
table.insert(selectstack,mindex[i])
end
end
end
 
for i=1,getn(selectstack) do
if type(Notes_Notes[selectstack[i]]["book"])=="table" then
if getn(Notes_Notes[selectstack[i]]["book"]) > 0 then
for j=1,getn(Notes_Notes[selectstack[i]]["book"]) do
local pageidx = Notes_GetNoteIndex(Notes_Notes[selectstack[i]]["book"][j])
if pageidx then
if not Notes_Notes[pageidx]["locked"] then
table.insert(deletestack,pageidx)
Notes_TotalPages = Notes_TotalPages - 1
else
Notes_Notes[pageidx]["book"] = false
 
if not newmid or type(newmid) == "string" then newmid = {} end
table.insert(newmid,Notes_Notes[pageidx]["id"])
end
end
end
end
table.insert(deletestack,selectstack[i])
 
elseif type(Notes_Notes[selectstack[i]]["book"])=="string" then
local curidx, newidx = Notes_ExtractSelected(selectstack[i])
if newidx and not newmid then
newmid = Notes_Notes[newidx]["id"]
end
table.insert(deletestack,curidx)
else
table.insert(deletestack,selectstack[i])
end
end
 
for i=1,getn(Notes_Notes) do
if not Notes_InTable(deletestack,i) then
table.insert(newNotes_Notes,Notes_Notes[i])
end
end
 
Notes_Notes = newNotes_Notes
 
if type(newmid)=="string" then
local lid = Notes_GetNoteIndex(newmid)
if lid then
Notes_LoadSelected(lid)
else
Notes_LoadEmpty()
end
 
elseif type(newmid)=="table" then
 
Notes_LoadSelected(Notes_GetNoteIndex(newmid[1]))
if getn(newmid) > 1 then
Notes_MultiSelect = {}
for i=2,getn(newmid) do
local mulidx = Notes_GetNoteIndex(newmid[i])
if mulidx then table.insert(Notes_MultiSelect,mulidx) end
end
end
else
Notes_LoadEmpty()
end
Notes_ScrollBarUpdate(1)
end
 
function Notes_CompileOrExtractSelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index then return end
 
local selectstack = {}
 
if type(Notes_Notes[index]["book"])=="table" and getn(mindex) == 0 then
for i=getn(Notes_Notes[index]["book"]),1,-1 do
local page = Notes_GetNoteIndex(Notes_Notes[index]["book"][i])
table.insert(selectstack,Notes_Notes[page]["id"])
if page then Notes_ExtractSelected(page) end
end
 
if getn(selectstack) > 0 then
if getn(selectstack) > 1 then
for i=2,getn(selectstack) do
local page = Notes_GetNoteIndex(selectstack[i])
table.insert(Notes_MultiSelect,page)
end
end
Notes_LoadSelected(Notes_GetNoteIndex(selectstack[1]))
end
 
elseif type(Notes_Notes[index]["book"])=="string" then
Notes_LoadSelected(Notes_ExtractSelected())
else
Notes_CompileSelected()
end
 
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate(1)
end
 
function Notes_CompileSelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index then return end
 
local selectstack = {}
local pagestack = {}
local idstack = {}
 
local targetbook = nil
local deletebooks = {}
 
table.insert(selectstack,index)
if getn(mindex) > 0 then
for i=1,getn(mindex) do
table.insert(selectstack,mindex[i])
end
end
 
table.sort(selectstack,Notes_HashNatNotesTitleSort)
 
for i=1,getn(selectstack) do
if type(Notes_Notes[selectstack[i]]["book"])=="table" and getn(Notes_Notes[selectstack[i]]["book"]) > 0 then
for j=1,getn(Notes_Notes[selectstack[i]]["book"]) do
local pageidx = Notes_GetNoteIndex(Notes_Notes[selectstack[i]]["book"][j])
if pageidx then
table.insert(pagestack,pageidx)
table.insert(idstack,Notes_Notes[pageidx]["id"])
end
end
if targetbook == nil and getn(deletebooks) == 0 then
targetbook = Notes_Notes[selectstack[i]]["id"]
 
else
if targetbook ~= nil then
table.insert(deletebooks,targetbook)
targetbook = nil
end
table.insert(deletebooks,Notes_Notes[selectstack[i]]["id"])
end
 
elseif type(Notes_Notes[selectstack[i]]["book"])~="string" then
table.insert(pagestack,selectstack[i])
table.insert(idstack,Notes_Notes[selectstack[i]]["id"])
end
end
 
 
if targetbook then
local bookidx = Notes_GetNoteIndex(targetbook)
if bookidx then
for i=1,getn(selectstack) do
local booktype = type(Notes_Notes[selectstack[i]]["book"])
Notes_Notes[selectstack[i]]["book"] = Notes_Notes[bookidx]["id"]
end
 
Notes_Notes[bookidx]["book"] = idstack
Notes_Selected = bookidx
Notes_LoadSelected()
Notes_MultiSelect = {}
return
end
end
 
local bookid = Notes_MakeNoteID()
 
for i=1,getn(selectstack) do
Notes_Notes[selectstack[i]]["book"] = bookid
end
 
Notes_MultiSelect = {}
if getn(deletebooks) > 0 then
for i=1,getn(deletebooks) do
local bookidx = Notes_GetNoteIndex(deletebooks[i])
if bookidx then
Notes_Notes[bookidx]["book"] = false
Notes_Notes[bookidx]["locked"] = false
Notes_DeleteAndRebuild(bookidx)
end
end
end
Notes_NewNote(Notes_FindNextInSequence("New Book #1"),"",false,false,bookid,idstack)
end
 
function Notes_ExtractSelected(idx)
local index = Notes_Selected
if idx then index = idx end
 
if not index then return end
 
local loadid = Notes_LoadID
local bookidx = Notes_GetNoteIndex(Notes_BookID)
Notes_Notes[index]["book"] = false
 
if bookidx then
local contents = {}
for i=1,getn(Notes_Notes[bookidx]["book"]) do
if Notes_Notes[bookidx]["book"][i] ~= Notes_Notes[index]["id"] then
table.insert(contents,Notes_Notes[bookidx]["book"][i])
else
Notes_TotalPages = Notes_TotalPages - 1
end
end
 
if getn(contents) > 0 then
Notes_Notes[bookidx]["book"] = contents
if Notes_BookPage > getn(contents) then
Notes_BookPage = Notes_BookPage - 1
end
 
return Notes_GetNoteIndex(loadid), Notes_GetNoteIndex(contents[Notes_BookPage])
else
Notes_Notes[bookidx]["book"] = false
Notes_Notes[bookidx]["locked"] = false
Notes_DeleteAndRebuild(bookidx)
return Notes_GetNoteIndex(loadid)
end
end
end
 
------------------------------------------
-- D) LUA Functions
--[[
Notes_ExecuteSelected - Execute the selected LUA script note
RunNote - wrapper for Notes_RunNote
Notes_RunNote - Execute a LUA script note by passing a note id
Notes_AddLUASetupNote - Add the default LUA setup note
]]--
 
function Notes_ExecuteSelected(idx)
local index = Notes_Selected
if idx then index = idx end
 
if not index then return end
 
RunScript(Notes_Notes[index]["text"])
end
 
function RunNote(noteid)
return Notes_RunNote(noteid)
end
 
function Notes_RunNote(noteid)
local idx = Notes_GetNoteIndex(tostring(noteid))
if idx ~= nil then Notes_ExecuteSelected(idx) else
Notes_ErrorPrint("Note ID ["..noteid.."] not found") end
end
 
function Notes_AddLUASetupNote()
Notes_NewNote(Notes_LUASetupNote[1],Notes_LUASetupNote[2],false,false,"1","2","Notes LUA Book")
end
 
------------------------------------------
-- E) UI Update Functions
--[[
Notes_SetButtonState - Update the Button UI status
Notes_ScrollBarUpdate - Update the graphics for the notes navigation system
Notes_GetColor - Get the proper color for a note's title
]]--
 
function Notes_SetButtonState(fullupdate)
if not NotesFrame:IsVisible() then return end
 
if Notes_Selected and Notes_Notes[Notes_Selected] then
if Notes_Selected ~= Notes_SelectedAtLastUpdate or
Notes_MultiSelectCountAtLastUpdate ~= getn(Notes_MultiSelect) or fullupdate then
Notes_SelectedAtLastUpdate = Notes_Selected
Notes_MultiSelectCountAtLastUpdate = getn(Notes_MultiSelect)
 
NotesLockedCheckButton:SetChecked(Notes_Notes[Notes_Selected]["locked"])
NotesCompileButton:Enable()
NotesExecuteButton:Enable()
NotesSyncCheckButton:Enable()
NotesSyncCheckButtonText:SetText("Sync")
NotesSyncCheckButton:SetCheckedTexture("Interface/Buttons/UI-CheckBox-Check")
NotesSyncCheckButton:SetChecked(Notes_Notes[Notes_Selected]["sync"])
NotesLockedCheckButtonText:SetText("Locked")
NotesLockedCheckButton:Enable()
NotesLockedCheckButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
NotesCommSendButton:SetText("Print Note")
NotesGoPageButton:SetText("Index")
 
NotesTOC:Hide()
NotesText:Show()
 
local isbook = type(Notes_Notes[Notes_Selected]["book"]) == "table"
local bookidx = Notes_GetNoteIndex(Notes_BookID)
local booksync = not isbook and bookidx and Notes_Notes[bookidx]["sync"]
local booklock = not isbook and bookidx and Notes_Notes[bookidx]["locked"]
 
local unlockcount = 0
local notecount = 0
 
if not Notes_Notes[Notes_Selected]["locked"] then
unlockcount = unlockcount + 1
end
if type(Notes_Notes[Notes_Selected]["book"]) ~= "table" then
notecount = notecount + 1
end
for i=1,getn(Notes_MultiSelect) do
if not Notes_Notes[Notes_MultiSelect[i]]["locked"] then
unlockcount = unlockcount + 1
end
if type(Notes_Notes[Notes_MultiSelect[i]]["book"]) ~= "table" then
notecount = notecount + 1
end
end
 
if isbook then
Notes_BookUIToggle("show")
NotesSyncCheckButton:Enable()
NotesSyncCheckButtonText:SetTextColor(Notes_ColorBookSync[1],Notes_ColorBookSync[2],Notes_ColorBookSync[3])
NotesLockedCheckButton:Enable()
NotesReorderPageButton:Disable()
NotesCurPageNumText:Show()
NotesCurPageNumText:SetText(Notes_BookPage)
NotesPageSlash:Show()
NotesPageLabel:Show()
NotesMaxPageNumText:Show()
NotesMaxPageNumText:SetText(getn(Notes_Notes[bookidx]["book"]))
NotesCommSendButton:SetText("Print Book")
NotesGoPageButton:SetText("Go to")
 
NotesTOC:Show()
NotesText:Hide()
 
NotesPrevPageButton:Disable()
NotesNextPageButton:Enable()
NotesPrevPageButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
NotesNextPageButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
 
if getn(Notes_MultiSelect) > 0 then
NotesCompileButton:SetText("Compile")
else
NotesCompileButton:SetText("Extract All")
if Notes_Notes[Notes_Selected]["locked"] then NotesCompileButton:Disable() end
end
else
if not Notes_Notes[Notes_Selected]["sync"] and booksync then
NotesSyncCheckButton:SetChecked(1)
NotesSyncCheckButton:SetCheckedTexture("Interface/Buttons/UI-CheckBox-Check-Disabled")
NotesSyncCheckButtonText:SetText("Book Sync")
end
 
if Notes_BookID and type(Notes_Notes[Notes_Selected]["book"]) == "string" then
Notes_BookPages = Notes_Notes[bookidx]["book"]
 
local pages = getn(Notes_BookPages)
Notes_BookUIToggle("show")
NotesCompileButton:SetText("Extract")
NotesReorderPageButton:Enable()
NotesCurPageNumText:Show()
NotesCurPageNumText:SetText(Notes_BookPage)
NotesPageSlash:Show()
NotesPageLabel:Show()
NotesMaxPageNumText:Show()
NotesMaxPageNumText:SetText(pages)
 
if Notes_BookPage <= 0 then
NotesPrevPageButton:Disable()
NotesNextPageButton:Enable()
NotesPrevPageButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
NotesNextPageButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
 
elseif Notes_BookPage >= pages then
NotesPrevPageButton:Enable()
NotesNextPageButton:Disable()
NotesPrevPageButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
NotesNextPageButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
else
NotesPrevPageButton:Enable()
NotesNextPageButton:Enable()
NotesPrevPageButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
NotesNextPageButtonText:SetTextColor(Notes_ColorNormal[1],Notes_ColorNormal[2],Notes_ColorNormal[3])
end
else
Notes_BookUIToggle("hide")
NotesCompileButton:SetText("Compile")
end
end
 
if notecount > 0 then NotesDuplicateButton:Enable()
else NotesDuplicateButton:Disable() end
 
local synccolor = Notes_ColorSync
local synclockcolor = Notes_ColorSyncLocked
if type(Notes_Notes[Notes_Selected]["book"]) == "table" then
synccolor = Notes_ColorBookSync
synclockcolor = Notes_ColorBookSyncLocked
end
 
if notecount > 0 then NotesDuplicateButton:Enable() end
 
if unlockcount == 0 or booklock then
NotesSyncCheckButtonText:SetTextColor(synclockcolor[1],synclockcolor[2],synclockcolor[3])
NotesDeleteButton:Disable()
if booklock then
NotesLockedCheckButton:SetChecked(1)
NotesLockedCheckButton:Disable()
NotesLockedCheckButtonText:SetText("Book Locked")
NotesLockedCheckButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
end
if not Notes_Notes[Notes_Selected]["sync"] and booksync then
NotesSyncCheckButtonText:SetText("Book Broadcast Only")
else
NotesSyncCheckButtonText:SetText("Broadcast Only")
end
else
NotesSyncCheckButton:Enable()
NotesSyncCheckButtonText:SetTextColor(synccolor[1],synccolor[2],synccolor[3])
NotesDeleteButton:Enable()
end
 
if Notes_CommModes[Notes_SelectedComm][3]() then NotesCommSendButton:Enable()
else NotesCommSendButton:Disable() end
end
else
NotesCompileButton:Disable()
NotesDeleteButton:Disable()
NotesDuplicateButton:Disable()
NotesExecuteButton:Disable()
NotesMacroEditBox:SetText("")
NotesMacroEditBox:Hide()
NotesPrintMacroEditBox:SetText("")
NotesPrintMacroEditBox:Hide()
NotesSyncCheckButton:Disable()
NotesSyncCheckButton:SetChecked(false)
NotesSyncCheckButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
NotesLockedCheckButton:Disable()
NotesLockedCheckButton:SetChecked(false)
NotesLockedCheckButtonText:SetTextColor(Notes_ColorLocked[1],Notes_ColorLocked[2],Notes_ColorLocked[3])
NotesCommSendButton:Disable()
NotesTOC:Hide()
NotesText:Show()
Notes_BookUIToggle("hide")
end
 
if getn(Notes_PrintCache) > 0 then NotesStopPrintButton:Enable()
else NotesStopPrintButton:Disable() end
 
if Notes_LoadID and Notes_Undo[Notes_LoadID] and Notes_Undo[Notes_LoadID]["undo"] == true and
Notes_Selected and Notes_Notes[Notes_Selected] and not Notes_Notes[Notes_Selected]["locked"] then
NotesUndoButton:Enable()
else NotesUndoButton:Disable()end
 
if fullupdate then
if Notes_CommMode then
NotesCommButton:SetNormalTexture("Interface/ChatFrame/UI-ChatIcon-Chat-Down")
ShowUIPanel(NotesCommFrame)
 
NotesLuaFrame:ClearAllPoints()
NotesLuaFrame:SetPoint("TOP",NotesCommFrame,"BOTTOM",0,4)
 
UIDropDownMenu_SetSelectedValue(NotesCommDropDown, Notes_SelectedComm)
UIDropDownMenu_SetSelectedValue(NotesChanSelectDropDown, Notes_SelectedChan)
if Notes_CommModes[Notes_SelectedComm][1] == "Whisper" then
NotesWhisperEditBox:Show()
else
NotesWhisperEditBox:Hide()
end
 
if Notes_CommModes[Notes_SelectedComm][1] == "Channel" then
UIDropDownMenu_Initialize(NotesChanSelectDropDown, Notes_ChanSelectDropDownInitialize)
UIDropDownMenu_SetSelectedValue(NotesChanSelectDropDown, Notes_SelectedChan)
NotesChanSelectDropDown:Show()
else
NotesChanSelectDropDown:Hide()
end
 
if Notes_CommSpeedMode then
NotesCommSpeedCheckButton:SetChecked(1)
NotesCommFrame:SetHeight(70)
NotesCommSpeedSlider:Show()
NotesCommSpeedSlider:SetValue(Notes_PrintMaxInterval)
 
if Notes_PrintMaxInterval == 0 then
NotesCommSpeedLabel:SetText("Max Delay: [Off]")
elseif Notes_PrintMaxInterval == 5 then
NotesCommSpeedLabel:SetText("Max Delay: [Very Short]")
elseif Notes_PrintMaxInterval == 10 then
NotesCommSpeedLabel:SetText("Max Delay: [Short]")
elseif Notes_PrintMaxInterval == 15 then
NotesCommSpeedLabel:SetText("Max Delay: [Medium]")
elseif Notes_PrintMaxInterval == 20 then
NotesCommSpeedLabel:SetText("Max Delay: [Long]")
elseif Notes_PrintMaxInterval == 25 then
NotesCommSpeedLabel:SetText("Max Delay: [Very Long]")
end
else
NotesCommSpeedCheckButton:SetChecked(0)
NotesCommFrame:SetHeight(50)
NotesCommSpeedSlider:Hide()
end
else
NotesCommButton:SetNormalTexture("Interface/ChatFrame/UI-ChatIcon-Chat-Up")
HideUIPanel(NotesCommFrame)
 
NotesLuaFrame:ClearAllPoints()
NotesLuaFrame:SetPoint("TOP",NotesCommFrame,"TOP",0,0)
end
end
 
if Notes_CommMode then
if Notes_Selected then
local target = Notes_CommModes[Notes_SelectedComm][5]()
local str = "/PrintNote "..Notes_Notes[Notes_Selected]["id"]
if target then str = str.." "..target end
NotesPrintMacroEditBox:SetText(str)
NotesPrintMacroEditBox:Show()
end
end
 
if Notes_LUAMode then
NotesLUACheckButton:SetChecked(1)
ShowUIPanel(NotesLuaFrame)
 
if Notes_GetNoteIndex("1") then NotesLUASetupButton:Disable()
else NotesLUASetupButton:Enable() end
 
 
 
if Notes_Selected then
NotesMacroEditBox:SetText("/RunNote "..Notes_Notes[Notes_Selected]["id"])
NotesMacroEditBox:Show()
end
else
NotesLUACheckButton:SetChecked(nil)
HideUIPanel(NotesLuaFrame)
end
 
if getglobal("NotesExportFrame") then
if Notes_LUAMode then
NotesExportFrame:ClearAllPoints()
NotesExportFrame:SetPoint("TOP",NotesLuaFrame,"BOTTOM",0,4)
else
NotesExportFrame:ClearAllPoints()
NotesExportFrame:SetPoint("TOP",NotesLuaFrame,"TOP",0,0)
end
 
if Notes_ExportMode then
NotesExportCheckButton:SetChecked(1)
ShowUIPanel(NotesExportFrame)
 
NotesImportButton:SetText("Import ["..getn(Notes_Import).."] Notes")
if getn(Notes_Import) == 0 then NotesImportButton:Disable()
else NotesImportButton:Enable() end
 
if Notes_Selected then NotesExportButton:Enable()
else NotesExportButton:Disable() end
else
NotesExportCheckButton:SetChecked(nil)
NotesExportFrame:Hide()
HideUIPanel(NotesExportFrame)
end
end
 
if Notes_ShowIcon then
NotesIconCheckButton:SetChecked(1)
ShowUIPanel(NotesIconFrame)
else
NotesIconCheckButton:SetChecked(nil)
HideUIPanel(NotesIconFrame)
end
end
 
function Notes_ScrollBarUpdate(fullupdate)
local line -- 1 through 5 of our window to scroll
local lineplusoffset -- an index into our data calculated from the scroll offset
 
FauxScrollFrame_Update(NotesNoteScrollBar,getn(Notes_Notes)-Notes_TotalPages,5,16)
for line=1,5 do
lineplusoffset = line + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
if lineplusoffset <= getn(Notes_Notes) then
local title = Notes_Notes[lineplusoffset]["title"]
local descr = ""
 
if type(Notes_Notes[lineplusoffset]["book"]) == "table" then
local pages = getn(Notes_Notes[lineplusoffset]["book"])
getglobal("NotesNote"..line.."_BookIcon"):Show()
getglobal("NotesNote"..line.."_BookIcon"):SetTexture("Interface/Icons/INV_Misc_Book_0"..(mod(Notes_Notes[lineplusoffset]["id"],8)+1))
title = " "..title
descr = pages.." Page"
if pages ~= 1 then descr = descr.."s" end
else
getglobal("NotesNote"..line.."_BookIcon"):Hide()
descr = string.gsub(gsub(Notes_Notes[lineplusoffset]["text"],"\n"," "),"%s+"," ")
local olddescr = descr
if descr ~= nil then
descr = strsub(descr,0,Notes_DescrLen)
if strlen(olddescr) > Notes_DescrLen then
descr = descr.."..."
end
end
end
 
local oldtitle = title
if title ~= nil then
title = strsub(title,0,Notes_TitleLen)
if strlen(oldtitle) > Notes_TitleLen then
title = title.."..."
end
end
 
if Notes_Selected == lineplusoffset then
getglobal("NotesNote"..line.."NTex"):SetDesaturated(0)
getglobal("NotesNote"..line.."NTex"):SetAlpha(1)
elseif getn(Notes_MultiSelect) > 0 and Notes_InTable(Notes_MultiSelect,lineplusoffset) then
getglobal("NotesNote"..line.."NTex"):SetDesaturated(0)
getglobal("NotesNote"..line.."NTex"):SetAlpha(.4)
elseif Notes_BookID and Notes_GetNoteIndex(Notes_BookID) == lineplusoffset then
getglobal("NotesNote"..line.."NTex"):SetDesaturated(1)
getglobal("NotesNote"..line.."NTex"):SetAlpha(1)
else
getglobal("NotesNote"..line.."NTex"):SetDesaturated(0)
getglobal("NotesNote"..line.."NTex"):SetAlpha(0)
end
 
if type(Notes_Notes[lineplusoffset]["book"]) == "string" then
getglobal("NotesNote"..line):Hide()
else
local textcolor = Notes_GetColor(lineplusoffset)
 
getglobal("NotesNote"..line.."_Text"):SetTextColor(textcolor[1],textcolor[2],textcolor[3])
getglobal("NotesNote"..line.."_Text"):SetText(title)
getglobal("NotesNote"..line.."_Description"):SetText(descr)
getglobal("NotesNote"..line):Show()
end
else
getglobal("NotesNote"..line):Hide()
end
end
Notes_SetButtonState(fullupdate)
end
 
function Notes_GetColor(index)
if type(index) == "string" then
local num = index
if getglobal(index) then
num = tonumber(strsub(index,-1))
index = num + FauxScrollFrame_GetOffset(NotesNoteScrollBar)
end
end
 
local color = Notes_ColorNormal
if Notes_Notes[index] then
if Notes_Notes[index]["sync"] then
color = Notes_ColorSync
end
if Notes_Notes[index]["locked"] then
color = Notes_ColorLocked
end
if Notes_Notes[index]["sync"] and Notes_Notes[index]["locked"] then
color = Notes_ColorSyncLocked
end
 
if type(Notes_Notes[index]["book"]) == "table" then
color = Notes_ColorBook
if Notes_Notes[index]["sync"] then
color = Notes_ColorBookSync
end
if Notes_Notes[index]["locked"] then
color = Notes_ColorBookLocked
end
if Notes_Notes[index]["sync"] and Notes_Notes[index]["locked"] then
color = Notes_ColorBookSyncLocked
end
end
 
if type(Notes_Notes[index]["book"]) == "string" then
color = Notes_ColorLocked
end
end
return color
end
 
------------------------------------------
-- F) UI Functions
--[[
Notes_OnLoad - Register Notes with the system
Notes_OnUpdate - This function's body is defined dynamically
Notes_OnEvent - This function's body is defined dynamically
Notes_UIToggle - Hide or show Notes
Notes_HideNotes - Clear the selection when Notes is hidden
Notes_BookUIToggle - Hide or show the book navigation panel
Notes_CommUIToggle - Hide or show the communications panel
Notes_LUAUIToggle - Hide or show the LUA panel
Notes_IconDragging - Drag the minimap button
]]--
 
function Notes_OnLoad()
SlashCmdList["NOTES"] = Notes_UIToggle
SLASH_NOTES1 = "/notes"
SLASH_NOTES2 = "/note"
 
SlashCmdList["RUNNOTES"] = Notes_RunNote
SLASH_RUNNOTES1 = "/runnotes"
SLASH_RUNNOTES2 = "/runnote"
 
SlashCmdList["PRINTNOTES"] = Notes_PrintNote
SLASH_PRINTNOTES1 = "/printnotes"
SLASH_PRINTNOTES2 = "/printnote"
SLASH_PRINTNOTES3 = "/print"
 
SlashCmdList["STOPNOTES"] = Notes_StopPrinting
SLASH_STOPNOTES1 = "/stopnotes"
SLASH_STOPNOTES2 = "/stopnote"
SLASH_STOPNOTES3 = "/stop"
 
SlashCmdList["NOTESICONTOGGLE"] = Notes_IconToggle
SLASH_NOTESICONTOGGLE1 = "/notesicon"
 
SlashCmdList["NOTESDEBUG"] = Notes_Debug
SLASH_NOTESDEBUG1 = "/notesdebug"
 
NotesEvents:RegisterEvent('VARIABLES_LOADED')
NotesEvents:RegisterEvent('CHAT_MSG_CHANNEL_NOTICE')
NotesEvents:RegisterEvent('RAID_ROSTER_UPDATE')
NotesEvents:RegisterEvent('PLAYER_TARGET_CHANGED')
 
NotesEvents:RegisterEvent('CHAT_MSG_ADDON')
NotesEvents:RegisterEvent('CHAT_MSG_RAID')
NotesEvents:RegisterEvent('CHAT_MSG_RAID_LEADER')
NotesEvents:RegisterEvent('CHAT_MSG_PARTY')
NotesEvents:RegisterEvent('CHAT_MSG_GUILD')
NotesEvents:RegisterEvent('CHAT_MSG_WHISPER')
NotesEvents:RegisterEvent('CHAT_MSG_CHANNEL')
NotesEvents:RegisterEvent('CHAT_MSG_CHANNEL_LEAVE')
 
Notes_Import = Notes_Export
end
 
function Notes_OnUpdate()
-- This function's body is defined dynamically
end
 
function Notes_OnEvent()
-- This function's body is defined dynamically
end
 
function Notes_Debug()
RunScript("Notes_OnEvent = function() if arg1 == 'Notes' then Notes_Print(arg2) end end Notes_WarningPrint('Now printing sync debug info')")
end
 
function Notes_UIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesFrame:IsVisible()) then
Notes_HideNotes()
 
elseif mode == "show" or mode=="toggle" then
ShowUIPanel(NotesFrame)
Notes_SetButtonState(1)
end
end
 
function Notes_HideNotes()
Notes_LoadEmpty()
NotesFrame:Hide()
end
 
function Notes_BookUIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesBookFrame:IsVisible()) then
NotesBookFrame:Hide()
 
NotesCommFrame:ClearAllPoints()
NotesCommFrame:SetPoint("TOP",NotesBookFrame,"TOP",0,0)
 
elseif mode == "show" or mode=="toggle" then
NotesBookFrame:Show()
 
NotesCommFrame:ClearAllPoints()
NotesCommFrame:SetPoint("TOP",NotesBookFrame,"BOTTOM",0,4)
end
end
 
function Notes_CommUIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesCommFrame:IsVisible()) then
Notes_CommMode = false
Notes_SetButtonState(1)
 
NotesLuaFrame:ClearAllPoints()
NotesLuaFrame:SetPoint("TOP",NotesCommFrame,"TOP",0,0)
 
elseif mode == "show" or mode=="toggle" then
Notes_CommMode = true
Notes_SetButtonState(1)
 
NotesLuaFrame:ClearAllPoints()
NotesLuaFrame:SetPoint("TOP",NotesCommFrame,"BOTTOM",0,4)
end
end
 
function Notes_CommSpeedUIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and Notes_CommSpeedMode == true) then
Notes_CommSpeedMode = false
Notes_SetButtonState(1)
 
elseif mode == "show" or mode=="toggle" then
Notes_CommSpeedMode = true
Notes_SetButtonState(1)
end
end
 
 
function Notes_LUAUIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesLuaFrame:IsVisible()) then
Notes_LUAMode = false
Notes_SetButtonState()
 
if getglobal("NotesExportFrame") then
NotesExportFrame:ClearAllPoints()
NotesExportFrame:SetPoint("TOP",NotesLuaFrame,"TOP",0,0)
end
 
elseif mode == "show" or mode=="toggle" then
Notes_LUAMode = true
Notes_SetButtonState()
 
if getglobal("NotesExportFrame") then
NotesExportFrame:ClearAllPoints()
NotesExportFrame:SetPoint("TOP",NotesLuaFrame,"BOTTOM",0,4)
end
end
end
 
function Notes_IconToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesIconFrame:IsVisible()) then
Notes_ShowIcon = false
Notes_SetButtonState()
 
elseif mode == "show" or mode=="toggle" then
Notes_ShowIcon = true
Notes_SetButtonState()
end
end
 
function Notes_IconMove(iconpos)
if not Notes_IconDrag and not iconpos then return end
 
local xpos,ypos
if iconpos then
xpos = iconpos[1]
ypos = iconpos[2]
end
 
if not xpos and not ypos then
xpos,ypos = GetCursorPosition()
local xmin,ymin = Minimap:GetLeft(), Minimap:GetBottom()
 
xpos = xmin-xpos/Minimap:GetEffectiveScale()+70
ypos = ypos/Minimap:GetEffectiveScale()-ymin-70
 
local angle = math.deg(math.atan2(ypos,xpos)) or 0
 
xpos = 80*cos(angle)
ypos = 80*sin(angle)
 
Notes_IconPos = {xpos,ypos}
end
 
NotesIconFrame:SetPoint("TOPLEFT","Minimap","TOPLEFT",52-xpos,ypos-52)
end
 
------------------------------------------
-- G) Sync Functions
--[[
Notes_PrintNote - Wrapper for Notes_PrintSelected to be called from the command line
Notes_PrintSelected - Load a note into the print cache for later parsing
Notes_AddToCache - Add a message chunk in to the print cache
Notes_SendNote - Do the actual printing of a message chunk
Notes_StopPrinting - Clear the current print cache and notify other clients to stop syncing
Notes_ParseCache - Stagger printing from the messages in the print cache
Notes_ListenEvent - Listen to raid chat for synchronizing notes
Notes_InitChannelList - Initialize the list of channels for syncing
]]--
 
function Notes_PrintNote(cmd)
local args = Notes_Split(cmd," ")
local idx = Notes_GetNoteIndex(tostring(args[1]))
 
if not args[2] then args[2] = "Self" end
 
if idx ~= nil then Notes_PrintSelected(idx,nil,args[2]) else
Notes_ErrorPrint("Note ID ["..args[1].."] not found") end
end
 
function Notes_PrintSelected(idx,midx,chatmethod)
local index = Notes_Selected
local mindex = Notes_MultiSelect
local method = Notes_SelectedComm
if idx then index = idx end
if midx then mindex = midx end
if chatmethod then method = chatmethod end
 
if not index or not Notes_Notes[index] then return end
 
local selectstack = {}
local printstack = {}
 
table.insert(selectstack,index)
if getn(mindex) > 0 then
for i=1,getn(mindex) do
table.insert(selectstack,mindex[i])
end
end
 
for i=1,getn(selectstack) do
if type(Notes_Notes[selectstack[i]]["book"])=="table" and getn(Notes_Notes[selectstack[i]]["book"]) > 0 then
 
table.insert(printstack,selectstack[i])
for j=1,getn(Notes_Notes[selectstack[i]]["book"]) do
local pageidx = Notes_GetNoteIndex(Notes_Notes[selectstack[i]]["book"][j])
if pageidx then table.insert(printstack,pageidx) end
end
 
elseif type(Notes_Notes[selectstack[i]]["book"])=="string" then
table.insert(printstack,selectstack[i])
else
table.insert(printstack,selectstack[i])
end
end
 
local curbookid = "nil"
local curbookidx = nil
local booksync = false
local bookpages = 0
local bookpage = 0
 
for k=1,getn(printstack) do
 
if type(Notes_Notes[printstack[k]]["book"]) == "table" then
booksync = Notes_Notes[printstack[k]]["sync"]
curbooktitle = Notes_Notes[printstack[k]]["title"]
curbookid = Notes_Notes[printstack[k]]["id"]
curbookidx = printstack[k]
 
if booksync then
bookpage = 0
bookpages = getn(Notes_Notes[printstack[k]]["book"],",")
end
else
local note = Notes_Notes[printstack[k]]["text"]
local title = Notes_Notes[printstack[k]]["title"]
local notelength = strlen(note)
 
local notebits = Notes_Split(note,"\n")
local startloc = getn(Notes_PrintCache)+1
local curbooksync = false
 
if type(Notes_Notes[printstack[k]]["book"]) == "string" then
curbookid = Notes_Notes[printstack[k]]["book"]
curbookidx = Notes_GetNoteIndex(Notes_Notes[printstack[k]]["book"])
curbooktitle = Notes_Notes[curbookidx]["title"]
curbooksync = Notes_Notes[curbookidx]["sync"]
else
curbookid = "nil"
curbookidx = nil
curbooktitle = nil
curbooksync = nil
end
 
local sync = Notes_Notes[printstack[k]]["sync"] or curbooksync
 
if sync then
Notes_AddToCache("<NOTE::"..title.."::"..Notes_Notes[printstack[k]]["id"].."::"..notelength.."::"..Notes_DataToString(curbookid).."::"..Notes_DataToString(curbooktitle),sync,nil,method,title)
if booksync then
if Notes_InTable(Notes_Notes[curbookidx]["book"],Notes_Notes[printstack[k]]["id"]) then
bookpage = bookpage + 1
else
Notes_ErrorPrint("Added the wrong page to the queue")
Notes_StopPrinting()
end
end
end
 
for i=1,getn(notebits) do
if notebits[i] == "" then
notebits[i] = " "
notelength = notelength + 1
if sync then
Notes_AddToCache("<NOTE::"..title.."::"..Notes_Notes[printstack[k]]["id"].."::"..notelength.."::"..Notes_DataToString(curbookid).."::"..Notes_DataToString(curbooktitle),sync,startloc,method,title)
end
end
 
if strlen(notebits[i]) <= Notes_PrintMaxChunkLength then
Notes_AddToCache(notebits[i],sync,nil,method,title)
else
local notebitswords = Notes_Split(notebits[i]," ")
local notebitsword = ""
 
for j=1,getn(notebitswords) do
local testword = notebitsword.." "..notebitswords[j]
if strlen(testword) < Notes_PrintMaxChunkLength then
notebitsword = testword
else
Notes_AddToCache(notebitsword,sync,nil,method,title)
notebitsword = notebitswords[j]
 
notelength = notelength + 1
 
if sync then
Notes_AddToCache("<NOTE::"..title.."::"..Notes_Notes[printstack[k]]["id"].."::"..notelength.."::"..Notes_DataToString(curbookid).."::"..Notes_DataToString(curbooktitle),sync,startloc,method,title)
end
end
end
Notes_AddToCache(notebitsword,sync,nil,method,title)
end
end
 
if sync then
Notes_AddToCache("<NOTE::END",sync,nil,method,title)
end
 
if booksync then
if bookpage >= bookpages then
curbookid = "nil"
curbookidx = nil
curbooktitle = nil
booksync = false
bookpages = 0
bookpage = 0
end
end
end
end
Notes_SetButtonState()
end
 
function Notes_AddToCache(msg,sync,loc,chatmethod,title)
local method = Notes_SelectedComm
if not sync then sync = false end
if chatmethod then method = chatmethod end
 
local target = nil
if type(method) == "string" then
for i=1,getn(Notes_CommModes) do
if strlower(Notes_CommModes[i][1]) == strlower(method) then
target = method
method = i
break
end
end
if type(method) == "string" then
target = method
local index = GetChannelName(method)
if index ~= nil and index ~= 0 then method = 10
else method = 9 end
end
 
else
if Notes_CommModes[method][1] == "Target" then
target = UnitName("target")
end
 
if Notes_CommModes[method][1] == "Whisper" then
target = NotesWhisperEditBox:GetText()
end
 
if Notes_CommModes[method][1] == "Channel" then
target = Notes_ChanList[Notes_SelectedChan][2]
end
end
 
if not Notes_CommModes[method][3]() then return end
 
if not loc then
table.insert(Notes_PrintCache,{msg,method,target,sync,title})
else
Notes_PrintCache[loc] = {msg,method,target,sync,title}
end
end
 
function Notes_SendNote(msg,method,target)
if not method then method = 7 end -- DEFAULT TO SELF
 
if strsub(msg,1,7) == "<NOTE::" then
msg = msg.."::"..method.."::"..Notes_DataToString(target)..">"
 
if Notes_InGuild() then
SendAddonMessage("Notes",msg,"GUILD")
end
if (Notes_CommModes[method][4] ~= "RAID" or Notes_CommModes[method][4] ~= "PARTY") or
(Notes_InParty() and not Notes_InRaid()) or (Notes_InRaid() and (IsRaidLeader() or IsRaidOfficer())) then
SendAddonMessage("Notes",msg,"RAID")
end
if (Notes_InBattlefield()) then
SendAddonMessage("Notes",msg,"BATTLEGROUND")
end
else
Notes_CommModes[method][2](msg,target)
end
end
 
function Notes_StopPrinting()
if Notes_PrintCache[Notes_CacheIndex][4] then
Notes_SendNote("<NOTE::STOP",Notes_PrintCache[Notes_CacheIndex][2],Notes_PrintCache[Notes_CacheIndex][3])
end
 
Notes_WarningPrint("Printing halted for ["..Notes_PrintCache[Notes_CacheIndex][5].."]")
 
Notes_PrintCache = {}
Notes_CacheIndex = 1
Notes_LastUpdateTime = nil
Notes_PrintInterval = Notes_PrintMaxInterval
 
Notes_SetButtonState()
end
 
function Notes_ParseCache()
if getn(Notes_PrintCache) > 0 then
if not Notes_LastUpdateTime then
Notes_LastUpdateTime = 0
end
 
local curtime = GetTime()
if curtime-Notes_LastUpdateTime > Notes_PrintInterval then
if Notes_PrintCache[Notes_CacheIndex] ~= nil then
Notes_SendNote(Notes_PrintCache[Notes_CacheIndex][1],Notes_PrintCache[Notes_CacheIndex][2],Notes_PrintCache[Notes_CacheIndex][3])
 
if strsub(Notes_PrintCache[Notes_CacheIndex][1],1,7) == "<NOTE::" then
Notes_PrintInterval=1
else
Notes_PrintInterval=((Notes_PrintMaxInterval-Notes_PrintMinInterval)*
(strlen(Notes_PrintCache[Notes_CacheIndex][1])-Notes_PrintMinLength)/
(Notes_PrintMaxLength-Notes_PrintMinLength))+Notes_PrintMinInterval
end
 
if Notes_PrintInterval < Notes_PrintMinInterval then Notes_PrintInterval = Notes_PrintMinInterval end
if Notes_PrintInterval > Notes_PrintMaxInterval then Notes_PrintInterval = Notes_PrintMaxInterval end
 
if not Notes_PrintCache[Notes_CacheIndex+1] or
(Notes_PrintCache[Notes_CacheIndex+1] and Notes_PrintCache[Notes_CacheIndex+1][5] and
Notes_PrintCache[Notes_CacheIndex+1][5] ~= Notes_PrintCache[Notes_CacheIndex][5]) then
Notes_SuccessPrint("Printing finished for ["..Notes_PrintCache[Notes_CacheIndex][5].."]")
end
 
Notes_CacheIndex = Notes_CacheIndex + 1
Notes_LastUpdateTime = curtime
else
 
Notes_PrintCache = {}
Notes_CacheIndex = 1
Notes_LastUpdateTime = nil
Notes_PrintInterval = Notes_PrintMaxInterval
Notes_SetButtonState()
end
end
end
end
 
function Notes_ListenEvent()
if event == "VARIABLES_LOADED" then
Notes_ChanSelectDropDownOnLoad()
Notes_CommDropDownOnLoad()
Notes_IconMove(Notes_IconPos)
Notes_ScrollBarUpdate(1)
 
if Notes_GetNoteIndex("1") then Notes_RunNote("1") end
end
 
if event == "CHAT_MSG_CHANNEL_NOTICE" then
Notes_InitChannelList()
end
 
if (event=="PLAYER_TARGET_CHANGED" or event == "RAID_ROSTER_UPDATE") then
Notes_SetButtonState(1)
end
 
if event == "CHAT_MSG_ADDON" and arg1 == "Notes" then
parsebits = Notes_Split(strsub(arg2,0,-2),"::")
 
if Notes_ListenStack[arg4] and parsebits[2] == "END" then
if tonumber(strlen(strsub(Notes_ListenStack[arg4]["text"],0,-2))) == tonumber(Notes_ListenStack[arg4]["length"]) then
local success = Notes_NewNote(Notes_ListenStack[arg4]["title"],strsub(Notes_ListenStack[arg4]["text"],0,-2),1,false,Notes_ListenStack[arg4]["id"],Notes_ListenStack[arg4]["bookid"],Notes_ListenStack[arg4]["bookname"],true,true)
if success == 0 then
Notes_SuccessPrint("Sync successful for ["..Notes_ListenStack[arg4]["title"].."]")
end
 
Notes_SortAndReselect()
Notes_ScrollBarUpdate()
else
Notes_ErrorPrint("Sync failed for ["..Notes_ListenStack[arg4]["title"].."]")
end
Notes_ListenStack[arg4] = nil
 
elseif Notes_ListenStack[arg4] and parsebits[2] == "STOP" then
Notes_ErrorPrint("Sync halted for ["..Notes_ListenStack[arg4]["title"].."] at request of "..arg4)
Notes_ListenStack[arg4] = nil
else
if not Notes_ListenStack[arg4] and arg4 ~= UnitName("player") then
if not tonumber(parsebits[7]) then return end
 
local commtype = Notes_CommModes[tonumber(parsebits[7])][4]
local commtarget = nil
if parsebits[8] ~= "nil" then commtarget = strlower(parsebits[8]) end
 
if commtype and Notes_CommModes[tonumber(parsebits[7])][6](arg4,commtarget) then
Notes_ListenStack[arg4] = {}
Notes_ListenStack[arg4]["title"] = parsebits[2]
Notes_ListenStack[arg4]["id"] = parsebits[3]
Notes_ListenStack[arg4]["length"] = parsebits[4]
if parsebits[5] ~= "nil" and parsebits[6] ~= "nil" then
Notes_ListenStack[arg4]["bookid"] = parsebits[5]
Notes_ListenStack[arg4]["bookname"] = parsebits[6]
end
Notes_ListenStack[arg4]["commtype"] = commtype
Notes_ListenStack[arg4]["commtarget"] = commtarget
Notes_ListenStack[arg4]["text"] = ""
end
end
end
end
 
if strsub(event,1,9) == "CHAT_MSG_" and Notes_ListenStack[arg2] then
local commtype = Notes_ListenStack[arg2]["commtype"]
local commtarget = Notes_ListenStack[arg2]["commtarget"]
 
local subevent = strsub(event,10)
if subevent == "RAID_LEADER" then subevent = "RAID" end
 
if commtype == subevent then
if (commtype ~= "CHANNEL" and commtype ~= "WHISPER") or
(commtype == "CHANNEL" and commtarget and commtarget == strlower(arg9)) or
(commtype == "WHISPER" and commtarget and commtarget == strlower(UnitName("player"))) then
Notes_ListenStack[arg2]["text"] = Notes_ListenStack[arg2]["text"]..arg1.."\n"
end
 
if tonumber(strlen(strsub(Notes_ListenStack[arg2]["text"],0,-2))) > tonumber(Notes_ListenStack[arg2]["length"]) then
Notes_ErrorPrint("Sync failed for ["..Notes_ListenStack[arg2]["title"].."]")
Notes_ListenStack[arg2] = nil
end
end
end
end
 
function Notes_InitChannelList()
Notes_ChanList = {}
for i=1,10 do
local id, name = GetChannelName(i)
if id and id ~= 0 and name ~= nil then
table.insert(Notes_ChanList,{id,name,strlower(name)})
end
end
end
 
------------------------------------------
-- H) Notes Sorting Functions
--[[
Notes_HashNatSort - Natural sorting for numbers that appear after the last # of the value
Notes_HashNatTitleSort - Natural sorting for numbers that appear after the last # of the value's title
Notes_FindNextInSequence - Find the next value in a sequence
Notes_FindLast - Reverse string search
]]--
 
function Notes_HashNatSort(a,b)
local hashloca = Notes_FindLast(a,"#")
local hashlocb = Notes_FindLast(b,"#")
 
if not hashloca or not hashlocb then return a < b end
 
local astr = strsub(a,0,hashloca)
local bstr = strsub(b,0,hashlocb)
 
if astr ~= bstr then return a < b end
 
local anum = tonumber(strsub(a,hashloca+1))
local bnum = tonumber(strsub(b,hashlocb+1))
 
if not anum or not bnum then return a < b end
 
return anum < bnum
end
 
function Notes_HashNatTitleSort(a,b)
if type(a["book"]) == "table" and type(b["book"]) ~= "table" then return true end
if not a["book"] and type(b["book"]) == "string" then return true end
if type(b["book"]) == "table" and type(a["book"]) ~= "table" then return false end
if not b["book"] and type(a["book"]) == "string" then return false end
 
if a["title"] == b["title"] then return a["id"] < b["id"] end
 
local hashloca = Notes_FindLast(a["title"],"#")
local hashlocb = Notes_FindLast(b["title"],"#")
 
if not hashloca or not hashlocb then return a["title"] < b["title"] end
 
local astr = strsub(a["title"],0,hashloca)
local bstr = strsub(b["title"],0,hashlocb)
 
if astr ~= bstr then return a["title"] < b["title"] end
 
local anum = tonumber(strsub(a["title"],hashloca+1))
local bnum = tonumber(strsub(b["title"],hashlocb+1))
 
if not anum or not bnum then return a["title"] < b["title"] end
 
return anum < bnum
end
 
function Notes_HashNatNotesTitleSort(a,b)
if type(Notes_Notes[a]["book"]) == "table" and type(Notes_Notes[b]["book"]) ~= "table" then return true end
if not Notes_Notes[a]["book"] and type(Notes_Notes[b]["book"]) == "string" then return true end
if type(Notes_Notes[b]["book"]) == "table" and type(Notes_Notes[a]["book"]) ~= "table" then return false end
if not Notes_Notes[b]["book"] and type(Notes_Notes[a]["book"]) == "string" then return false end
 
if Notes_Notes[a]["title"] == Notes_Notes[b]["title"] then return Notes_Notes[a]["id"] < Notes_Notes[b]["id"] end
 
local hashloca = Notes_FindLast(Notes_Notes[a]["title"],"#")
local hashlocb = Notes_FindLast(Notes_Notes[b]["title"],"#")
 
if not hashloca or not hashlocb then return Notes_Notes[a]["title"] < Notes_Notes[b]["title"] end
 
local astr = strsub(Notes_Notes[a]["title"],0,hashloca)
local bstr = strsub(Notes_Notes[b]["title"],0,hashlocb)
 
if astr ~= bstr then return Notes_Notes[a]["title"] < Notes_Notes[b]["title"] end
 
local anum = tonumber(strsub(Notes_Notes[a]["title"],hashloca+1))
local bnum = tonumber(strsub(Notes_Notes[b]["title"],hashlocb+1))
 
if not anum or not bnum then return Notes_Notes[a]["title"] < Notes_Notes[b]["title"] end
 
return anum < bnum
end
 
function Notes_FindNextInSequence(title) -- requires to be in the format: "TITLE #<num>"
local titles = {}
local hashloc = Notes_FindLast(title,"#")
 
local prefix = strsub(title,0,hashloc)
local num = tonumber(strsub(title,hashloc+1))
 
title = prefix..num
 
for i=1,getn(Notes_Notes) do
table.insert(titles,Notes_Notes[i]["title"])
end
table.sort(titles,Notes_HashNatSort)
 
for i=1,getn(titles) do
if titles[i] == title then
num = num + 1
title = prefix..num
end
end
return title
end
 
function Notes_FindLast(haystack,needle)
local loc = string.find(haystack,needle)
i=1
while loc do
local testloc = string.find(haystack,needle,loc+1)
if testloc then loc = testloc
else break end
end
return loc
end
 
------------------------------------------
-- I) General Tools Functions
--[[
Notes_InTable - Check to see if an item is in an array
Notes_Split - Split a string into an array via a delimeter
Notes_Join - Join an array into a string via a delimeter
Notes_Merge - Merge two arrays into one
Notes_RaidPrint - Do your best to print to raid chat
Notes_Print - General purpose print function. Better than the default.
Notes_DataToString - Format data into a string for printing
Notes_StringToID - Create a number from a string
Notes_SuccessPrint - Print a success message
Notes_WarningPrint - Print a warning message
Notes_ErrorPrint - Print an error message
Notes_InParty - Am I in a party?
Notes_InRaid - Am I in a raid?
]]--
 
function Notes_InTable(haystack,needle,id,id2)
for key,hay in pairs(haystack) do
if id then hay = hay[id] end
if id2 then hay = hay[id2] end
if needle == hay then return key end
end
return nil
end
 
function Notes_GetNoteIndex(id)
if id == nil then return nil end
return Notes_InTable(Notes_Notes,id,"id")
end
 
function Notes_Split(text, delimiter)
local list = {}
local pos = 1
if strfind("", delimiter, 1) then -- this would result in endless loops
return text
end
while 1 do
local first, last = strfind(text, delimiter, pos)
if first then
tinsert(list, strsub(text, pos, first-1))
pos = last+1
else
tinsert(list, strsub(text, pos))
break
end
end
return list
end
 
function Notes_Join(list, delimiter)
local len = getn(list)
if len == 0 then return "" end
 
local string = list[1]
for i = 2, len do
string = string..delimiter..list[i]
end
return string
end
 
function Notes_Merge (table1, table2, start1, start2, end1, end2)
if not start1 then start1 = 1 end
if not start2 then start2 = 1 end
if not end1 then end1 = 10000 end
if not end2 then end2 = 10000 end
 
local mtable = {}
if type(table1) == "table" then
for i=max(1,start1),min(getn(table1),end1) do
table.insert(mtable,table1[i])
end
elseif type(table1) == "string" then
table.insert(mtable,table1)
end
 
if type(table2) == "table" then
for i=max(1,start2),min(getn(table2),end2) do
table.insert(mtable,table2[i])
end
elseif type(table2) == "string" then
table.insert(mtable,table2)
end
 
return mtable
end
 
function Notes_RaidPrint (msg)
local index = nil
 
if Notes_InRaid() then
ChatThrottleLib:SendChatMessage("NORMAL","",msg, "RAID")
 
elseif Notes_InParty() then
ChatThrottleLib:SendChatMessage("NORMAL","",msg, "PARTY")
else
Notes_Print(msg)
end
end
 
function Notes_Print(msg,channel,prefix)
if prefix == nil then prefix = "" end
 
if msg == nil then
Notes_ChanPrint(prefix.."nil",channel,.8,.8,.8)
 
elseif type(msg) == "number" then
Notes_ChanPrint(prefix..msg,channel,.8,.8,1)
 
elseif type(msg) == "string" then
Notes_ChanPrint(prefix..msg,channel,1,.9,.8)
 
elseif type(msg) == "boolean" and msg==false then
Notes_ChanPrint(prefix.."false",channel,1,.8,.8)
 
elseif type(msg) == "boolean" and msg==true then
Notes_ChanPrint(prefix.."true",channel,.8,1,.8)
 
elseif type(msg) == "table" then
for index,item in pairs(msg) do
if type(item) == "table" then
if getn(item) > 0 then
Notes_ChanPrint(prefix..index.." --TABLE--",channel)
Notes_Print(item,channel,prefix.."> ")
end
else
Notes_Print(item,channel,prefix..index.." ")
end
end
end
end
 
function Notes_ChanPrint(msg,chan,R,G,B)
if not msg then return end
if not chan then chan = "CONSOLE" end
 
chan = strupper(chan)
 
if chan == "RAID" then
if UnitInRaid("player") then SendChatMessage(msg,"RAID",GetDefaultLanguage("player"))
elseif GetPartyMember(1) then SendChatMessage(msg,"PARTY",GetDefaultLanguage("player")) end
 
elseif chan == "PARTY" then
SendChatMessage(msg,"PARTY",GetDefaultLanguage("player"))
 
elseif chan == "GUILD" then
SendChatMessage(msg,"GUILD",GetDefaultLanguage("player"))
 
elseif chan == "OFFICER" then
SendChatMessage(msg,"OFFICER",GetDefaultLanguage("player"))
 
elseif chan == "BATTLEGROUND" or chan == "BATTLEFIELD" or chan == "BG" then
SendChatMessage(msg,"BATTLEGROUND",GetDefaultLanguage("player"))
 
elseif chan == "CONSOLE" then
DEFAULT_CHAT_FRAME:AddMessage(msg,R,G,B)
else
local index = GetChannelName(chan)
if index ~= nil and index ~= 0 then
SendChatMessage(msg,"CHANNEL",GetDefaultLanguage("player"),index)
else
SendChatMessage(msg,"WHISPER",GetDefaultLanguage("player"),chan)
end
end
end
 
function Notes_DataToString(msg,prefix)
local str = ""
 
if prefix == nil then prefix = "" end
 
if msg == nil then
str = str..prefix.."nil\n"
 
elseif type(msg) == "number" then
str = str..prefix..msg.."\n"
 
elseif type(msg) == "string" then
str = str..prefix..msg.."\n"
 
elseif type(msg) == "boolean" and msg==false then
str = str..prefix.."false\n"
 
elseif type(msg) == "boolean" and msg==true then
str = str..prefix.."true\n"
 
elseif type(msg) == "table" then
for index,item in pairs(msg) do
if type(item) == "table" then
str = str..prefix..index.." --TABLE--\n"
str = str..Notes_DataToString(item,prefix.."> ")
else
str = str..Notes_DataToString(item,prefix..index.." \n")
end
end
end
return strsub(str,0,-2)
end
 
function Notes_StringToID(msg)
local id = 0
for i=1,strlen(msg) do
local val = strsub(msg,i,i)
if tonumber(val) then id = id + tonumber(val)*i end
if val=="a" or val=="A" then id = id + 1*i*10 end
if val=="b" or val=="B" then id = id + 2*i*10 end
if val=="c" or val=="C" then id = id + 3*i*10 end
if val=="d" or val=="D" then id = id + 4*i*10 end
if val=="e" or val=="E" then id = id + 5*i*10 end
if val=="f" or val=="F" then id = id + 6*i*10 end
if val=="g" or val=="G" then id = id + 7*i*10 end
if val=="h" or val=="H" then id = id + 8*i*10 end
if val=="i" or val=="I" then id = id + 9*i*10 end
if val=="j" or val=="J" then id = id + 10*i*10 end
if val=="k" or val=="K" then id = id + 11*i*10 end
if val=="l" or val=="L" then id = id + 12*i*10 end
if val=="m" or val=="M" then id = id + 13*i*10 end
if val=="n" or val=="N" then id = id + 14*i*10 end
if val=="o" or val=="O" then id = id + 15*i*10 end
if val=="p" or val=="P" then id = id + 16*i*10 end
if val=="q" or val=="Q" then id = id + 17*i*10 end
if val=="r" or val=="R" then id = id + 18*i*10 end
if val=="s" or val=="S" then id = id + 19*i*10 end
if val=="t" or val=="T" then id = id + 20*i*10 end
if val=="u" or val=="U" then id = id + 21*i*10 end
if val=="v" or val=="V" then id = id + 22*i*10 end
if val=="w" or val=="W" then id = id + 23*i*10 end
if val=="x" or val=="X" then id = id + 24*i*10 end
if val=="y" or val=="Y" then id = id + 25*i*10 end
if val=="z" or val=="Z" then id = id + 26*i*10 end
end
return id
end
 
function Notes_SuccessPrint(msg)
DEFAULT_CHAT_FRAME:AddMessage("<<Notes: "..msg..">>",.6,1,.3)
end
 
function Notes_WarningPrint(msg)
DEFAULT_CHAT_FRAME:AddMessage("<<Notes Warning: "..msg..">>",1,.8,0)
end
 
function Notes_ErrorPrint(msg)
DEFAULT_CHAT_FRAME:AddMessage("<<Notes Error: "..msg..">>",1,0,0)
end
 
function Notes_InParty(player)
if player then
player = strlower(player)
for i=1,4 do
local name = UnitName("party"..i)
if name and strlower(name) == player then
return 1
end
end
else
return GetPartyMember(1)
end
return nil
end
 
function Notes_InRaid(player)
if player then
player = strlower(player)
for i=1,GetNumRaidMembers() do
local name = GetRaidRosterInfo(i)
if name and strlower(name) == player then
return 1
end
end
else
return UnitInRaid("player")
end
return nil
end
 
function Notes_InGuild(player)
if player then
player = strlower(player)
for i=1,GetNumGuildMembers() do
local name = GetGuildRosterInfo(i)
if name and strlower(name) == player then
return 1
end
end
else
return IsInGuild()
end
return nil
end
 
function Notes_InBattlefield()
for i=1,3 do
if GetBattlefieldStatus(i)=="active" then
return true
end
end
end
 
------------------------------------------
-- J) Dropdown UI Functions
--[[
Notes_CommDropDownOnLoad - Set the width of the communications drop down and set starting value
Notes_CommDropDownOnClick - Set the communications method
Notes_CommDropDownInitialize - Prepare the communications drop down
Notes_ChanSelectDropDownOnLoad - Set the width of the communications channel drop down
Notes_ChanSelectDropDownOnClick - Set the communications channel
Notes_ChanSelectDropDownInitialize - Prepare the communications channel drop down
]]--
 
function Notes_CommDropDownOnLoad()
UIDropDownMenu_Initialize(NotesCommDropDown, Notes_CommDropDownInitialize)
UIDropDownMenu_SetSelectedValue(NotesCommDropDown, Notes_SelectedComm)
UIDropDownMenu_SetWidth(NotesCommDropDown, 70)
end
 
function Notes_CommDropDownOnClick()
UIDropDownMenu_SetSelectedValue(NotesCommDropDown, this.value)
Notes_SelectedComm = this.value
Notes_SetButtonState(1)
end
 
function Notes_CommDropDownInitialize()
local selectedValue = UIDropDownMenu_GetSelectedValue(NotesCommDropDown)
 
for i=1,getn(Notes_CommModes) do
local info = {}
info.text = Notes_CommModes[i][1]
info.func = Notes_CommDropDownOnClick
info.value = i
info.checked = nil
if ( info.value == selectedValue ) then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
end
 
function Notes_ChanSelectDropDownOnLoad()
UIDropDownMenu_SetWidth(NotesChanSelectDropDown, 115)
end
 
function Notes_ChanSelectDropDownOnClick()
UIDropDownMenu_SetSelectedValue(NotesChanSelectDropDown, this.value)
Notes_SelectedChan = this.value
Notes_SetButtonState(1)
end
 
function Notes_ChanSelectDropDownInitialize()
local selectedValue = UIDropDownMenu_GetSelectedValue(NotesChanSelectDropDown)
 
Notes_InitChannelList()
 
for i=1,getn(Notes_ChanList) do
if Notes_ChanList[i][2] ~= nil then
local info = {}
info.text = Notes_ChanList[i][1]..". "..Notes_ChanList[i][2]
info.func = Notes_ChanSelectDropDownOnClick
info.value = i
info.checked = nil
if ( info.value == selectedValue ) then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
end
end
 
------------------------------------------
-- K) Book UI Functions
--[[
Notes_CreateIndexPage - Create a table of contents for a book
Notes_TOCScrollBarUpdate - Update the scrolling table of contents on vertical scroll
Notes_ToggleTOCSelected - Load the new book page from the index page
Notes_LoadPrevPage - Load the previous book page
Notes_LoadNextPage - Load the next book page
Notes_GoToPage - Go to some random book page
Notes_ReorderPage - Move the current page to your target page
]]--
function Notes_CreateIndexPage(bookid)
local id = Notes_BookID
if bookid then id = bookid end
 
local index = Notes_GetNoteIndex(id)
if not index then return end
 
NotesTOCTitle_Text:SetText("["..Notes_Notes[index]["title"].."] Table of Contents")
 
Notes_TOCPageData = {}
for i=1,getn(Notes_BookPages) do
local idx = Notes_GetNoteIndex(Notes_BookPages[i])
if idx then
Notes_TOCPageData[i] = "Page "..i..") "
 
if Notes_Notes[idx]["sync"] then
Notes_TOCPageData[i] = Notes_TOCPageData[i].."[S]"
end
 
if Notes_Notes[idx]["locked"] then
Notes_TOCPageData[i] = Notes_TOCPageData[i].."[L]"
end
if Notes_Notes[idx]["sync"] or Notes_Notes[idx]["locked"] then
Notes_TOCPageData[i] = Notes_TOCPageData[i].." "
end
 
local title = Notes_Notes[idx]["title"]
local oldtitle = Notes_Notes[idx]["title"]
if title ~= nil then
title = strsub(title,0,Notes_TOCTitleLen)
if strlen(oldtitle) > Notes_TOCTitleLen then
title = title.."..."
end
end
 
Notes_TOCPageData[i] = Notes_TOCPageData[i]..title
end
end
Notes_TOCScrollBarUpdate()
end
 
function Notes_TOCScrollBarUpdate()
local line; -- 1 through 5 of our window to scroll
local lineplusoffset; -- an index into our data calculated from the scroll offset
 
if getn(Notes_TOCPageData) == 0 then return end
 
FauxScrollFrame_Update(NotesTOCScrollBar,getn(Notes_TOCPageData),16,16);
for line=1,16 do
lineplusoffset = line + FauxScrollFrame_GetOffset(NotesTOCScrollBar);
if lineplusoffset <= getn(Notes_TOCPageData) then
getglobal("NotesTOC"..line.."_Text"):SetText(Notes_TOCPageData[lineplusoffset]);
getglobal("NotesTOC"..line):Show();
else
getglobal("NotesTOC"..line):Hide();
end
end
end
 
function Notes_ToggleTOCSelected(button)
if button ~= nil then
local num = button
 
if getglobal(button) then
for i=2,1,-1 do
num = tonumber(strsub(button,-1*i))
if num ~= nil then break end
end
end
local toselect = num + FauxScrollFrame_GetOffset(NotesTOCScrollBar)
 
Notes_GoToPage(toselect)
end
end
 
function Notes_LoadPrevPage()
return Notes_GoToPage(Notes_BookPage - 1)
end
 
function Notes_LoadNextPage()
return Notes_GoToPage(Notes_BookPage + 1)
end
 
function Notes_GoToPage(pagenum)
if pagenum < 0 or pagenum > getn(Notes_BookPages) then
Notes_ErrorPrint("Page out of range (0-"..getn(Notes_BookPages)..")")
return Notes_SetButtonState(1)
end
 
Notes_MultiSelected = {}
 
Notes_BookPage = pagenum
Notes_LoadSelected(Notes_GetNoteIndex(Notes_BookPages[Notes_BookPage]))
if Notes_BookPage == 0 then
Notes_LoadSelected(Notes_GetNoteIndex(Notes_BookID))
 
elseif Notes_BookPage >= 1 and Notes_BookPage <= getn(Notes_BookPages) then
local idx = Notes_GetNoteIndex(Notes_BookPages[Notes_BookPage])
if idx then Notes_LoadSelected(idx) end
end
end
 
function Notes_ReorderPage(targetpage)
if not Notes_BookID or not Notes_Selected or not Notes_Notes[Notes_Selected] then return end
if targetpage < 1 or targetpage > getn(Notes_BookPages) then
Notes_ErrorPrint("Page out of range (1-"..getn(Notes_BookPages)..")")
return Notes_SetButtonState(1)
end
 
local bookidx = Notes_GetNoteIndex(Notes_BookID)
if not bookidx then return end
 
local pages = Notes_Notes[bookidx]["book"]
local curid = Notes_Notes[Notes_Selected]["id"]
local newpages = {}
local newpage = 1
local oldpage = 1
 
if targetpage == 1 then
table.insert(newpages,Notes_Notes[Notes_Selected]["id"])
newpage = newpage + 1
end
 
while true do
if pages[oldpage] ~= Notes_Notes[Notes_Selected]["id"] then
table.insert(newpages,pages[oldpage])
newpage = newpage + 1
end
 
if newpage == targetpage then
table.insert(newpages,Notes_Notes[Notes_Selected]["id"])
newpage = newpage + 1
end
 
oldpage = oldpage + 1
if not pages[oldpage] then break end
end
 
if getn(pages) == getn(newpages) then
Notes_Notes[bookidx]["book"] = newpages
Notes_GoToPage(targetpage)
end
end
branches/WotLK/Notes/Notes_Export.lua New file
0,0 → 1,2
 
Notes_Export = {}
branches/WotLK/Notes/readme.txt New file
0,0 → 1,111
Notes
Author: Vincent, Silver Hand
Full and due credit to the original author: Andersen, Silvermoon
 
Versions beyond 1.4a:
Notes is a fantastic mod that fills a needed niche. Since the original author seems to have abandoned the project and since it is too lovely a rose to let wither, I've taken over "keep alive" support for the mod. No new features are currently planned and any that may find their way into it will be on an 'as time allows' basis as this is not the only mod I maintain.
 
 
Summary:
Notes keeps track of notes in an easy-to-use GUI. Raid leaders and raid assistants can print notes to raid chat. Notes marked as "sync" will synchronize notes that are printed by someone else using the notes mod who set their note to 'sync'.
 
Furthermore, any note can be executed as a LUA script and called via a macro. The macro script necessary to execute the Notes script is easily visible. This
essentially makes a nearly unlimited macro length. Notes can also hook into the OnUpdate and OnEvent calls that WoW makes while playing for easy Add-On Development.
 
Thanks to Salamengel and Merphle (Author of LuaPad) for inspiration. Thanks to Sumul and Shinsplitter for suggestions.
 
use /notes to show the GUI
 
Features:
* Multiple notes and easy navigation
* Lock notes
* Revert changes to last time the GUI was shown
* Fully functional LUA mode/macro editor
* Note synchronization
 
---
 
Note: Printing a note will stagger the information printed so raiders have a time to read the entire note as you print it. If you type a message while a note is being printed, syncing will not work.
 
Note: Notes will not sync via whispers or channels between versions 1.1x and 1.2+
 
---
 
Change Log:
v1.4a (9/30/08)
* Updated for Wrath of the Lich King
 
v1.4 (12/11/06)
* Remaining bugs with syncing through channels should be sorted out
* Added version number to minimap tooltip
* Increased the delay times at all max delay settings by a small amount
 
v1.3a (11/17/06)
* Added slider to adjust auto delay amount for printing
* Increased default delay for long message chunks
* Success message printed when a Note has completed printing
* Integrated ChatThrottleLib for support when printing with
auto delay off
 
v1.3 (9/27/06)
* Changed the "Go to" page button to link back to the table
of contents page if you are currently looking at a page
> Pressing enter after manually typing in a page will
still navigate to that page
* The Table of Contents page is a scrollable list of page links,
which should make book navigation much better
* Fixed sync errors with channels
* Raid syncing will no longer report an error to people in your
guild who are in different raids
* GUI updates will no longer execute when the GUI is not visible.
 
v1.2 (9/5/06)
* Removed the checkbox to show or hide the minimap icon
* Added /notesicon command to toggle the minimap button
* Added /printnote and /stop commands
* Added a /printnote macro selection box
* Added bindings to toggle the Notes UI and minimap button
* Added support for importing/exporting of mods via files
(email your notes)
* Pages of books that are set to "sync" will sync, even if
the page itself is not set to sync
* Pressing esc will lose focus from the frame. Pressing esc
when no field has focus will hide the UI
* Notes errors will be less annoying
* Notes should be syncable from the raid leader again
 
v1.1b (8/23/06)
* Removed bogus debugging print functions
 
v1.1a (8/23/06)
* Added custom note import capability
 
v1.1 (8/22/06)
* Added a minimap icon
* Added "Notebooks" (Compilations of notes)
* Added multi-select for delete/copy/compile
* Added communications panel to send notes to
other places. Syncing messages only hidden
when notes are synced through raid chat
* Added stop printing button
* Added /runnote command
* Changed the "important" label to "sync"
Any previously "important" notes will
be considered normal after installing
this version
* Notes that exist must be flagged as sync to
overwrite it with new data. Notes that are
not marked sync will not be overwritten
* Able to sync multiple notes simultaneously now
(Still only one note can be synchronized at
at a time per person)
* Fixed undo functionality
* Sync notes uses the new CHAT_MSG_ADDON channel
* The LUA - Setup note is now executed on start up
This means don't type ReloadUI() in this note
 
v1.0a (8/12/06):
* Bug fix for notes synchronization
 
v1.0 (8/10/06):
* Initial revision
branches/WotLK/Notes/Bindings.xml New file
0,0 → 1,8
<Bindings>
<Binding name="NOTESTOGGLE" description="Toggle the Notes UI" header="NOTESHEADER">
Notes_UIToggle()
</Binding>
<Binding name="NOTESICONTOGGLE" description="Toggle the Notes Minimap Button">
Notes_IconToggle()
</Binding>
</Bindings>
branches/WotLK/Notes/ChatThrottleLib.lua New file
0,0 → 1,457
--
-- ChatThrottleLib by Mikk
--
-- Manages AddOn chat output to keep player from getting kicked off.
--
-- ChatThrottleLib.SendChatMessage/.SendAddonMessage functions that accept
-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
--
-- Priorities get an equal share of available bandwidth when fully loaded.
-- Communication channels are separated on extension+chattype+destination and
-- get round-robinned. (Destination only matters for whispers and channels,
-- obviously)
--
-- Will install hooks for SendChatMessage and SendAdd[Oo]nMessage to measure
-- bandwidth bypassing the library and use less bandwidth itself.
--
--
-- Fully embeddable library. Just copy this file into your addon directory,
-- add it to the .toc, and it's done.
--
-- Can run as a standalone addon also, but, really, just embed it! :-)
--
 
local CTL_VERSION = 11
 
local MAX_CPS = 1000 -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 1000.
local MSG_OVERHEAD = 40 -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
 
local BURST = 8000 -- WoW's server buffer seems to be about 32KB. Let's use 25% of it for our lib.
 
local MIN_FPS = 20 -- Reduce output CPS to half (and don't burst) if FPS drops below this value
 
if(ChatThrottleLib and ChatThrottleLib.version>=CTL_VERSION) then
-- There's already a newer (or same) version loaded. Buh-bye.
return;
end
 
 
 
if(not ChatThrottleLib) then
ChatThrottleLib = {}
end
 
ChatThrottleLib.version=CTL_VERSION;
 
 
-----------------------------------------------------------------------
-- Double-linked ring implementation
 
local Ring = {}
local RingMeta = { __index=Ring }
 
function Ring:New()
local ret = {}
setmetatable(ret, RingMeta)
return ret;
end
 
function Ring:Add(obj) -- Append at the "far end" of the ring (aka just before the current position)
if(self.pos) then
obj.prev = self.pos.prev;
obj.prev.next = obj;
obj.next = self.pos;
obj.next.prev = obj;
else
obj.next = obj;
obj.prev = obj;
self.pos = obj;
end
end
 
function Ring:Remove(obj)
obj.next.prev = obj.prev;
obj.prev.next = obj.next;
if(self.pos == obj) then
self.pos = obj.next;
if(self.pos == obj) then
self.pos = nil;
end
end
end
 
 
 
-----------------------------------------------------------------------
-- Recycling bin for pipes (kept in a linked list because that's
-- how they're worked with in the rotating rings; just reusing members)
 
ChatThrottleLib.PipeBin = { count=0 }
 
function ChatThrottleLib.PipeBin:Put(pipe)
for i=getn(pipe),1,-1 do
tremove(pipe, i);
end
pipe.prev = nil;
pipe.next = self.list;
self.list = pipe;
self.count = self.count+1;
end
 
function ChatThrottleLib.PipeBin:Get()
if(self.list) then
local ret = self.list;
self.list = ret.next;
ret.next=nil;
self.count = self.count - 1;
return ret;
end
return {};
end
 
function ChatThrottleLib.PipeBin:Tidy()
if(self.count < 25) then
return;
end
 
if(self.count > 100) then
n=self.count-90;
else
n=10;
end
for i=2,n do
self.list = self.list.next;
end
local delme = self.list;
self.list = self.list.next;
delme.next = nil;
end
 
 
 
 
-----------------------------------------------------------------------
-- Recycling bin for messages
 
ChatThrottleLib.MsgBin = {}
 
function ChatThrottleLib.MsgBin:Put(msg)
msg.text = nil;
tinsert(self, msg);
end
 
function ChatThrottleLib.MsgBin:Get()
local ret = tremove(self, getn(self));
if(ret) then return ret; end
return {};
end
 
function ChatThrottleLib.MsgBin:Tidy()
if(getn(self)<50) then
return;
end
if(getn(self)>150) then -- "can't happen" but ...
for n=getn(self),120,-1 do
tremove(self,n);
end
else
for n=getn(self),getn(self)-20,-1 do
tremove(self,n);
end
end
end
 
 
-----------------------------------------------------------------------
-- ChatThrottleLib:Init
-- Initialize queues, set up frame for OnUpdate, etc
 
 
function ChatThrottleLib:Init()
 
-- Set up queues
if(not self.Prio) then
self.Prio = {}
self.Prio["ALERT"] = { ByName={}, Ring = Ring:New(), avail=0 };
self.Prio["NORMAL"] = { ByName={}, Ring = Ring:New(), avail=0 };
self.Prio["BULK"] = { ByName={}, Ring = Ring:New(), avail=0 };
end
 
-- v4: total send counters per priority
for _,Prio in pairs(self.Prio) do
Prio.nTotalSent = Prio.nTotalSent or 0;
end
 
self.avail = self.avail or 0; -- v5
self.nTotalSent = self.nTotalSent or 0; -- v5
 
 
-- Set up a frame to get OnUpdate events
if(not self.Frame) then
self.Frame = CreateFrame("Frame");
self.Frame:Hide();
end
self.Frame.Show = self.Frame.Show; -- cache for speed
self.Frame.Hide = self.Frame.Hide; -- cache for speed
self.Frame:SetScript("OnUpdate", self.OnUpdate);
self.Frame:SetScript("OnEvent", self.OnEvent); -- v11: Monitor P_E_W so we can throttle hard for a few seconds
self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD");
self.OnUpdateDelay=0;
self.LastAvailUpdate=GetTime();
self.HardThrottlingBeginTime=GetTime(); -- v11: Throttle hard for a few seconds after startup
 
-- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
if(not self.ORIG_SendChatMessage) then
--SendChatMessage
self.ORIG_SendChatMessage = SendChatMessage;
SendChatMessage = function(a1,a2,a3,a4) return ChatThrottleLib.Hook_SendChatMessage(a1,a2,a3,a4); end
--SendAdd[Oo]nMessage
if(SendAddonMessage or SendAddOnMessage) then -- v10: don't pretend like it doesn't exist if it doesn't!
self.ORIG_SendAddonMessage = SendAddonMessage or SendAddOnMessage;
SendAddonMessage = function(a1,a2,a3) return ChatThrottleLib.Hook_SendAddonMessage(a1,a2,a3); end
if(SendAddOnMessage) then -- in case Slouken changes his mind...
SendAddOnMessage = SendAddonMessage;
end
end
end
self.nBypass = 0;
end
 
 
-----------------------------------------------------------------------
-- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination)
local self = ChatThrottleLib;
local size = strlen(text or "") + strlen(chattype or "") + strlen(destination or "") + 40;
self.avail = self.avail - size;
self.nBypass = self.nBypass + size;
return self.ORIG_SendChatMessage(text, chattype, language, destination);
end
function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype)
local self = ChatThrottleLib;
local size = strlen(text or "") + strlen(chattype or "") + strlen(prefix or "") + 40;
self.avail = self.avail - size;
self.nBypass = self.nBypass + size;
 
--DEFAULT_CHAT_FRAME:AddMessage(prefix.." "..text.." "..chattype)
 
return self.ORIG_SendAddonMessage(prefix, text, chattype);
end
 
 
 
-----------------------------------------------------------------------
-- ChatThrottleLib:UpdateAvail
-- Update self.avail with how much bandwidth is currently available
 
function ChatThrottleLib:UpdateAvail()
local now = GetTime();
local newavail = MAX_CPS * (now-self.LastAvailUpdate);
 
if(now - self.HardThrottlingBeginTime < 5) then
-- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
self.avail = min(self.avail + (newavail*0.1), MAX_CPS*0.5);
elseif(GetFramerate()<MIN_FPS) then -- GetFrameRate call takes ~0.002 secs
newavail = newavail * 0.5;
self.avail = min(MAX_CPS, self.avail + newavail);
self.bChoking = true; -- just for stats
else
self.avail = min(BURST, self.avail + newavail);
self.bChoking = false;
end
 
self.avail = max(self.avail, 0-(MAX_CPS*2)); -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
self.LastAvailUpdate = now;
 
return self.avail;
end
 
 
-----------------------------------------------------------------------
-- Despooling logic
 
function ChatThrottleLib:Despool(Prio)
local ring = Prio.Ring;
while(ring.pos and Prio.avail>ring.pos[1].nSize) do
local msg = tremove(Prio.Ring.pos, 1);
if(not Prio.Ring.pos[1]) then
local pipe = Prio.Ring.pos;
Prio.Ring:Remove(pipe);
Prio.ByName[pipe.name] = nil;
self.PipeBin:Put(pipe);
else
Prio.Ring.pos = Prio.Ring.pos.next;
end
Prio.avail = Prio.avail - msg.nSize;
msg.f(msg[1], msg[2], msg[3], msg[4]);
Prio.nTotalSent = Prio.nTotalSent + msg.nSize;
self.MsgBin:Put(msg);
end
end
 
 
function ChatThrottleLib:OnEvent()
-- v11: We know that the rate limiter is touchy after login. Assume that it's touch after zoning, too.
self = ChatThrottleLib;
if(event == "PLAYER_ENTERING_WORLD") then
self.HardThrottlingBeginTime=GetTime(); -- Throttle hard for a few seconds after zoning
self.avail = 0;
end
end
 
 
function ChatThrottleLib:OnUpdate()
self = ChatThrottleLib;
 
self.OnUpdateDelay = self.OnUpdateDelay + arg1;
if(self.OnUpdateDelay < 0.08) then
return;
end
self.OnUpdateDelay = 0;
 
self:UpdateAvail();
 
if(self.avail<0) then
return; -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
end
 
-- See how many of or priorities have queued messages
local n=0;
for prioname,Prio in pairs(self.Prio) do
if(Prio.Ring.pos or Prio.avail<0) then
n=n+1;
end
end
 
-- Anything queued still?
if(n<1) then
-- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
for prioname,Prio in pairs(self.Prio) do
self.avail = self.avail + Prio.avail;
Prio.avail = 0;
end
self.bQueueing = false;
self.Frame:Hide();
return;
end
 
-- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
local avail= self.avail/n;
self.avail = 0;
 
for prioname,Prio in pairs(self.Prio) do
if(Prio.Ring.pos or Prio.avail<0) then
Prio.avail = Prio.avail + avail;
if(Prio.Ring.pos and Prio.avail>Prio.Ring.pos[1].nSize) then
self:Despool(Prio);
end
end
end
 
-- Expire recycled tables if needed
self.MsgBin:Tidy();
self.PipeBin:Tidy();
end
 
 
 
 
-----------------------------------------------------------------------
-- Spooling logic
 
 
function ChatThrottleLib:Enqueue(prioname, pipename, msg)
local Prio = self.Prio[prioname];
local pipe = Prio.ByName[pipename];
if(not pipe) then
self.Frame:Show();
pipe = self.PipeBin:Get();
pipe.name = pipename;
Prio.ByName[pipename] = pipe;
Prio.Ring:Add(pipe);
end
 
tinsert(pipe, msg);
 
self.bQueueing = true;
end
 
 
 
function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination)
if(not (self and prio and text and self.Prio[prio] ) ) then
error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix" or nil, "text"[, "chattype"[, "language"[, "destination"]]]', 0);
end
 
prefix = prefix or tostring(this); -- each frame gets its own queue if prefix is not given
 
local nSize = strlen(text) + MSG_OVERHEAD;
 
-- Check if there's room in the global available bandwidth gauge to send directly
if(not self.bQueueing and nSize < self:UpdateAvail()) then
self.avail = self.avail - nSize;
self.ORIG_SendChatMessage(text, chattype, language, destination);
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize;
return;
end
 
-- Message needs to be queued
msg=self.MsgBin:Get();
msg.f=self.ORIG_SendChatMessage
msg[1]=text;
msg[2]=chattype or "SAY";
msg[3]=language;
msg[4]=destination;
msg.n = 4
msg.nSize = nSize;
 
self:Enqueue(prio, string.format("%s/%s/%s", prefix, chattype, destination or ""), msg);
end
 
 
function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype)
if(not (self and prio and prefix and text and chattype and self.Prio[prio] ) ) then
error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype")', 0);
end
 
local nSize = strlen(prefix) + 1 + strlen(text) + MSG_OVERHEAD;
 
-- Check if there's room in the global available bandwidth gauge to send directly
if(not self.bQueueing and nSize < self:UpdateAvail()) then
self.avail = self.avail - nSize;
self.ORIG_SendAddonMessage(prefix, text, chattype);
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize;
return;
end
 
-- Message needs to be queued
msg=self.MsgBin:Get();
msg.f=self.ORIG_SendAddonMessage;
msg[1]=prefix;
msg[2]=text;
msg[3]=chattype;
msg.n = 3
msg.nSize = nSize;
 
self:Enqueue(prio, string.format("%s/%s", prefix, chattype), msg);
end
 
 
 
 
-----------------------------------------------------------------------
-- Get the ball rolling!
 
ChatThrottleLib:Init();
 
--[[ WoWBench debugging snippet
if(WOWB_VER) then
local function SayTimer()
print("SAY: "..GetTime().." "..arg1);
end
ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer);
ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY");
end
]]
 
 
branches/WotLK/Notes/Notes.toc New file
0,0 → 1,8
## Interface: 30000
## Title: Notes
## Version: 1.4a
## Notes: Take Note!
## SavedVariables: Notes_Notes, Notes_LUAMode, Notes_CommMode, Notes_CommSpeedMode, Notes_ExportMode, Notes_PrintMaxInterval
## SavedVariablesPerCharacter: Notes_IconPos, Notes_ShowIcon, Notes_SelectedComm, Notes_SelectedChan
Notes.xml
ChatThrottleLib.lua
branches/WotLK/Notes_Export/Notes_Export.xml New file
0,0 → 1,106
<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/C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
<Script file="Notes_Export.lua"/>
 
<CheckButton name="NotesExportCheckButton" inherits="NotesCheckButtonTemplate" checked="false" hidden="false" parent="NotesBGFrame">
<Size>
<AbsDimension x="15" y="15"></AbsDimension>
</Size>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Import/Export")
--this:SetParent("NotesBGFrame")
</OnLoad>
<OnClick>
Notes_ExportUIToggle()
</OnClick>
</Scripts>
<Anchors>
<Anchor point="TOPRIGHT" relativeTo="NotesLUACheckButton" relativePoint="BOTTOMRIGHT">
<Offset>
<AbsDimension x="0" y="4"/>
</Offset>
</Anchor>
</Anchors>
</CheckButton>
 
 
<Frame name="NotesExportFrameTemplate" enableMouse="true" virtual="true" hidden="true">
<Size>
<AbsDimension x="330" y="30"/>
</Size>
<Backdrop bgFile="Interface\TutorialFrame\TutorialFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="32"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Frames>
<Button name="NotesImportButton" inherits="NotesLargeButtonTemplate" text="Import [0] Notes">
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="5" y="6"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_ImportNotes();
</OnClick>
</Scripts>
</Button>
<Button name="NotesExportButton" inherits="NotesLargeButtonTemplate" text="Export Selected">
<Anchors>
<Anchor point="LEFT" relativeTo="NotesImportButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-2" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_ExportSelected();
</OnClick>
</Scripts>
</Button>
<Button name="NotesExportCloseButton" inherits="NotesLargeButtonTemplate" text="Exit Export">
<Size>
<AbsDimension x="77" y="18"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="NotesExportButton" relativePoint="RIGHT">
<Offset>
<AbsDimension x="-1" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Notes_ExportUIToggle("hide")
</OnClick>
</Scripts>
</Button>
</Frames>
</Frame>
 
 
<Frame name="NotesExportFrame" inherits="NotesExportFrameTemplate" hidden="false" parent="NotesFrame">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="NotesLUAFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="4"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
this:SetPoint("TOPLEFT","NotesLuaFrame","BOTTOMLEFT",0,4)
</OnLoad>
</Scripts>
</Frame>
</Ui>
branches/WotLK/Notes_Export/Notes_Export.lua New file
0,0 → 1,102
function Notes_ExportUIToggle(mode)
if mode==nil or mode=="" then mode = "toggle" end
 
if mode == "hide" or (mode=="toggle" and NotesExportFrame:IsVisible()) then
Notes_ExportMode = false
Notes_SetButtonState()
 
elseif mode == "show" or mode=="toggle" then
Notes_ExportMode = true
Notes_SetButtonState()
end
end
 
function Notes_ImportNotes()
local idlookup = {}
local titlelookup = {}
 
local startid = Notes_MakeNoteID()
 
for i=1,getn(Notes_Import) do
idlookup[Notes_Import[i]["id"]] = tostring(tonumber(Notes_Import[i]["id"]) + tonumber(math.mod(math.abs(tonumber(startid)-tonumber(Notes_Import[1]["id"])),999999)))
titlelookup[idlookup[Notes_Import[i]["id"]]] = Notes_Import[i]["title"]
end
for i=1,getn(Notes_Import) do
local bookname = nil
Notes_Import[i]["id"] = idlookup[Notes_Import[i]["id"]]
if type(Notes_Import[i]["book"]) == "table" then
local newpages = {}
for j=1,getn(Notes_Import[i]["book"]) do
if idlookup[Notes_Import[i]["book"][j]] then
table.insert(newpages,idlookup[Notes_Import[i]["book"][j]])
end
end
Notes_Import[i]["book"] = newpages
 
elseif type(Notes_Import[i]["book"]) == "string" then
if idlookup[Notes_Import[i]["book"]] then
Notes_Import[i]["book"] = idlookup[Notes_Import[i]["book"]]
bookname = titlelookup[Notes_Import[i]["book"]]
else
Notes_Import[i]["book"] = false
end
end
Notes_NewNote(Notes_Import[i]["title"],Notes_Import[i]["text"],Notes_Import[i]["sync"],Notes_Import[i]["locked"],Notes_Import[i]["id"],Notes_Import[i]["book"],bookname)
end
 
for i=1,getn(Notes_Import) do
if type(Notes_Import[i]["book"]) ~= "string" then
local idx = Notes_GetNoteIndex(Notes_Import[i]["id"])
if idx and idx ~= Notes_Selected then
table.insert(Notes_MultiSelect,idx)
end
end
end
Notes_ScrollBarUpdate()
end
 
function Notes_ExportSelected(idx,midx)
local index = Notes_Selected
local mindex = Notes_MultiSelect
if idx then index = idx end
if midx then mindex = midx end
 
if not index or not Notes_Notes[index] then Notes_ErrorPrint("No notes selected") return end
 
Notes_Export = {}
 
local selectstack = {}
local exportstack = {}
local bookcount = 0
 
table.insert(selectstack,index)
if getn(mindex) > 0 then
for i=1,getn(mindex) do
table.insert(selectstack,mindex[i])
end
end
 
for i=1,getn(selectstack) do
if type(Notes_Notes[selectstack[i]]["book"])=="table" then
if getn(Notes_Notes[selectstack[i]]["book"]) > 0 then
for j=1,getn(Notes_Notes[selectstack[i]]["book"]) do
local pageidx = Notes_GetNoteIndex(Notes_Notes[selectstack[i]]["book"][j])
if pageidx then
table.insert(exportstack,pageidx)
end
end
end
bookcount = bookcount + 1
table.insert(exportstack,selectstack[i])
else
table.insert(exportstack,selectstack[i])
end
end
 
for i=1,getn(exportstack) do
table.insert(Notes_Export,Notes_Notes[exportstack[i]])
end
Notes_SuccessPrint(getn(exportstack) - bookcount.." notes and "..bookcount.." books exported")
Notes_SuccessPrint("You must log out or reload your UI to save the changes.")
Notes_SuccessPrint("Move the Notes_Export.lua file in your SavedVariables directory into the Interface/AddOns/Notes directory.")
end
branches/WotLK/Notes_Export/Notes_Export.toc New file
0,0 → 1,7
## Interface: 30000
## Title: Notes Import/Export
## Version: 1.2
## Notes: Export Notes
## Dependencies: Notes
## SavedVariables: Notes_Export
Notes_Export.xml