WoWInterface SVN PhanxConfigWidgets

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /branches
    from Rev 54 to Rev 55
    Reverse comparison

Rev 54 → Rev 55

AceGUI-3.0-Spell-EditBox/Spells-Editbox.lua New file
0,0 → 1,12
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Spell_EditBox"
local Version = 3
 
-- I know theres a better way of doing this than this, but not sure for the time being, works fine though!
local function Constructor()
return AceGUI:Create("Predictor_Base")
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/AceGUI-3.0-Spell-EditBox.xml New file
0,0 → 1,8
<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/">
<Script file="SpellLoader.lua"/>
<Script file="EditBox-Core.lua"/>
<Script file="Spells-EditBox.lua"/>
<Script file="Casts-EditBox.lua"/>
<Script file="Auras-EditBox.lua"/>
<Script file="Player-EditBox.lua"/>
</Ui>
Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/AceGUI-3.0-Spell-EditBox.lua New file
0,0 → 1,475
-- Based off of AceGUI-3.0 EditBox
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Spell_EditBox"
local Version = 2
local PREDICTION_ROWS = 10
local totalSpellsLoaded, spellLoader = 0
local spells, indexedSpells, visiblePredicters = {}, {}, {}
 
-- Defined blew
local searchSpells
 
-- Spells have to gradually be loaded in to prevent the client from lagging, this starts as soon as one widget is shown
-- as of 3.1 the spellID goes up to ~66,000 which means it'll take around 5 - 10 seconds for it to load them all
-- Given users have to actually move the mouse, type what they want etc
-- it should result in them not noticing it does not have all the spell data yet
local function startLoading()
if( spellLoader ) then return end
 
spellLoader = CreateFrame("Frame")
spellLoader.timeElapsed = 0
spellLoader.totalInvalid = 0
spellLoader.index = 0
spellLoader:SetScript("OnUpdate", function(self, elapsed)
self.timeElapsed = self.timeElapsed + elapsed
if( self.timeElapsed < 0.10 ) then return end
self.timeElapsed = self.timeElapsed - 0.10
 
-- Too many invalid spells found will assume we found all there is that we can
if( self.totalInvalid >= 5000 ) then
self:Hide()
return
end
 
-- Load as many spells in
local spellsLoaded = totalSpellsLoaded
for i=spellLoader.index + 1, spellLoader.index + 500 do
local name, _, icon = GetSpellInfo(i)
 
-- The majority of spells that use the engineer gear icon are actually invalid spells that we can easily ignore
-- since there are ~12000 not counting duplicate names that use this icon it's worthwhile to filter out these spells
self.totalInvalid = self.totalInvalid + 1
if( name and icon ~= "Interface\\Icons\\Trade_Engineering" ) then
name = string.lower(name)
 
if( not spells[name] ) then
spells[string.lower(name)] = i
table.insert(indexedSpells, name)
 
totalSpellsLoaded = totalSpellsLoaded + 1
self.totalInvalid = 0
end
end
end
 
-- Every ~1 second it will update any visible predicters to make up for the fact that the data is delay loaded
if( spellLoader.index % 5000 == 0 ) then
for predicter in pairs(visiblePredicters) do
searchSpells(predicter, predicter.lastQuery)
end
end
 
-- Increment and do it all over!
spellLoader.index = spellLoader.index + 500
end)
end
 
-- Search for spells quickly
searchSpells = function(self, query)
for _, button in pairs(self.buttons) do button:Hide() end
 
local usedButtons = 0
for i=1, totalSpellsLoaded do
local name = indexedSpells[i]
if( string.match(name, query) ) then
usedButtons = usedButtons + 1
 
local spellName, _, spellIcon = GetSpellInfo(spells[name])
local button = self.buttons[usedButtons]
button.spellID = spells[name]
button:SetFormattedText("|T%s:20:20:2:11|t %s", spellIcon, spellName)
button:Show()
 
if( usedButtons ~= self.selectedButton ) then
button:UnlockHighlight()
 
if( GameTooltip:IsOwned(button) ) then
GameTooltip:Hide()
end
end
 
-- Ran out of text to suggest :<
if( usedButtons >= PREDICTION_ROWS ) then break end
end
end
 
if( usedButtons > 0 ) then
self:SetHeight(15 + usedButtons * 17)
self:Show()
else
self:Hide()
end
 
self.lastQuery = query
self.usedButtons = usedButtons
end
 
local function OnAcquire(self)
self:SetHeight(26)
self:SetWidth(200)
self:SetDisabled(false)
self:SetLabel()
self.showbutton = true
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.predictFrame:Hide()
 
