From 5a6c9c3f789807e0abaefe96719bed8ba07c85ed Mon Sep 17 00:00:00 2001 From: Xruptor Date: Mon, 16 Aug 2010 08:49:33 -0400 Subject: [PATCH] -A slight fix again for the Search Window. Items weren't being inputed unless the editbox was shown. -An update for the Search Window window to automatically select current editbox being used. -Updated libraries (because of github lol) --- BagSync_Search.lua | 15 +- libs/LibItemSearch-1.0.lua | 417 ++++++++++++++++++++++++++++++++++++++++++++ libs/LibStub.lua | 30 ++++ libs/tekKonfigDropdown.lua | 85 +++++++++ libs/tekKonfigScroll.lua | 80 +++++++++ 5 files changed, 616 insertions(+), 11 deletions(-) create mode 100644 libs/LibItemSearch-1.0.lua create mode 100644 libs/LibStub.lua create mode 100644 libs/tekKonfigDropdown.lua create mode 100644 libs/tekKonfigScroll.lua diff --git a/BagSync_Search.lua b/BagSync_Search.lua index c761cf4..a5564b4 100644 --- a/BagSync_Search.lua +++ b/BagSync_Search.lua @@ -128,17 +128,10 @@ function bgSearch:LoadSlider() row:SetScript("OnClick", function(self) if self.link then if IsShiftKeyDown() then - local passChk = false - for i = 1, NUM_CHAT_WINDOWS do - local editBox = _G[("ChatFrame%dEditBox"):format(i)] - if editBox:IsVisible() then - editBox:Insert(self.link) - passChk = true - break - end - end - if not passChk then - _G[("ChatFrame1EditBox"):Insert(self.link) + local editBox = ChatEdit_ChooseBoxForSend() + if editBox then + editBox:Insert(self.link) + ChatFrame_OpenChat(editBox:GetText()) end elseif IsControlKeyDown() then DressUpItemLink(self.link) diff --git a/libs/LibItemSearch-1.0.lua b/libs/LibItemSearch-1.0.lua new file mode 100644 index 0000000..e7f52a6 --- /dev/null +++ b/libs/LibItemSearch-1.0.lua @@ -0,0 +1,417 @@ +--[[ + ItemSearch + An item text search engine of some sort + + Grammar: + := + := & ; + := | ; + := ! ; + := ; ; ; + := bop ; boa ; bou ; boe ; quest + := q ; q + := ilvl + := t: + := + := : | = | == | != | ~= | < | > | <= | >= + + I kindof half want to make a full parser for this +--]] + +local MAJOR, MINOR = "LibItemSearch-1.0", 2 +local ItemSearch = LibStub:NewLibrary(MAJOR, MINOR) +if not ItemSearch then return end + +--[[ general search ]]-- + +function ItemSearch:Find(itemLink, search) + if not search then + return true + end + + if not itemLink then + return false + end + + local search = search:lower() + if search:match('\124') then + return self:FindUnionSearch(itemLink, strsplit('\124', search)) + end + return self:FindUnionSearch(itemLink, search) +end + + +--[[ union search: & ]]-- + +function ItemSearch:FindUnionSearch(itemLink, ...) + for i = 1, select('#', ...) do + local search = select(i, ...) + if search and search ~= '' then + if search:match('\038') then + if self:FindIntersectSearch(itemLink, strsplit('\038', search)) then + return true + end + else + if self:FindIntersectSearch(itemLink, search) then + return true + end + end + end + end + return false +end + + +--[[ intersect search: | ]]-- + +function ItemSearch:FindIntersectSearch(itemLink, ...) + for i = 1, select('#', ...) do + local search = select(i, ...) + if search and search ~= '' then + if not self:FindNegatableSearch(itemLink, search) then + return false + end + end + end + return true +end + + +--[[ negated search: ! ]]-- + +function ItemSearch:FindNegatableSearch(itemLink, search) + local negatedSearch = search:match('^\033(.+)$') + if negatedSearch then + return not self:FindTypedSearch(itemLink, negatedSearch) + end + return self:FindTypedSearch(itemLink, search) +end + + +--[[ + typed search: + user defined search types + + A typed search object should look like the following: + { + string id + unique identifier for the search type, + + string searchCapture = function isSearch(self, search) + returns a capture if the given search matches this typed search + returns nil if the search is not a match for this type + + bool isMatch = function findItem(self, itemLink, searchCapture) + returns true if is in the search defined by + } +--]] + +local typedSearches = {} +function ItemSearch:RegisterTypedSearch(typedSearchObj) + typedSearches[typedSearchObj.id] = typedSearchObj +end + +function ItemSearch:GetTypedSearches() + return pairs(typedSearches) +end + +function ItemSearch:GetTypedSearch(id) + return typedSearches[id] +end + +function ItemSearch:FindTypedSearch(itemLink, search) + if not search then + return false + end + + for id, searchInfo in self:GetTypedSearches() do + local capture1, capture2, capture3 = searchInfo:isSearch(search) + if capture1 then + return searchInfo:findItem(itemLink, capture1, capture2, capture3) + end + end + + return self:GetTypedSearch('itemTypeGeneric'):findItem(itemLink, search) or self:GetTypedSearch('itemName'):findItem(itemLink, search) +end + + +--[[ + Basic typed searches +--]] + +function ItemSearch:Compare(op, lhs, rhs) + --ugly, but it works + if op == ':' or op == '=' or op == '==' then + return lhs == rhs + end + if op == '!=' or op == '~=' then + return lhs ~= rhs + end + if op == '<=' then + return lhs <= rhs + end + if op == '<' then + return lhs < rhs + end + if op == '>' then + return lhs > rhs + end + if op == '>=' then + return lhs >= rhs + end + return false +end + + +--[[ basic text search n:(.+) ]]-- + +local function search_IsInText(search, ...) + for i = 1, select('#', ...) do + local text = select(i, ...) + text = text and tostring(text):lower() + if text and (text == search or text:match(search)) then + return true + end + end + return false +end + +ItemSearch:RegisterTypedSearch{ + id = 'itemName', + + isSearch = function(self, search) + return search and search:match('^n:(.+)$') + end, + + findItem = function(self, itemLink, search) + local itemName = (GetItemInfo(itemLink)) + return search_IsInText(search, itemName) + end +} + + +--[[ item type,subtype,equip loc search t:(.+) ]]-- + +ItemSearch:RegisterTypedSearch{ + id = 'itemTypeGeneric', + + isSearch = function(self, search) + return search and search:match('^t:(.+)$') + end, + + findItem = function(self, itemLink, search) + local name, link, quality, iLevel, reqLevel, type, subType, maxStack, equipSlot = GetItemInfo(itemLink) + if not name then + return false + end + return search_IsInText(search, type, subType, _G[equipSlot]) + end +} + + +--[[ item quality search: q(sign)(%d+) | q:(qualityName) ]]-- + +ItemSearch:RegisterTypedSearch{ + id = 'itemQuality', + + isSearch = function(self, search) + if search then + return search:match('^q([%~%:%<%>%=%!]+)(%w+)$') + end + end, + + descToQuality = function(self, desc) + local q = 0 + + local quality = _G['ITEM_QUALITY' .. q .. '_DESC'] + while quality and quality:lower() ~= desc do + q = q + 1 + quality = _G['ITEM_QUALITY' .. q .. '_DESC'] + end + + if quality then + return q + end + end, + + findItem = function(self, itemLink, op, search) + local name, link, quality = GetItemInfo(itemLink) + if not name then + return false + end + + local num = tonumber(search) or self:descToQuality(search) + return num and ItemSearch:Compare(op, quality, num) or false + end, +} + +--[[ item level search: lvl(sign)(%d+) ]]-- + +ItemSearch:RegisterTypedSearch{ + id = 'itemLevel', + + isSearch = function(self, search) + if search then + return search:match('^ilvl([:<>=!]+)(%d+)$') + end + end, + + findItem = function(self, itemLink, op, search) + local name, link, quality, iLvl = GetItemInfo(itemLink) + if not iLvl then + return false + end + + local num = tonumber(search) + return num and ItemSearch:Compare(op, iLvl, num) or false + end, +} + + +--[[ tooltip keyword search ]]-- + +local tooltipCache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end}) +local tooltipScanner = _G['LibItemSearchTooltipScanner'] or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate') + +local function link_FindSearchInTooltip(itemLink, search) + --look in the cache for the result + local itemID = itemLink:match('item:(%d+)') + local cachedResult = tooltipCache[search][itemID] + if cachedResult ~= nil then + return cachedResult + end + + --no match?, pull in the resut from tooltip parsing + tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE') + tooltipScanner:SetHyperlink(itemLink) + + local result = false + if tooltipScanner:NumLines() > 1 and _G[tooltipScanner:GetName() .. 'TextLeft2']:GetText() == search then + result = true + elseif tooltipScanner:NumLines() > 2 and _G[tooltipScanner:GetName() .. 'TextLeft3']:GetText() == search then + result = true + end + tooltipScanner:Hide() + + tooltipCache[search][itemID] = result + return result +end + +ItemSearch:RegisterTypedSearch{ + id = 'tooltip', + + isSearch = function(self, search) + return self.keywords[search] + end, + + findItem = function(self, itemLink, search) + return search and link_FindSearchInTooltip(itemLink, search) + end, + + keywords = { + ['boe'] = ITEM_BIND_ON_EQUIP, + ['bop'] = ITEM_BIND_ON_PICKUP, + ['bou'] = ITEM_BIND_ON_USE, + ['quest'] = ITEM_BIND_QUEST, + ['boa'] = ITEM_BIND_TO_ACCOUNT + } +} + + +--[[ equipment set search ]]-- + +local function IsWardrobeLoaded() + local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo('Wardrobe') + return enabled +end + +local function findEquipmentSetByName(search) + local startsWithSearch = '^' .. search + local partialMatch = nil + + for i = 1, GetNumEquipmentSets() do + local setName = (GetEquipmentSetInfo(i)) + local lSetName = setName:lower() + + if lSetName == search then + return setName + end + + if lSetName:match(startsWithSearch) then + partialMatch = setName + end + end + + -- Wardrobe Support + if Wardrobe then + for i, outfit in ipairs( Wardrobe.CurrentConfig.Outfit) do + local setName = outfit.OutfitName + local lSetName = setName:lower() + + if lSetName == search then + return setName + end + + if lSetName:match(startsWithSearch) then + partialMatch = setName + end + end + end + + return partialMatch +end + +local function isItemInEquipmentSet(itemLink, setName) + if not setName then + return false + end + + local itemIDs = GetEquipmentSetItemIDs(setName) + if not itemIDs then + return false + end + + local itemID = tonumber(itemLink:match('item:(%d+)')) + for inventoryID, setItemID in pairs(itemIDs) do + if itemID == setItemID then + return true + end + end + + return false +end + +local function isItemInWardrobeSet(itemLink, setName) + if not Wardrobe then return false end + + local itemName = (GetItemInfo(itemLink)) + for i, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do + if outfit.OutfitName == setName then + for j, item in pairs(outfit.Item) do + if item and (item.IsSlotUsed == 1) and (item.Name == itemName) then + return true + end + end + end + end + + return false +end + +ItemSearch:RegisterTypedSearch{ + id = 'equipmentSet', + + isSearch = function(self, search) + return search and search:match('^s:(.+)$') + end, + + findItem = function(self, itemLink, search) + local setName = findEquipmentSetByName(search) + if not setName then + return false + end + + return isItemInEquipmentSet(itemLink, setName) + or isItemInWardrobeSet(itemLink, setName) + end, +} \ No newline at end of file diff --git a/libs/LibStub.lua b/libs/LibStub.lua new file mode 100644 index 0000000..0a41ac0 --- /dev/null +++ b/libs/LibStub.lua @@ -0,0 +1,30 @@ +-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info +-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke +local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! +local LibStub = _G[LIBSTUB_MAJOR] + +if not LibStub or LibStub.minor < LIBSTUB_MINOR then + LibStub = LibStub or {libs = {}, minors = {} } + _G[LIBSTUB_MAJOR] = LibStub + LibStub.minor = LIBSTUB_MINOR + + function LibStub:NewLibrary(major, minor) + assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") + minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") + + local oldminor = self.minors[major] + if oldminor and oldminor >= minor then return nil end + self.minors[major], self.libs[major] = minor, self.libs[major] or {} + return self.libs[major], oldminor + end + + function LibStub:GetLibrary(major, silent) + if not self.libs[major] and not silent then + error(("Cannot find a library instance of %q."):format(tostring(major)), 2) + end + return self.libs[major], self.minors[major] + end + + function LibStub:IterateLibraries() return pairs(self.libs) end + setmetatable(LibStub, { __call = LibStub.GetLibrary }) +end diff --git a/libs/tekKonfigDropdown.lua b/libs/tekKonfigDropdown.lua new file mode 100644 index 0000000..42a9b16 --- /dev/null +++ b/libs/tekKonfigDropdown.lua @@ -0,0 +1,85 @@ +local lib, oldminor = LibStub:NewLibrary("tekKonfig-Dropdown", 3) +if not lib then return end +oldminor = oldminor or 0 + + +local GameTooltip = GameTooltip +local function HideTooltip() GameTooltip:Hide() end +local function ShowTooltip(self) + if self.frame.tiptext then + GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT") + GameTooltip:SetText(self.frame.tiptext, nil, nil, nil, nil, true) + end +end +local function ShowTooltip2(self) ShowTooltip(self.container) end + + +local function OnClick(self) + ToggleDropDownMenu(nil, nil, self:GetParent()) + PlaySound("igMainMenuOptionCheckBoxOn") +end + +local function OnHide() CloseDropDownMenus() end + + +-- Create a dropdown. +-- All args optional, parent recommended +function lib.new(parent, label, ...) + local container = CreateFrame("Button", nil, parent) + container:SetWidth(149+13) container:SetHeight(32+24) + container:SetScript("OnEnter", ShowTooltip) + container:SetScript("OnLeave", HideTooltip) + if select("#", ...) > 0 then container:SetPoint(...) end + + local name = "tekKonfigDropdown"..GetTime() -- Sadly, some of these frames must be named + local f = CreateFrame("Frame", name, parent) + f:SetWidth(149) f:SetHeight(32) + f:SetPoint("TOPLEFT", container, -13, -24) + f:EnableMouse(true) + f:SetScript("OnHide", OnHide) + container.frame = f + + local ltex = f:CreateTexture(name.."Left", "ARTWORK") + ltex:SetWidth(25) ltex:SetHeight(64) + ltex:SetPoint("TOPLEFT", 0, 17) + ltex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + ltex:SetTexCoord(0, 0.1953125, 0, 1) + + local rtex = f:CreateTexture(nil, "ARTWORK") + rtex:SetWidth(25) rtex:SetHeight(64) + rtex:SetPoint("RIGHT") + rtex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + rtex:SetTexCoord(0.8046875, 1, 0, 1) + + local mtex = f:CreateTexture(nil, "ARTWORK") + mtex:SetWidth(115) mtex:SetHeight(64) + mtex:SetPoint("LEFT", ltex, "RIGHT") + mtex:SetPoint("RIGHT", rtex, "LEFT") + mtex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + mtex:SetTexCoord(0.1953125, 0.8046875, 0, 1) + + local text = f:CreateFontString(name.."Text", "ARTWORK", "GameFontHighlightSmall") + text:SetWidth(0) text:SetHeight(10) + text:SetPoint("RIGHT", rtex, -43, 2) + text:SetJustifyH("RIGHT") + + local button = CreateFrame("Button", nil, f) + button:SetWidth(24) button:SetHeight(24) + button:SetPoint("TOPRIGHT", rtex, -16, -18) + button:SetScript("OnClick", OnClick) + button:SetScript("OnEnter", ShowTooltip2) + button.container = container + + button:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") + button:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") + button:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight") + button:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled") + button:GetHighlightTexture():SetBlendMode("ADD") + + local labeltext = f:CreateFontString(nil, "BACKGROUND", "GameFontNormal")--GameFontHighlight + labeltext:SetPoint("BOTTOMLEFT", container, "TOPLEFT", 16-13, 3-24) + labeltext:SetText(label) + + return f, text, container, labeltext +end + diff --git a/libs/tekKonfigScroll.lua b/libs/tekKonfigScroll.lua new file mode 100644 index 0000000..ff69b13 --- /dev/null +++ b/libs/tekKonfigScroll.lua @@ -0,0 +1,80 @@ + +local lib, oldminor = LibStub:NewLibrary("tekKonfig-Scroll", 2) +if not lib then return end + +lib.bg = { + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, + tileSize = 16, + edgeSize = 12, + insets = { left = 0, right = 0, top = 5, bottom = 5 } +} + +-- Creates a scrollbar +-- Parent is required, offset and step are optional +function lib.new(parent, offset, step) + local f = CreateFrame("Slider", nil, parent) + f:SetWidth(16) + + f:SetPoint("TOPRIGHT", 0 - (offset or 0), -16 - (offset or 0)) + f:SetPoint("BOTTOMRIGHT", 0 - (offset or 0), 16 + (offset or 0)) + + local up = CreateFrame("Button", nil, f) + up:SetPoint("BOTTOM", f, "TOP") + up:SetWidth(16) up:SetHeight(16) + up:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Up") + up:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Down") + up:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Disabled") + up:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Highlight") + + up:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + up:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + up:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + up:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + up:GetHighlightTexture():SetBlendMode("ADD") + + up:SetScript("OnClick", function(self) + local parent = self:GetParent() + parent:SetValue(parent:GetValue() - (step or parent:GetHeight()/2)) + PlaySound("UChatScrollButton") + end) + + local down = CreateFrame("Button", nil, f) + down:SetPoint("TOP", f, "BOTTOM") + down:SetWidth(16) down:SetHeight(16) + down:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up") + down:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Down") + down:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Disabled") + down:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Highlight") + + down:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + down:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + down:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + down:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4) + down:GetHighlightTexture():SetBlendMode("ADD") + + down:SetScript("OnClick", function(self) + local parent = self:GetParent() + parent:SetValue(parent:GetValue() + (step or parent:GetHeight()/2)) + PlaySound("UChatScrollButton") + end) + + f:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob") + local thumb = f:GetThumbTexture() + thumb:SetWidth(16) thumb:SetHeight(24) + thumb:SetTexCoord(1/4, 3/4, 1/8, 7/8) + + f:SetScript("OnValueChanged", function(self, value) + local min, max = self:GetMinMaxValues() + if value == min then up:Disable() else up:Enable() end + if value == max then down:Disable() else down:Enable() end + end) + + local border = CreateFrame("Frame", nil, f) + border:SetPoint("TOPLEFT", up, -5, 5) + border:SetPoint("BOTTOMRIGHT", down, 5, -3) + border:SetBackdrop(lib.bg) + border:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 0.5) + + return f, up, down, border +end -- 1.7.9.5