From 5b8f72a3ef5d6729725c186e56ad31862439541c Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Fri, 29 Jan 2016 11:33:55 +0100 Subject: [PATCH] working on basic functionality for the new filter search tab --- Aux-AddOn.toc | 4 +- auctions_frame.lua | 6 -- bids_frame.lua | 6 -- core.lua | 9 +++ filter_search_frame.lua | 108 +++++++++++++++++++-------- filter_search_frame.xml | 2 +- groups.lua | 55 +++++++++++++- gui.lua | 46 +++++++----- item_search_frame.lua | 10 +-- post_frame.lua | 8 +- scan.lua | 37 +++++++--- scan_frame.lua | 6 -- scan_util.lua | 157 +++++++++++++++++++++++++++++++++++++--- util.lua | 6 ++ 14 files changed, 349 insertions(+), 111 deletions(-) diff --git a/Aux-AddOn.toc b/Aux-AddOn.toc index a282cbd..febc735 100644 --- a/Aux-AddOn.toc +++ b/Aux-AddOn.toc @@ -1,8 +1,8 @@ ## Interface: 11200 ## Title: Aux ## Notes: A lightweight addon designed to help manage auctions -## SavedVariablesPerCharacter: aux_recently_searched, aux_view, AUX_AUCTION_DURATION -## SavedVariables: aux_groups, aux_database, aux_auctionable_items +## SavedVariablesPerCharacter: aux_recently_searched, aux_recent_searches, aux_favorite_searches, aux_view, AUX_AUCTION_DURATION +## SavedVariables: aux_database, aux_auctionable_items slash.lua core.xml diff --git a/auctions_frame.lua b/auctions_frame.lua index 75f947a..e7af9aa 100644 --- a/auctions_frame.lua +++ b/auctions_frame.lua @@ -172,12 +172,6 @@ function public.update_auction_records() { type = 'owner', start_page = 0, - next_page = function(page, total_pages) - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end, } }, on_page_loaded = function(page, total_pages) diff --git a/bids_frame.lua b/bids_frame.lua index b206d37..169c1c2 100644 --- a/bids_frame.lua +++ b/bids_frame.lua @@ -187,12 +187,6 @@ function public.update_bid_records() { type = 'bidder', start_page = 0, - next_page = function(page, total_pages) - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end, } }, on_page_loaded = function(page, total_pages) diff --git a/core.lua b/core.lua index 9c3980b..c938f68 100644 --- a/core.lua +++ b/core.lua @@ -395,4 +395,13 @@ function Aux.item_subclass_index(class_index, item_subclass) return i end end +end + +function Aux.item_quality_index(item_quality) + for i=0,4 do + local quality = getglobal('ITEM_QUALITY'..i..'_DESC') + if strlower(item_quality) == strlower(quality) then + return i + end + end end \ No newline at end of file diff --git a/filter_search_frame.lua b/filter_search_frame.lua index 51d62df..fc0b34d 100644 --- a/filter_search_frame.lua +++ b/filter_search_frame.lua @@ -390,6 +390,67 @@ function public.on_load() [Aux.view.BID] = Aux.sheet.create(private.views[Aux.view.BID]), [Aux.view.FULL] = Aux.sheet.create(private.views[Aux.view.FULL]), } + do + local btn = Aux.gui.button(AuxFilterSearchFrame, 22) + btn:SetPoint('TOPRIGHT', -5, -3) + btn:SetWidth(60) + btn:SetHeight(25) + btn:SetText('Search') + btn:SetScript('OnClick', Aux.filter_search_frame.start_search) + private.search_button = btn + end + do + local editbox = Aux.gui.editbox(AuxFilterSearchFrame) + editbox:SetPoint('TOPLEFT', 5, -3) + editbox:SetPoint('TOPRIGHT', private.search_button, 'TOPLEFT', -4, 0) + editbox:SetWidth(400) + editbox:SetHeight(25) +-- editbox:SetScript('OnTabPressed', function() +-- if IsShiftKeyDown() then +-- getglobal(this:GetParent():GetName()..'TooltipInputBox4'):SetFocus() +-- else +-- getglobal(this:GetParent():GetName()..'MinLevel'):SetFocus() +-- end +-- end) + editbox:SetScript('OnEnterPressed', function() + this:ClearFocus() + Aux.filter_search_frame.start_search() + end) + editbox:SetScript('OnEscapePressed', function() + this:ClearFocus() + end) + private.search_box = editbox + end + do + Aux.gui.horizontal_line(AuxFilterSearchFrame, -35) + end + do + local btn = Aux.gui.button(AuxFilterSearchFrame, 18) + btn:SetPoint('TOPLEFT', 10, -40) + btn:SetWidth(220) + btn:SetHeight(24) + btn:SetText('Search Results') + btn:SetScript('OnClick', Aux.filter_search_frame.start_search) + private.search_results_button = btn + end + do + local btn = Aux.gui.button(AuxFilterSearchFrame, 18) + btn:SetPoint('TOPLEFT', private.search_results_button, 'TOPRIGHT', 5, 0) + btn:SetWidth(220) + btn:SetHeight(24) + btn:SetText('Saved Searches') + btn:SetScript('OnClick', Aux.filter_search_frame.start_search) + private.saved_searches_button = btn + end + do + local btn = Aux.gui.button(AuxFilterSearchFrame, 18) + btn:SetPoint('TOPLEFT', private.saved_searches_button, 'TOPRIGHT', 5, 0) + btn:SetWidth(220) + btn:SetHeight(24) + btn:SetText('New Filter') + btn:SetScript('OnClick', Aux.filter_search_frame.start_search) + private.new_filter_button = btn + end do local btn = Aux.gui.button(AuxFilterSearchFrameFilters, 16, '$parentSearchButton') btn:SetPoint('BOTTOMLEFT', 8, 15) @@ -703,14 +764,6 @@ function private.create_filter_query() return { type = 'list', start_page = AuxFilterSearchFrameFiltersAllPagesCheckButton:GetChecked() and 0 or AuxFilterSearchFrameFiltersPageEditBox:GetNumber(), - next_page = function(page, total_pages) - if AuxFilterSearchFrameFiltersAllPagesCheckButton:GetChecked() then - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end - end, name = AuxFilterSearchFrameFiltersNameInputBox:GetText(), min_level = AuxFilterSearchFrameFiltersMinLevel:GetText(), max_level = AuxFilterSearchFrameFiltersMaxLevel:GetText(), @@ -750,22 +803,19 @@ function public.start_search() local queries - if false then - queries = { private.create_filter_query() } - else - queries = Aux.util.map(group, function(item_key) - return Aux.scan_util.create_item_query( - Aux.groups.parse_item_key(item_key), - 'list', - 0, - function(page, total_pages) - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end - ) +-- queries = { private.create_filter_query() } + local filters = Aux.scan_util.parse_filter_string(private.search_box:GetText()) + if filters then + queries = Aux.util.map(filters, function(filter) + return { + type = 'list', + start_page = 0, + blizzard_query = Aux.scan_util.blizzard_query(filter), + validator = Aux.scan_util.validator(filter), + } end) + else + return end @@ -781,15 +831,9 @@ function public.start_search() end, on_read_auction = function(auction_info) auctions = auctions or {} - if false then - if Aux.info.tooltip_match(tooltip_patterns, auction_info.tooltip) then - tinsert(auctions, private.create_auction_record(auction_info)) - end - else - if Aux.util.any(group, function(item_key) return auction_info.item_id == Aux.groups.parse_item_key(item_key) end) then - tinsert(auctions, private.create_auction_record(auction_info)) - end - end +-- if Aux.info.tooltip_match(tooltip_patterns, auction_info.tooltip) then + tinsert(auctions, private.create_auction_record(auction_info)) +-- end end, on_complete = function() auctions = auctions or {} diff --git a/filter_search_frame.xml b/filter_search_frame.xml index a3a2f5c..b38dfd1 100644 --- a/filter_search_frame.xml +++ b/filter_search_frame.xml @@ -14,7 +14,7 @@ - + diff --git a/groups.lua b/groups.lua index 4ec283a..28353ce 100644 --- a/groups.lua +++ b/groups.lua @@ -11,4 +11,57 @@ function m.parse_item_key(item_key) return tonumber(item_id), suffix_id == '' and 0 or tonumber(suffix_id) end -m.test_group = '13127,9510,4438,16254,12006,13131,13012,4413,1482' \ No newline at end of file +m.test_group = '13127,9510,4438,16254,12006,13131,13012,4413,1482' + + +--function private:StartFilterSearch() +-- local filter = private.frame.filter.filterInputBox:GetText() +-- +-- local minLevel = private.frame.filter.levelMinBox:GetNumber() +-- local maxLevel = private.frame.filter.levelMaxBox:GetNumber() +-- if maxLevel > 0 then +-- filter = format("%s/%d/%d", filter, minLevel, maxLevel) +-- elseif minLevel > 0 then +-- filter = format("%s/%d", filter, minLevel) +-- end +-- +-- local minItemLevel = private.frame.filter.itemLevelMinBox:GetNumber() +-- local maxItemLevel = private.frame.filter.itemLevelMaxBox:GetNumber() +-- if maxItemLevel > 0 then +-- filter = format("%s/i%d/i%d", filter, minItemLevel, maxItemLevel) +-- elseif minItemLevel > 0 then +-- filter = format("%s/i%d", filter, minItemLevel) +-- end +-- +-- local class = private.frame.filter.classDropdown:GetValue() +-- if class then +-- local classes = {GetAuctionItemClasses()} +-- filter = format("%s/%s", filter, classes[class]) +-- local subClass = private.frame.filter.subClassDropdown:GetValue() +-- if subClass then +-- local subClasses = {GetAuctionItemSubClasses(class)} +-- filter = format("%s/%s", filter, subClasses[subClass]) +-- end +-- end +-- +-- local rarity = private.frame.filter.rarityDropdown:GetValue() +-- if rarity then +-- filter = format("%s/%s", filter, _G["ITEM_QUALITY"..rarity.."_DESC"]) +-- end +-- +-- if private.frame.filter.usableCheckBox:GetValue() then +-- filter = format("%s/usable", filter) +-- end +-- +-- if private.frame.filter.exactCheckBox:GetValue() then +-- filter = format("%s/exact", filter) +-- end +-- +-- local maxQty = private.frame.filter.maxQtyBox:GetNumber() +-- if maxQty > 0 then +-- filter = format("%s/x%d", filter, maxQty) +-- end +-- +-- local searchInfo = {searchMode="normal", extraInfo={searchType="filter"}, filter=filter} +-- TSM.AuctionTab:StartSearch(searchInfo) +--end \ No newline at end of file diff --git a/gui.lua b/gui.lua index 5bde5f8..1a187ff 100644 --- a/gui.lua +++ b/gui.lua @@ -16,6 +16,14 @@ m.config = { } +function m.panel(parent) + local panel = CreateFrame('Frame', parent) + panel:SetBackdrop({bgFile='Interface\\Buttons\\WHITE8X8', edgeFile='Interface\\Buttons\\WHITE8X8', edgeSize=m.config.edge_size}) + panel:SetBackdropColor(unpack(m.config.frame_color)) + panel:SetBackdropBorderColor(unpack(m.config.frame_border_color)) + return panel +end + function m.button(parent, text_height, name) local button = CreateFrame('Button', name, parent) button:SetBackdrop({bgFile='Interface\\Buttons\\WHITE8X8', edgeFile='Interface\\Buttons\\WHITE8X8', edgeSize=m.config.edge_size}) @@ -336,32 +344,30 @@ function m.label(parent, size) return label end -function m.CreateHorizontalLine(parent, ofsy, relativeFrame, invertedColor) - relativeFrame = relativeFrame or parent - local barTex = parent:CreateTexture() - barTex:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", 2, ofsy) - barTex:SetPoint("TOPRIGHT", relativeFrame, "TOPRIGHT", -2, ofsy) - barTex:SetHeight(2) - if invertedColor then - TSMAPI.Design:SetFrameColor(barTex) +function m.horizontal_line(parent, y_offset, inverted_color) + local texture = parent:CreateTexture() + texture:SetPoint('TOPLEFT', parent, 'TOPLEFT', 2, y_offset) + texture:SetPoint('TOPRIGHT', parent, 'TOPRIGHT', -2, y_offset) + texture:SetHeight(2) + if inverted_color then + texture:SetTexture(unpack(m.config.frame_color)) else - TSMAPI.Design:SetContentColor(barTex) + texture:SetTexture(unpack(m.config.content_color)) end - return barTex + return texture end -function m.CreateVerticalLine(parent, ofsx, relativeFrame, invertedColor) - relativeFrame = relativeFrame or parent - local barTex = parent:CreateTexture() - barTex:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", ofsx, -2) - barTex:SetPoint("BOTTOMLEFT", relativeFrame, "BOTTOMLEFT", ofsx, 2) - barTex:SetWidth(2) - if invertedColor then - TSMAPI.Design:SetFrameColor(barTex) +function m.vertical_line(parent, x_offset, inverted_color) + local texture = parent:CreateTexture() + texture:SetPoint('TOPLEFT', parent, 'TOPLEFT', x_offset, -2) + texture:SetPoint('BOTTOMLEFT', parent, 'BOTTOMLEFT', x_offset, 2) + texture:SetWidth(2) + if inverted_color then + texture:SetTexture(unpack(m.config.frame_color)) else - TSMAPI.Design:SetContentColor(barTex) + texture:SetTexture(unpack(m.config.content_color)) end - return barTex + return texture end function m.dropdown() diff --git a/item_search_frame.lua b/item_search_frame.lua index 0db6729..a0355b8 100644 --- a/item_search_frame.lua +++ b/item_search_frame.lua @@ -552,15 +552,7 @@ function public.start_search() local query = Aux.scan_util.create_item_query( item_id, 'list', - AuxItemSearchFrameItemAllPagesCheckButton:GetChecked() and 0 or AuxItemSearchFrameItemPageEditBox:GetNumber(), - function(page, total_pages) - if AuxItemSearchFrameItemAllPagesCheckButton:GetChecked() then - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end - end + AuxItemSearchFrameItemAllPagesCheckButton:GetChecked() and 0 or AuxItemSearchFrameItemPageEditBox:GetNumber() ) Aux.scan.start{ diff --git a/post_frame.lua b/post_frame.lua index c59894b..e2756ce 100644 --- a/post_frame.lua +++ b/post_frame.lua @@ -697,13 +697,7 @@ function private.refresh_entries() local query = Aux.scan_util.create_item_query( item_id, 'list', - 0, - function(page, total_pages) - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end + 0 ) private.status_bar:update_status(0,0) diff --git a/scan.lua b/scan.lua index 7cd49cf..8c5283e 100644 --- a/scan.lua +++ b/scan.lua @@ -15,6 +15,13 @@ local state local scan_auctions, scan_auctions_helper, submit_query, wait_for_callback, wait_for_results, wait_for_owner_data, on_abort, current_query +function private.default_next_page(page, total_pages) + local last_page = max(total_pages - 1, 0) + if page < last_page then + return page + 1 + end +end + function current_query() return state.params.queries[state.query_index] end @@ -140,7 +147,11 @@ function private.process_query() scan_auctions(count, function() - state.page = current_query().next_page and current_query().next_page(state.page, state.total_pages) + if current_query().next_page then + state.page = current_query().next_page(state.page, state.total_pages) + else + state.page = private.default_next_page(state.page, state.total_pages) + end if state.page then return private.process_query() @@ -176,10 +187,12 @@ function scan_auctions_helper(i, n, k) Aux.history.process_auction(auction_info) end - wait_for_callback{state.params.on_read_auction or Aux.util.pass, auction_info, recurse} - else - recurse() + if not current_query().validator or current_query().validator(auction_info) then + return wait_for_callback{state.params.on_read_auction or Aux.util.pass, auction_info, recurse } + end end + + return recurse() end function submit_query(k) @@ -208,15 +221,15 @@ function submit_query(k) GetOwnerAuctionItems(state.page) else QueryAuctionItems( - current_query().name, - current_query().min_level, - current_query().max_level, - current_query().slot, - current_query().class, - current_query().subclass, + Aux.util.safe_index{current_query(), 'blizzard_query', 'name'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'min_level'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'max_level'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'slot'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'class'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'subclass'}, state.page, - current_query().usable, - current_query().quality + Aux.util.safe_index{current_query(), 'blizzard_query', 'usable'}, + Aux.util.safe_index{current_query(), 'blizzard_query', 'quality'} ) end end) diff --git a/scan_frame.lua b/scan_frame.lua index 1263556..9c88d1a 100644 --- a/scan_frame.lua +++ b/scan_frame.lua @@ -25,12 +25,6 @@ function public.start_scan() queries = {{ type = 'list', start_page = 0, - next_page = function(page, total_pages) - local last_page = max(total_pages - 1, 0) - if page < last_page then - return page + 1 - end - end, }}, on_page_loaded = function(page, total_pages) Aux.log('Scanning page '..(page+1)..' out of '..total_pages..' ...') diff --git a/scan_util.lua b/scan_util.lua index bd161bc..b42f137 100644 --- a/scan_util.lua +++ b/scan_util.lua @@ -10,16 +10,19 @@ function m.find(test, query, page, status_bar, on_failure, on_success) local pages = page > 0 and { page, page - 1 } or { page } - query = Aux.util.copy_table(query) - query.start_page = nil - query.next_page = function() - if getn(pages) == 1 then - status_bar:update_status(50, 50) + local new_query = { + type = query.type, + validator = test, + blizzard_query = query.blizzard_query, + next_page = function() + if getn(pages) == 1 then + status_bar:update_status(50, 50) + end + local page = pages[1] + tremove(pages, 1) + return page end - local page = pages[1] - tremove(pages, 1) - return page - end + } Aux.scan.start{ queries = { query }, @@ -47,6 +50,9 @@ end function m.create_item_query(item_id, type, start_page, next_page) local item_info = Aux.static.item_info(item_id) + local function validator(auction_info) + return auction_info.item_id == item_id + end -- local class_index = Aux.item_class_index(item_info.class) -- local subclass_index = class_index and Aux.item_subclass_index(class_index, item_info.subclass) -- TODO test if needed @@ -65,4 +71,137 @@ function m.create_item_query(item_id, type, start_page, next_page) quality = item_info.quality, usable = item_info.usable, } +end + +function m.parse_filter_string(filter_string) + local parts = {Aux.persistence.deserialize(filter_string, ';')} + + local filters = {} + for _, str in ipairs(parts) do + str = Aux.util.trim(str) + if tonumber(str) then + local filter = Aux.scan_util.create_item_query(tonumber(str)) + if filter then + tinsert(filters, filter) + end + else + local filter, error = m.filter(str) + + if not filter then + Aux.log('Invalid filter: '..error) + elseif strlen(filter.query_string) > 63 then + + else + tinsert(filters, filter) + end + end + end + + return filters +end + +function m.filter(filter_term) + local parts = {Aux.persistence.deserialize(filter_term, '/')} + local query_string, class, subclass, min_level, max_level, quality, usable_only, exact_only, even_only, min_profit, max_percentage + + if getn(parts) == 0 then + return false, 'Invalid Filter' + end + + for i, str in ipairs(parts) do + str = Aux.util.trim(str) + + if tonumber(str) then + if not min_level then + min_level = tonumber(str) + elseif not max_level then + max_level = tonumber(str) + else + return false, 'Invalid Min Level' + end + elseif not class and Aux.item_class_index(str) then + if not class then + class = Aux.item_class_index(str) + else + return false, 'Invalid Item Type' + end + elseif Aux.item_subclass_index(class, str) then + if not subclass then + subclass = Aux.item_subclass_index(class, str) + else + return false, 'Invalid Item SubType' + end + elseif Aux.item_quality_index(str) then + if not quality then + quality = Aux.item_quality_index(str) + else + return false, 'Invalid Item Rarity' + end + elseif strlower(str) == 'usable' then + if not usable_only then + usable_only = true + else + return false, 'Invalid Usable Only Filter' + end + elseif strlower(str) == 'exact' then + if not exact_only then + exact_only = true + else + return false, 'Invalid Exact Only Filter' + end + elseif strlower(str) == 'even' then + if not even_only then + even_only = true + else + return false, 'Invalid Even Only Filter' + end + elseif Aux.money.from_string(str) then + min_profit = Aux.money.from_string(str) + elseif i == 1 then + query_string = str + else + return false, 'Unknown Filter' + end + end + + min_level, max_level = min(min_level, max_level), max(min_level, max_level) + + return { query_string or '', class or 0, subclass or 0, min_level or 0, max_level or 0, quality or 0, usable_only or 0, exact_only or nil, even_only or nil, min_profit } +end + +function m.blizzard_query(filter) + return { + name = filter.query_string, + min_level = filter.min_level, + max_level = filter.max_level, + slot = filter.slot, + class = filter.class, + subclass = filter.subclass, + usable = filter.usable_only, + quality = filter.quality, + } +end + +function m.validator(filter) + + return function(record) + + if filter.exact_only and record.name ~= record.name then + return + end + + if filter.even_only and rem(record.aux_quantity, 5) ~= 0 then + return + end + + if filter.min_level > 0 and record.level < record.min_level then + return + end + + if filter.max_level > 0 and record.level > record.max_level then + return + end + + return true + end end \ No newline at end of file diff --git a/util.lua b/util.lua index ea42163..27ca358 100644 --- a/util.lua +++ b/util.lua @@ -18,6 +18,12 @@ function public.copy_table(table) return copy end +function public.trim(string) + string = gsub(string, '^%s*', '') + string = gsub(string, '%s*$', '') + return string +end + function Aux.util.inventory_iterator() local inventory = {} for bag = 0, 4 do