self:SetDisabled(false)
end
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
 
local function ShowButton(self)
if( self.lasttext ~= "" ) then
self.editbox.predictFrame.selectedButton = nil
searchSpells(self.editbox.predictFrame, "^" .. string.lower(self.lasttext))
else
self.editbox.predictFrame:Hide()
end
 
if( self.showbutton ) then
self.button:Show()
self.editbox:SetTextInsets(0,20,3,3)
end
end
 
local function HideButton(self)
self.button:Hide()
self.editbox:SetTextInsets(0,0,3,3)
self.editbox.predictFrame:Hide()
end
 
local function EditBox_OnEnterPressed(this)
if( this.predictFrame.selectedButton ) then
this.predictFrame.buttons[this.predictFrame.selectedButton]:Click()
this.predictFrame.selectedButton = nil
return
end
 
local self = this.obj
local value = this:GetText()
local cancel = self:Fire("OnEnterPressed", value)
if( not cancel ) then
HideButton(self)
end
 
-- Reactivate the cursor, odds are if you're adding auras you're adding multiple auras
self.editbox:SetFocus()
end
 
local function Button_OnClick(this)
local editbox = this.obj.editbox
 
editbox:ClearFocus()
EditBox_OnEnterPressed(editbox)
end
 
local function Predicter_OnHide(self)
-- Allow users to use arrows to go back and forth again without the fix
self.editbox:SetAltArrowKeyMode(false)
 
visiblePredicters[self] = nil
 
ClearOverrideBindings(self)
end
 
local function Predicter_OnShow(self)
-- I'm pretty sure this is completely against what you are supposed to actually do :>
visiblePredicters[self] = true
 
-- User doesn't need arrow keys, and by doing this the override binding for up/down arrows will work properly
self.editbox:SetAltArrowKeyMode(true)
 
SetOverrideBindingClick(self, true, "DOWN", self:GetName(), 1)
SetOverrideBindingClick(self, true, "UP", self:GetName(), -1)
SetOverrideBindingClick(self, true, "LEFT", self:GetName(), "LEFT")
SetOverrideBindingClick(self, true, "RIGHT", self:GetName(), "RIGHT")
end
 
-- When using SetAltArrowKeyMode the ability to move the cursor with left and right is disabled, this reenables that
-- since the cursor position automatically can't go below 0, this is a quick and easy fix
local function EditBox_FixCursorPosition(self, direction)
self:SetCursorPosition(self:GetCursorPosition() + (direction == "RIGHT" and 1 or -1))
end
 
local function EditBox_OnReceiveDrag(this)
local self = this.obj
local type, id, info = GetCursorInfo()
if( type == "spell" ) then
local name = GetSpellName(id, info)
self:SetText(name)
self:Fire("OnEnterPressed" ,name)
ClearCursor()
end
HideButton(self)
AceGUI:ClearFocus()
end
 
local function EditBox_OnTextChanged(this)
local self = this.obj
local value = this:GetText()
if( value ~= self.lasttext ) then
self:Fire("OnTextChanged", value)
self.lasttext = value
ShowButton(self)
end
end
 
local function EditBox_OnEditFocusLost(self)
Predicter_OnHide(self.predictFrame)
end
 
local function EditBox_OnEditFocusGained(self)
if( self.predictFrame:IsVisible() ) then
Predicter_OnShow(self.predictFrame)
end
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if( disabled ) then
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5, 0.5, 0.5)
self.label:SetTextColor(0.5, 0.5, 0.5)
else
self.editbox:EnableMouse(true)
self.editbox:SetTextColor(1, 1, 1)
self.label:SetTextColor(1, 0.82, 0)
end
end
 
local function SetText(self, text, cursor)
self.lasttext = text or ""
self.editbox:SetText(self.lasttext)
self.editbox:SetCursorPosition(cursor or 0)
 
HideButton(self)
end
 
local function SetLabel(self, text)
if( text and text ~= "" ) then
self.label:SetText(text)
self.label:Show()
self.editbox:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 7, -18)
self:SetHeight(44)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editbox:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 7, 0)
self:SetHeight(26)
self.alignoffset = 12
end
end
 
local function Predicter_OnMouseDown(self, direction)
if( direction == "LEFT" or direction == "RIGHT" ) then
EditBox_FixCursorPosition(self.editbox, direction)
return
end
 
self.selectedButton = (self.selectedButton or 0) + direction
if( self.selectedButton > self.usedButtons ) then
self.selectedButton = 1
elseif( self.selectedButton <= 0 ) then
self.selectedButton = self.usedButtons
end
 
