292 lines
10 KiB
Lua
292 lines
10 KiB
Lua
AUTOCOMPLETE_MAX_BUTTONS = 5;
|
|
|
|
AUTOCOMPLETE_FLAG_NONE = 0x00000000;
|
|
AUTOCOMPLETE_FLAG_IN_GROUP = 0x00000001;
|
|
AUTOCOMPLETE_FLAG_IN_GUILD = 0x00000002;
|
|
AUTOCOMPLETE_FLAG_FRIEND = 0x00000004;
|
|
AUTOCOMPLETE_FLAG_BNET = 0x00000008;
|
|
AUTOCOMPLETE_FLAG_INTERACTED_WITH = 0x00000010;
|
|
AUTOCOMPLETE_FLAG_ONLINE = 0x00000020;
|
|
AUTOCOMPLETE_FLAG_ALL = 0xffffffff;
|
|
|
|
AUTOCOMPLETE_LIST_TEMPLATES = {
|
|
ALL = {
|
|
include = AUTOCOMPLETE_FLAG_ALL,
|
|
exclude = AUTOCOMPLETE_FLAG_NONE,
|
|
},
|
|
ALL_CHARS = {
|
|
include = AUTOCOMPLETE_FLAG_ALL,
|
|
exclude = AUTOCOMPLETE_FLAG_BNET,
|
|
},
|
|
ONLINE = {
|
|
include = AUTOCOMPLETE_FLAG_ONLINE,
|
|
exclude = AUTOCOMPLETE_FLAG_NONE,
|
|
},
|
|
ONLINE_NOT_IN_GROUP = {
|
|
include = AUTOCOMPLETE_FLAG_ONLINE,
|
|
exclude = bit.bor(AUTOCOMPLETE_FLAG_IN_GROUP,AUTOCOMPLETE_FLAG_BNET),
|
|
},
|
|
ONLINE_NOT_IN_GUILD = {
|
|
include = AUTOCOMPLETE_FLAG_ONLINE,
|
|
exclude = bit.bor(AUTOCOMPLETE_FLAG_IN_GUILD,AUTOCOMPLETE_FLAG_BNET),
|
|
},
|
|
NOT_FRIEND = {
|
|
include = AUTOCOMPLETE_FLAG_ALL,
|
|
exclude = bit.bor(AUTOCOMPLETE_FLAG_FRIEND,AUTOCOMPLETE_FLAG_BNET);
|
|
},
|
|
IN_GROUP = {
|
|
include = AUTOCOMPLETE_FLAG_IN_GROUP,
|
|
exclude = AUTOCOMPLETE_FLAG_BNET,
|
|
},
|
|
IN_GUILD = {
|
|
include = AUTOCOMPLETE_FLAG_IN_GUILD,
|
|
exclude = AUTOCOMPLETE_FLAG_BNET,
|
|
},
|
|
FRIEND = {
|
|
include = AUTOCOMPLETE_FLAG_FRIEND,
|
|
exclude = AUTOCOMPLETE_FLAG_BNET,
|
|
},
|
|
FRIEND_NOT_GUILD = {
|
|
include = AUTOCOMPLETE_FLAG_FRIEND,
|
|
exclude = bit.bor(AUTOCOMPLETE_FLAG_IN_GUILD,AUTOCOMPLETE_FLAG_BNET),
|
|
},
|
|
FRIEND_AND_GUILD = {
|
|
include = bit.bor(AUTOCOMPLETE_FLAG_FRIEND, AUTOCOMPLETE_FLAG_IN_GUILD),
|
|
exclude = AUTOCOMPLETE_FLAG_BNET,
|
|
},
|
|
}
|
|
|
|
AUTOCOMPLETE_LIST = {};
|
|
local AUTOCOMPLETE_LIST = AUTOCOMPLETE_LIST;
|
|
AUTOCOMPLETE_LIST.ALL = AUTOCOMPLETE_LIST_TEMPLATES.ALL;
|
|
AUTOCOMPLETE_LIST.WHISPER = AUTOCOMPLETE_LIST_TEMPLATES.ONLINE;
|
|
AUTOCOMPLETE_LIST.INVITE = AUTOCOMPLETE_LIST_TEMPLATES.ONLINE_NOT_IN_GROUP;
|
|
AUTOCOMPLETE_LIST.UNINVITE = AUTOCOMPLETE_LIST_TEMPLATES.IN_GROUP;
|
|
AUTOCOMPLETE_LIST.PROMOTE = AUTOCOMPLETE_LIST_TEMPLATES.IN_GROUP;
|
|
AUTOCOMPLETE_LIST.TEAM_INVITE = AUTOCOMPLETE_LIST_TEMPLATES.ONLINE;
|
|
AUTOCOMPLETE_LIST.GUILD_INVITE = AUTOCOMPLETE_LIST_TEMPLATES.ONLINE_NOT_IN_GUILD;
|
|
AUTOCOMPLETE_LIST.GUILD_UNINVITE = AUTOCOMPLETE_LIST_TEMPLATES.IN_GUILD;
|
|
AUTOCOMPLETE_LIST.GUILD_PROMOTE = AUTOCOMPLETE_LIST_TEMPLATES.IN_GUILD;
|
|
AUTOCOMPLETE_LIST.GUILD_DEMOTE = AUTOCOMPLETE_LIST_TEMPLATES.IN_GUILD;
|
|
AUTOCOMPLETE_LIST.GUILD_LEADER = AUTOCOMPLETE_LIST_TEMPLATES.IN_GUILD;
|
|
AUTOCOMPLETE_LIST.ADDFRIEND = AUTOCOMPLETE_LIST_TEMPLATES.NOT_FRIEND;
|
|
AUTOCOMPLETE_LIST.REMOVEFRIEND = AUTOCOMPLETE_LIST_TEMPLATES.FRIEND;
|
|
AUTOCOMPLETE_LIST.CHANINVITE = AUTOCOMPLETE_LIST_TEMPLATES.ONLINE;
|
|
AUTOCOMPLETE_LIST.MAIL = AUTOCOMPLETE_LIST_TEMPLATES.ALL_CHARS;
|
|
AUTOCOMPLETE_LIST.CALENDARGUILDEVENT= AUTOCOMPLETE_LIST_TEMPLATES.FRIEND_NOT_GUILD;
|
|
AUTOCOMPLETE_LIST.CALENDAREVENT = AUTOCOMPLETE_LIST_TEMPLATES.FRIEND_AND_GUILD;
|
|
|
|
AUTOCOMPLETE_SIMPLE_REGEX = "(.+)";
|
|
AUTOCOMPLETE_SIMPLE_FORMAT_REGEX = "%1$s";
|
|
|
|
AUTOCOMPLETE_DEFAULT_Y_OFFSET = 3;
|
|
function AutoComplete_OnLoad(self)
|
|
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
|
|
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
|
|
|
|
self.maxHeight = AUTOCOMPLETE_MAX_BUTTONS * AutoCompleteButton1:GetHeight();
|
|
|
|
AutoCompleteInstructions:SetText("|cffbbbbbb"..PRESS_TAB.."|r");
|
|
end
|
|
|
|
function AutoComplete_Update(parent, text, cursorPosition)
|
|
local self = AutoCompleteBox;
|
|
local attachPoint;
|
|
if ( not parent.autoCompleteParams ) then
|
|
return;
|
|
end
|
|
if ( not text or text == "" ) then
|
|
AutoComplete_HideIfAttachedTo(parent);
|
|
return;
|
|
end
|
|
if ( cursorPosition <= strlen(text) ) then
|
|
self:SetParent(parent);
|
|
if(self.parent ~= parent) then
|
|
AutoComplete_SetSelectedIndex(self, 0);
|
|
end
|
|
|
|
if ( parent:GetBottom() - self.maxHeight <= (AUTOCOMPLETE_DEFAULT_Y_OFFSET + 10) ) then --10 is a magic number from the offset of AutoCompleteButton1.
|
|
attachPoint = "ABOVE";
|
|
else
|
|
attachPoint = "BELOW";
|
|
end
|
|
if ( (self.parent ~= parent) or (self.attachPoint ~= attachPoint) ) then
|
|
if ( attachPoint == "ABOVE" ) then
|
|
self:ClearAllPoints();
|
|
self:SetPoint("BOTTOMLEFT", parent, "TOPLEFT", parent.autoCompleteXOffset or 0, parent.autoCompleteYOffset or -AUTOCOMPLETE_DEFAULT_Y_OFFSET);
|
|
elseif ( attachPoint == "BELOW" ) then
|
|
self:ClearAllPoints();
|
|
self:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", parent.autoCompleteXOffset or 0, parent.autoCompleteYOffset or AUTOCOMPLETE_DEFAULT_Y_OFFSET);
|
|
end
|
|
self.attachPoint = attachPoint;
|
|
end
|
|
|
|
self.parent = parent;
|
|
--We ask for one more result than we need so that we know whether or not results are continued
|
|
AutoComplete_UpdateResults(self,
|
|
GetAutoCompleteResults(text, parent.autoCompleteParams.include, parent.autoCompleteParams.exclude, AUTOCOMPLETE_MAX_BUTTONS+1, cursorPosition));
|
|
else
|
|
AutoComplete_HideIfAttachedTo(parent);
|
|
end
|
|
end
|
|
|
|
function AutoComplete_HideIfAttachedTo(parent)
|
|
local self = AutoCompleteBox;
|
|
if ( self.parent == parent ) then
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
function AutoComplete_SetSelectedIndex(self, index)
|
|
self.selectedIndex = index;
|
|
for i=1, AUTOCOMPLETE_MAX_BUTTONS do
|
|
_G["AutoCompleteButton"..i]:UnlockHighlight();
|
|
end
|
|
if ( index ~= 0 ) then
|
|
_G["AutoCompleteButton"..index]:LockHighlight();
|
|
end
|
|
end
|
|
|
|
function AutoComplete_GetSelectedIndex(self)
|
|
return self.selectedIndex;
|
|
end
|
|
|
|
function AutoComplete_GetNumResults(self)
|
|
return self.numResults;
|
|
end
|
|
|
|
function AutoComplete_UpdateResults(self, ...)
|
|
local totalReturns = select("#", ...);
|
|
local numReturns = min(totalReturns, AUTOCOMPLETE_MAX_BUTTONS);
|
|
local maxWidth = 120;
|
|
for i=1, numReturns do
|
|
local button = _G["AutoCompleteButton"..i]
|
|
button:SetText(select(i, ...));
|
|
maxWidth = max(maxWidth, button:GetFontString():GetWidth()+30);
|
|
button:Enable();
|
|
button:Show();
|
|
end
|
|
for i = numReturns+1, AUTOCOMPLETE_MAX_BUTTONS do
|
|
_G["AutoCompleteButton"..i]:Hide();
|
|
end
|
|
if ( numReturns > 0 ) then
|
|
if ( not self:IsShown() ) then
|
|
AutoComplete_SetSelectedIndex(self, 0);
|
|
end
|
|
maxWidth = max(maxWidth, AutoCompleteInstructions:GetStringWidth()+30);
|
|
self:SetHeight(numReturns*AutoCompleteButton1:GetHeight()+35);
|
|
self:SetWidth(maxWidth);
|
|
self:Show();
|
|
else
|
|
self:Hide();
|
|
end
|
|
if ( totalReturns > AUTOCOMPLETE_MAX_BUTTONS ) then
|
|
local button = _G["AutoCompleteButton"..AUTOCOMPLETE_MAX_BUTTONS];
|
|
button:SetText(CONTINUED);
|
|
button:Disable();
|
|
self.numResults = numReturns - 1;
|
|
else
|
|
self.numResults = numReturns;
|
|
end
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnTabPressed(editBox)
|
|
local autoComplete = AutoCompleteBox;
|
|
if ( autoComplete:IsShown() and autoComplete.parent == editBox ) then
|
|
local selectedIndex = AutoComplete_GetSelectedIndex(autoComplete);
|
|
local numReturns = AutoComplete_GetNumResults(autoComplete);
|
|
if ( IsShiftKeyDown() ) then
|
|
local nextNum = mod(selectedIndex - 1, numReturns);
|
|
if ( nextNum == 0 ) then
|
|
nextNum = numReturns;
|
|
end
|
|
AutoComplete_SetSelectedIndex(autoComplete, nextNum);
|
|
else
|
|
local nextNum = mod(selectedIndex + 1, numReturns);
|
|
if ( nextNum == 0 ) then
|
|
nextNum = numReturns;
|
|
end
|
|
AutoComplete_SetSelectedIndex(autoComplete, nextNum)
|
|
end
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnEnterPressed(self)
|
|
local autoComplete = AutoCompleteBox;
|
|
if ( autoComplete:IsShown() and (autoComplete.parent == self) and (AutoComplete_GetSelectedIndex(autoComplete) ~= 0) ) then
|
|
AutoCompleteButton_OnClick(_G["AutoCompleteButton"..AutoComplete_GetSelectedIndex(autoComplete)]);
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnTextChanged(self, userInput)
|
|
if ( userInput ) then
|
|
AutoComplete_Update(self, self:GetText(), self:GetUTF8CursorPosition());
|
|
end
|
|
end
|
|
|
|
function AutoCompleteEditBox_AddHighlightedText(editBox, text)
|
|
if ( not editBox.autoCompleteParams ) then
|
|
return;
|
|
end
|
|
local editBoxText = editBox:GetText();
|
|
local utf8Position = editBox:GetUTF8CursorPosition();
|
|
local nameToShow = GetAutoCompleteResults(text, editBox.autoCompleteParams.include, editBox.autoCompleteParams.exclude, 1, utf8Position);
|
|
if ( nameToShow ) then
|
|
--We're going to be setting the text programatically which will clear the userInput flag on the editBox. So we want to manually update the dropdown before we change the text.
|
|
AutoComplete_Update(editBox, editBoxText, utf8Position);
|
|
|
|
local newText = string.gsub(editBoxText, editBox.autoCompleteRegex or AUTOCOMPLETE_SIMPLE_REGEX,
|
|
--DEBUG FIXME - This likely won't work with X-server whispers.
|
|
string.format(editBox.autoCompleteFormatRegex or AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, nameToShow,
|
|
string.match(editBoxText, editBox.autoCompleteRegex or AUTOCOMPLETE_SIMPLE_REGEX)),
|
|
1)
|
|
editBox:SetText(newText);
|
|
editBox:HighlightText(strlen(editBoxText), strlen(newText)); --This won't work if there is more after the name, but we aren't enabling this for normal chat (yet). Please fix me when we do.
|
|
editBox:SetCursorPosition(strlen(editBoxText));
|
|
end
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnChar(self)
|
|
if (self.addHighlightedText and self:GetUTF8CursorPosition() == strlenutf8(self:GetText())) then
|
|
AutoCompleteEditBox_AddHighlightedText(self, self:GetText());
|
|
end
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnEditFocusLost(self)
|
|
AutoComplete_HideIfAttachedTo(self);
|
|
end
|
|
|
|
function AutoCompleteEditBox_OnEscapePressed(self)
|
|
local autoComplete = AutoCompleteBox;
|
|
if ( autoComplete:IsShown() and autoComplete.parent == self ) then
|
|
AutoComplete_HideIfAttachedTo(self);
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function AutoCompleteButton_OnClick(self)
|
|
local autoComplete = self:GetParent();
|
|
local editBox = autoComplete.parent;
|
|
local editBoxText = editBox:GetText();
|
|
|
|
--The following is used to replace "/whisper ar message here" with "/whisper Arenai message here"
|
|
local newText = string.gsub(editBoxText, editBox.autoCompleteRegex or AUTOCOMPLETE_SIMPLE_REGEX,
|
|
string.format(editBox.autoCompleteFormatRegex or AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, self:GetText(),
|
|
string.match(editBoxText, editBox.autoCompleteRegex or AUTOCOMPLETE_SIMPLE_REGEX)),
|
|
1)
|
|
|
|
if ( editBox.addSpaceToAutoComplete ) then
|
|
newText = newText.." ";
|
|
end
|
|
|
|
editBox:SetText(newText);
|
|
--When we change the text, we move to the end, so we'll be consistent and move to the end if we don't change it as well.
|
|
editBox:SetCursorPosition(strlen(newText));
|
|
autoComplete:Hide();
|
|
end
|