for i=1, self.usedButtons do
local button = self.buttons[i]
if( i == self.selectedButton ) then
button:LockHighlight()
 
GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT")
GameTooltip:SetHyperlink("spell:" .. button.spellID)
else
button:UnlockHighlight()
 
if( GameTooltip:IsOwned(button) ) then
GameTooltip:Hide()
end
end
end
end
 
local function Spell_OnClick(self)
local name = GetSpellInfo(self.spellID)
 
SetText(self.parent.obj, name, string.len(name))
self.parent.obj:Fire("OnEnterPressed", name)
end
 
local function Spell_OnEnter(self)
self.parent.selectedButton = nil
self:LockHighlight()
 
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
GameTooltip:SetHyperlink("spell:" .. self.spellID)
end
 
local function Spell_OnLeave(self)
self:UnlockHighlight()
GameTooltip:Hide()
end
 
local predicterBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
edgeSize = 26,
insets = {left = 9, right = 9, top = 9, bottom = 9},
}
 
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
local editbox = CreateFrame("EditBox", "AceGUI30SpellEditBox" .. num, frame, "InputBoxTemplate")
 
-- Don't feel like looking up the specific callbacks for when a widget resizes, so going to be creative with SetPoint instead!
local predictFrame = CreateFrame("Frame", "AceGUI30SpellEditBox" .. num .. "Predicter", UIParent)
predictFrame:SetBackdrop(predicterBackdrop)
predictFrame:SetBackdropColor(0, 0, 0, 0.85)
predictFrame:SetWidth(1)
predictFrame:SetHeight(150)
predictFrame:SetPoint("TOPLEFT", editbox, "BOTTOMLEFT", -6, 0)
predictFrame:SetPoint("TOPRIGHT", editbox, "BOTTOMRIGHT", 0, 0)
predictFrame:SetFrameStrata("TOOLTIP")
predictFrame:Hide()
 
predictFrame.buttons = {}
 
for i=1, PREDICTION_ROWS do
local button = CreateFrame("Button", nil, predictFrame)
button:SetHeight(17)
button:SetWidth(1)
button:SetPushedTextOffset(-2, 0)
button:SetScript("OnClick", Spell_OnClick)
button:SetScript("OnEnter", Spell_OnEnter)
button:SetScript("OnLeave", Spell_OnLeave)
button.parent = predictFrame
button.editbox = editbox
button:Hide()
 
if( i > 1 ) then
button:SetPoint("TOPLEFT", predictFrame.buttons[i - 1], "BOTTOMLEFT", 0, 0)
button:SetPoint("TOPRIGHT", predictFrame.buttons[i - 1], "BOTTOMRIGHT", 0, 0)
else
button:SetPoint("TOPLEFT", predictFrame, 8, -8)
button:SetPoint("TOPRIGHT", predictFrame, -7, 0)
end
 
-- Create the actual text
local text = button:CreateFontString(nil, "ARTWORK", "GameFontNormal")
text:SetHeight(1)
text:SetWidth(1)
text:SetJustifyH("LEFT")
text:SetAllPoints(button)
button:SetFontString(text)
 
-- Setup the highlighting
local texture = button:CreateTexture(nil, "ARTWORK")
texture:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
texture:ClearAllPoints()
texture:SetPoint("TOPLEFT", button, 0, -2)
texture:SetPoint("BOTTOMRIGHT", button, 5, 2)
texture:SetAlpha(0.70)
 
button:SetHighlightTexture(texture)
button:SetHighlightFontObject(GameFontHighlight)
button:SetNormalFontObject(GameFontNormal)
 
table.insert(predictFrame.buttons, button)
end
 
local self = {}
self.type = Type
self.num = num
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetDisabled = SetDisabled
self.SetText = SetText
self.SetLabel = SetLabel
 
frame.obj = self
self.frame = frame
 
editbox.obj = self
editbox.predictFrame = predictFrame
self.editbox = editbox
 
self.predictFrame = predictFrame
predictFrame.editbox = editbox
predictFrame.obj = self
 
self.alignoffset = 30
 
frame:SetHeight(44)
frame:SetWidth(200)
 
-- Despite the fact that wowprogramming/wowwiki say EditBoxes have OnKeyUp/OnKeyDown thats not actually true
-- so doing some trickery with bindings and such to make navigation work
predictFrame:SetScript("OnMouseDown", Predicter_OnMouseDown)
predictFrame:SetScript("OnHide", Predicter_OnHide)
predictFrame:SetScript("OnShow", Predicter_OnShow)
 
editbox:SetScript("OnShow", startLoading)
editbox:SetScript("OnEnter", Control_OnEnter)
editbox:SetScript("OnLeave", Control_OnLeave)
 
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
editbox:SetScript("OnEditFocusGained", EditBox_OnEditFocusGained)
editbox:SetScript("OnEditFocusLost", EditBox_OnEditFocusLost)
 
editbox:SetTextInsets(0, 0, 3, 3)
editbox:SetMaxLetters(256)
 
editbox:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 6, 0)
editbox:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
editbox:SetHeight(19)
 
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -2)
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
self.label = label
 
local button = CreateFrame("Button",nil,editbox,"UIPanelButtonTemplate")
button:SetWidth(40)
button:SetHeight(20)
button:SetPoint("RIGHT", editbox, "RIGHT", -2, 0)
button:SetText(OKAY)
button:SetScript("OnClick", Button_OnClick)
button:Hide()
 
self.button = button
button.obj = self
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
\ No newline at end of file Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/EditBox-Core.lua New file
0,0 → 1,468
-- This is basically the main portion of the predictor, the other files handle
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Predictor_Base"
local Version = 1
local PREDICTOR_ROWS = 10
local SpellData = LibStub("AceGUI-3.0-SpellLoader")
local tooltip
local alreadyAdded = {}
local predictorBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
edgeSize = 26,
insets = {left = 9, right = 9, top = 9, bottom = 9},
}
 
local function OnAcquire(self)
self:SetHeight(26)
self:SetWidth(200)
self:SetDisabled(false)
self:SetLabel()
self.showButton = true
 
SpellData:RegisterPredictor(self.predictFrame)
SpellData:StartLoading()
end
 
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.predictFrame:Hide()
self.spellFilter = nil
 
self:SetDisabled(false)
 
SpellData:UnregisterPredictor(self.predictFrame)
end
 
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
 
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
 
local function Predictor_Query(self)
for _, button in pairs(self.buttons) do button:Hide() end
for k in pairs(alreadyAdded) do alreadyAdded[k] = nil end
 
local query = "^" .. string.lower(self.obj.editBox:GetText())
 
local activeButtons = 0
for spellID, name in pairs(SpellData.spellList) do
if( not alreadyAdded[name] and string.match(name, query) and ( not self.obj.spellFilter or self.obj.spellFilter(self.obj, spellID) ) ) then
activeButtons = activeButtons + 1
 
local button = self.buttons[activeButtons]
local spellName, spellRank, spellIcon = GetSpellInfo(spellID)
if( self.obj.useRanks and spellRank and spellRank ~= "" ) then
button:SetFormattedText("|T%s:20:20:2:11|t %s (%s)", spellIcon, spellName, spellRank)
else
button:SetFormattedText("|T%s:20:20:2:11|t %s", spellIcon, spellName)
end
 
if( not self.obj.useRanks ) then
alreadyAdded[name] = true
end
 
button.spellID = spellID
button:Show()
 
-- Highlight if needed
if( activeButtons ~= self.selectedButton ) then
button:UnlockHighlight()
 
if( GameTooltip:IsOwned(button) ) then
GameTooltip:Hide()
end
end
 
-- Ran out of text to suggest :<
if( activeButtons >= PREDICTOR_ROWS ) then break end
end
end
 
if( activeButtons > 0 ) then
self:SetHeight(15 + activeButtons * 17)
self:Show()
else
self:Hide()
end
 
self.activeButtons = activeButtons
end
 
local function ShowButton(self)
if( self.lastText ~= "" ) then
self.predictFrame.selectedButton = nil
Predictor_Query(self.predictFrame)
else
self.predictFrame:Hide()
end
 
if( self.showButton ) then
self.button:Show()
self.editBox:SetTextInsets(0, 20, 3, 3)
end
end
 
local function HideButton(self)
self.button:Hide()
self.editBox:SetTextInsets(0, 0, 3, 3)
 
self.predictFrame.selectedButton = nil
self.predictFrame:Hide()
end
 
local function Predictor_OnHide(self)
-- Allow users to use arrows to go back and forth again without the fix
self.obj.editBox:SetAltArrowKeyMode(false)
 
-- Make sure the tooltip isn't kept open if one of the buttons was using it
for _, button in pairs(self.buttons) do
if( GameTooltip:IsOwned(button) ) then
GameTooltip:Hide()
end
end
 
-- Reset all bindings set on this predictor
ClearOverrideBindings(self)
end
 
local function Predictor_OnShow(self)
-- If the user is using an edit box in a configuration, they will live without arrow keys while the predictor
-- is opened, this also is the only way of getting up/down arrow for browsing the predictor to work.
self.obj.editBox:SetAltArrowKeyMode(true)
 
local name = self:GetName()
SetOverrideBindingClick(self, true, "DOWN", name, 1)
SetOverrideBindingClick(self, true, "UP", name, -1)
SetOverrideBindingClick(self, true, "LEFT", name, "LEFT")
SetOverrideBindingClick(self, true, "RIGHT", name, "RIGHT")
end
 
local function EditBox_OnEnterPressed(this)
local self = this.obj
 
-- Something is selected in the predictor, use that value instead of whatever is in the input box
if( self.predictFrame.selectedButton ) then
self.predictFrame.buttons[self.predictFrame.selectedButton]:Click()
return
end
 
local cancel = self:Fire("OnEnterPressed", this:GetText())
if( not cancel ) then
HideButton(self)
end
 
-- Reactive the cursor, odds are if someone is adding spells they are adding more than one
-- and if they aren't, it can't hurt anyway.
self.editBox:SetFocus()
end
 
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
 
-- When using SetAltArrowKeyMode the ability to move the cursor with left and right arrows is disabled
-- this reenables that so the user doesn't notice anything wrong
local function EditBox_FixCursorPosition(self, direction)
self:SetCursorPosition(self:GetCursorPosition() + (direction == "RIGHT" and 1 or -1))
end
 
local function EditBox_OnReceiveDrag(this)
local self = this.obj
local type, id, info = GetCursorInfo()
if( type == "spell" ) then
local name, rank = GetSpellName(id, info)
if( self.useRanks and rank and rank ~= "" ) then
name = string.format("%s (%s)", name, rank)
end
 
self:SetText(name)
self:Fire("OnEnterPressed", name)
ClearCursor()
end
 
HideButton(self)
AceGUI:ClearFocus()
end
 
local function EditBox_OnTextChanged(this)
local self = this.obj
local value = this:GetText()
if( value ~= self.lastText ) then
self:Fire("OnTextChanged", value)
self.lastText = value
 
ShowButton(self)
end
end
 
local function EditBox_OnEditFocusLost(self)
Predictor_OnHide(self.obj.predictFrame)
end
 
local function EditBox_OnEditFocusGained(self)
if( self.obj.predictFrame:IsVisible() ) then
Predictor_OnShow(self.obj.predictFrame)
end
end
 
local function Button_OnClick(this)
EditBox_OnEnterPressed(this.obj.editBox)
end
 
-- API calls
local function SetUseRanks(self, enabled)
self.useRanks = enabled
end
 
local function SetDisabled(self, disabled)
self.disabled = disabled
if( disabled ) then
self.editBox:EnableMouse(false)
self.editBox:ClearFocus()
self.editBox:SetTextColor(0.5, 0.5, 0.5)
self.label:SetTextColor(0.5, 0.5, 0.5)
else
self.editBox:EnableMouse(true)
self.editBox:SetTextColor(1, 1, 1)
self.label:SetTextColor(1, 0.82, 0)
end
end
 
local function SetText(self, text, cursor)
self.lastText = text or ""
self.editBox:SetText(self.lastText)
self.editBox:SetCursorPosition(cursor or 0)
 
HideButton(self)
end
 
local function SetLabel(self, text)
if( text and text ~= "" ) then
self.label:SetText(text)
self.label:Show()
self.editBox:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 7, -18)
self:SetHeight(44)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editBox:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 7, 0)
self:SetHeight(26)
self.alignoffset = 12
end
end
 
local function Predictor_OnMouseDown(self, direction)
-- Fix the cursor positioning if left or right arrow key was used
if( direction == "LEFT" or direction == "RIGHT" ) then
EditBox_FixCursorPosition(self.editBox, direction)
return
end
 
self.selectedButton = (self.selectedButton or 0) + direction
if( self.selectedButton > self.activeButtons ) then
self.selectedButton = 1
elseif( self.selectedButton <= 0 ) then
self.selectedButton = self.activeButtons
end
 
-- Figure out what to highlight and show the spell tooltip while we're at it
for i=1, self.activeButtons do
local button = self.buttons[i]
if( i == self.selectedButton ) then
button:LockHighlight()
 
GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT", 3)
GameTooltip:SetHyperlink("spell:" .. button.spellID)
else
button:UnlockHighlight()
 
if( GameTooltip:IsOwned(button) ) then
GameTooltip:Hide()
end
end
end
end
 
local function Spell_OnClick(self)
local name, rank = GetSpellInfo(self.spellID)
if( self.useRanks and rank and rank ~= "" ) then
name = string.format("%s (%s)", name, rank)
end
 
SetText(self.parent.obj, name, string.len(name))
 
self.parent.selectedButton = nil
self.parent.obj:Fire("OnEnterPressed", name)
end
 
local function Spell_OnEnter(self)
self.parent.selectedButton = nil
self:LockHighlight()
 
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT", 3)
GameTooltip:SetHyperlink("spell:" .. self.spellID)
end
 
local function Spell_OnLeave(self)
self:UnlockHighlight()
GameTooltip:Hide()
end
 
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
local editBox = CreateFrame("EditBox", "AceGUI30SpellEditBox" .. num, frame, "InputBoxTemplate")
 
-- Don't feel like looking up the specific callbacks for when a widget resizes, so going to be creative with SetPoint instead!
local predictFrame = CreateFrame("Frame", "AceGUI30SpellEditBox" .. num .. "Predictor", UIParent)
predictFrame:SetBackdrop(predictorBackdrop)
predictFrame:SetBackdropColor(0, 0, 0, 0.85)
predictFrame:SetWidth(1)
predictFrame:SetHeight(150)
predictFrame:SetPoint("TOPLEFT", editBox, "BOTTOMLEFT", -6, 0)
predictFrame:SetPoint("TOPRIGHT", editBox, "BOTTOMRIGHT", 0, 0)
predictFrame:SetFrameStrata("TOOLTIP")
predictFrame.buttons = {}
predictFrame.Query = Predictor_Query
predictFrame:Hide()
 
-- Create the mass of predictor rows
for i=1, PREDICTOR_ROWS do
local button = CreateFrame("Button", nil, predictFrame)
button:SetHeight(17)
button:SetWidth(1)
button:SetPushedTextOffset(-2, 0)
button:SetScript("OnClick", Spell_OnClick)
button:SetScript("OnEnter", Spell_OnEnter)
button:SetScript("OnLeave", Spell_OnLeave)
button.parent = predictFrame
button.editBox = editBox
button:Hide()
 
if( i > 1 ) then
button:SetPoint("TOPLEFT", predictFrame.buttons[i - 1], "BOTTOMLEFT", 0, 0)
button:SetPoint("TOPRIGHT", predictFrame.buttons[i - 1], "BOTTOMRIGHT", 0, 0)
else
button:SetPoint("TOPLEFT", predictFrame, 8, -8)
button:SetPoint("TOPRIGHT", predictFrame, -7, 0)
end
 
-- Create the actual text
local text = button:CreateFontString(nil, "ARTWORK", "GameFontNormal")
text:SetHeight(1)
text:SetWidth(1)
text:SetJustifyH("LEFT")
text:SetAllPoints(button)
button:SetFontString(text)
 
-- Setup the highlighting
local texture = button:CreateTexture(nil, "ARTWORK")
texture:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
texture:ClearAllPoints()
texture:SetPoint("TOPLEFT", button, 0, -2)
texture:SetPoint("BOTTOMRIGHT", button, 5, 2)
texture:SetAlpha(0.70)
 
button:SetHighlightTexture(texture)
button:SetHighlightFontObject(GameFontHighlight)
button:SetNormalFontObject(GameFontNormal)
 
table.insert(predictFrame.buttons, button)
end
 
-- Set the main info things for this thingy
local self = {}
self.type = Type
self.num = num
 
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
 
self.SetDisabled = SetDisabled
self.SetText = SetText
self.SetLabel = SetLabel
 
self.frame = frame
self.predictFrame = predictFrame
self.editBox = editBox
 
self.alignoffset = 30
 
frame:SetHeight(44)
frame:SetWidth(200)
 
frame.obj = self
editBox.obj = self
predictFrame.obj = self
 
-- Purely meant for a single tooltip for doing scanning
if( not tooltip ) then
tooltip = CreateFrame("GameTooltip")
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
for i=1, 6 do
tooltip["TextLeft" .. i] = tooltip:CreateFontString()
tooltip["TextRight" .. i] = tooltip:CreateFontString()
tooltip:AddFontStrings(tooltip["TextLeft" .. i], tooltip["TextRight" .. i])
end
end
 
self.tooltip = tooltip
 
-- EditBoxes override the OnKeyUp/OnKeyDown events so that they can function, meaning in order to make up and down
-- arrow navigation of the menu work, I have to do some trickery with temporary bindings.
predictFrame:SetScript("OnMouseDown", Predictor_OnMouseDown)
predictFrame:SetScript("OnHide", Predictor_OnHide)
predictFrame:SetScript("OnShow", Predictor_OnShow)
 
editBox:SetScript("OnEnter", Control_OnEnter)
editBox:SetScript("OnLeave", Control_OnLeave)
 
editBox:SetAutoFocus(false)
editBox:SetFontObject(ChatFontNormal)
editBox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
editBox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
editBox:SetScript("OnTextChanged", EditBox_OnTextChanged)
editBox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
editBox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
editBox:SetScript("OnEditFocusGained", EditBox_OnEditFocusGained)
editBox:SetScript("OnEditFocusLost", EditBox_OnEditFocusLost)
 
editBox:SetTextInsets(0, 0, 3, 3)
editBox:SetMaxLetters(256)
 
editBox:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 6, 0)
editBox:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
editBox:SetHeight(19)
 
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -2)
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
 
self.label = label
 
local button = CreateFrame("Button", nil, editBox, "UIPanelButtonTemplate")
button:SetPoint("RIGHT", editBox, "RIGHT", -2, 0)
button:SetScript("OnClick", Button_OnClick)
button:SetWidth(40)
button:SetHeight(20)
button:SetText(OKAY)
button:Hide()
 
self.button = button
button.obj = self
 
AceGUI:RegisterAsWidget(self)
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/SpellLoader.lua New file
0,0 → 1,86
local major = "AceGUI-3.0-SpellLoader"
local minor = 1
 
local SpellLoader = LibStub:NewLibrary(major, minor)
if( not SpellLoader ) then return end
 
SpellLoader.predictors = SpellLoader.predictors or {}
SpellLoader.spellList = SpellLoader.spellList or {}
SpellLoader.spellsLoaded = SpellLoader.spellsLoaded or 0
 
local SPELLS_PER_RUN = 500
local TIMER_THROTTLE = 0.10
local spells, predictors = SpellLoader.spellList, SpellLoader.predictors
 
function SpellLoader:RegisterPredictor(frame)
self.predictors[frame] = true
end
 
function SpellLoader:UnregisterPredictor(frame)
self.predictors[frame] = nil
end
 
function SpellLoader:StartLoading()
if( self.loader ) then return end
 
local blacklist = {
["Interface\\Icons\\Trade_Alchemy"] = true,
["Interface\\Icons\\Trade_BlackSmithing"] = true,
["Interface\\Icons\\Trade_BrewPoison"] = true,
["Interface\\Icons\\Trade_Engineering"] = true,
["Interface\\Icons\\Trade_Engraving"] = true,
["Interface\\Icons\\Trade_Fishing"] = true,
["Interface\\Icons\\Trade_Herbalism"] = true,
["Interface\\Icons\\Trade_LeatherWorking"] = true,
["Interface\\Icons\\Trade_Mining"] = true,
["Interface\\Icons\\Trade_Tailoring"] = true,
["Interface\\Icons\\Temp"] = true,
}
 
local timeElapsed, totalInvalid, currentIndex = 0, 0, 0
self.loader = CreateFrame("Frame")
self.loader:SetScript("OnUpdate", function(self, elapsed)
timeElapsed = timeElapsed + elapsed
if( timeElapsed < TIMER_THROTTLE ) then return end
timeElapsed = timeElapsed - TIMER_THROTTLE
 
-- 5,000 invalid spells in a row means it's a safe assumption that there are no more spells to query
if( totalInvalid >= 5000 ) then
self:Hide()
return
end
 
-- Load as many spells in
for spellID=currentIndex + 1, currentIndex + SPELLS_PER_RUN do
local name, rank, icon = GetSpellInfo(spellID)
 
-- Pretty much every profession spell uses Trade_* and 99% of the random spells use the Trade_Engineering icon
-- we can safely blacklist any of these spells as they are not needed. Can get away with this because things like
-- Alchemy use two icons, the Trade_* for the actual crafted spell and a different icon for the actual buff
-- Passive spells have no use as well, since they are well passive and can't actually be used
if( name and not blacklist[icon] and rank ~= SPELL_PASSIVE ) then
name = string.lower(name)
 
SpellLoader.spellsLoaded = SpellLoader.spellsLoaded + 1
spells[spellID] = string.lower(name)
 
totalInvalid = 0
else
totalInvalid = totalInvalid + 1
end
end
 
-- Every ~1 second it will update any visible predictors to make up for the fact that the data is delay loaded
if( currentIndex % 5000 == 0 ) then
for predictor in pairs(predictors) do
if( predictor:IsVisible() ) then
predictor:Query()
end
end
end
 
 
-- Increment and do it all over!
currentIndex = currentIndex + SPELLS_PER_RUN
end)
end
\ No newline at end of file Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/Auras-EditBox.lua New file
0,0 → 1,53
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Aura_EditBox"
local Version = 1
local filterCache = {}
 
-- Tooltip scanning every single spell while it's loading would be not be that fun. Scanning spells as we search them (and get valid results)
-- is a better solution since the results can be cached too.
local function spellFilter(self, spellID)
if( filterCache[spellID] ~= nil ) then return filterCache[spellID] end
 
-- Very very few auras are over 100 yard range, and those are generally boss spells should be able to get away with this
if( select(9, GetSpellInfo(spellID)) > 100 ) then
filterCache[spellID] = true
return false
end
 
-- We look for a description tag, 99% of auras have a description tag indicating what they are
-- so we don't find one, then it's likely a safe assumption that it is not an aura
self.tooltip:SetHyperlink("spell:" .. spellID)
for i=1, self.tooltip:NumLines() do
local text = self.tooltip["TextLeft" .. i]
if( text ) then
local r, g, b = text:GetTextColor()
r = math.floor(r + 0.10)
g = math.floor(g + 0.10)
b = math.floor(b + 0.10)
 
-- Gold first text, it's a profession link
if( i == 1 and ( r ~= 1 or g ~= 1 or g ~= 1 ) ) then
filterCache[spellID] = false
return false
-- Gold for anything else and it should be a valid aura
elseif( r ~= 1 or g ~= 1 or b ~= 1 ) then
filterCache[spellID] = true
return true
end
end
end
 
filterCache[spellID] = false
return false
end
 
-- I know theres a better way of doing this than this, but not sure for the time being, works fine though!
local function Constructor()
local self = AceGUI:Create("Predictor_Base")
self.spellFilter = spellFilter
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/AceGUI-3.0-Spell-EditBox.toc New file
0,0 → 1,13
## Interface: 30200
## Title: Lib: AceGUI-3.0-Spell-EditBox
## Notes: Adds predicted lists for spells while the user types
## Author: Shadowed
## X-Category: Library
## OptionalDeps: Ace3
## X-Curse-Packaged-Version: r20090807071246
## X-Curse-Project-Name: AceGUI-3.0-Spell-EditBox
## X-Curse-Project-ID: ace-gui-3-0-spell-editbox
## X-Curse-Repository-ID: wow/ace-gui-3-0-spell-editbox/mainline
 
AceGUI-3.0-Spell-EditBox.xml
## test.lua
\ No newline at end of file Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/Player-EditBox.lua New file
0,0 → 1,46
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Player_EditBox"
local Version = 1
local playerSpells = {}
local frame
 
local function spellFilter(self, spellID)
return playerSpells[spellID]
end
 
local function loadPlayerSpells(self)
table.wipe(playerSpells)
 
for tab=2, GetNumSpellTabs() do
local offset = select(3, GetSpellTabInfo(tab))
for i=1, offset do
self.tooltip:SetSpell(i + offset, tab)
 
local spellName, _, spellID = self.tooltip:GetSpell()
if( spellName ) then
playerSpells[spellID] = true
end
end
end
end
 
-- I know theres a better way of doing this than this, but not sure for the time being, works fine though!
local function Constructor()
local self = AceGUI:Create("Predictor_Base")
self.spellFilter = spellFilter
 
if( not frame ) then
frame = CreateFrame("Frame")
frame:RegisterEvent("SPELLS_CHANGED")
frame:SetScript("OnEvent", loadPlayerSpells)
frame.tooltip = self.tooltip
 
loadPlayerSpells(frame)
end
 
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
Property changes : Added: svn:eol-style + native
AceGUI-3.0-Spell-EditBox/Casts-EditBox.lua New file
0,0 → 1,35
local AceGUI = LibStub("AceGUI-3.0")
do
local Type = "Cast_EditBox"
local Version = 1
local filterCache = {}
 
local function spellFilter(self, spellID)
if( filterCache[spellID] ~= nil ) then return filterCache[spellID] end
 
-- Scan first line to figure out if it's a profession
self.tooltip:SetHyperlink("spell:" .. spellID)
local r, g, b = self.tooltip.TextLeft1:GetTextColor()
r = math.floor(r + 0.10)
g = math.floor(g + 0.10)
b = math.floor(b + 0.10)
 
if( r ~= 1 or g ~= 1 or b ~= 1 ) then
filterCache[spellID] = false
return false
end
 
-- Hide all spells without a cast time
filterCache[spellID] = select(7, GetSpellInfo(spellID)) > 0
return filterCache[spellID]
end
 
-- I know theres a better way of doing this than this, but not sure for the time being, works fine though!
local function Constructor()
local self = AceGUI:Create("Predictor_Base")
self.spellFilter = spellFilter
return self
end
 
AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
Property changes : Added: svn:eol-style + native