big refactoring

This commit is contained in:
Manuel Simon Hirsig
2016-08-17 15:08:11 +02:00
parent 2a7dea236d
commit 3624c8c4c0
34 changed files with 357 additions and 447 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'cache'
aux.module 'cache'
private.MIN_ITEM_ID = 1
private.MAX_ITEM_ID = 30000
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'disenchant'
aux.module 'disenchant'
private.UNCOMMON = 2
private.RARE = 3
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'history'
aux.module 'history'
local history_schema = {'record', '#', {next_push='number'}, {daily_min_buyout='number'}, {daily_max_price='number'}, {data_points={'list', ';', {'record', '@', {market_value='number'}, {time='number'}}}}}
private.value_cache = {}
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'post'
aux.module 'post'
private.state = nil
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'scan'
aux.module 'scan'
private.PAGE_SIZE = 50
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'stack'
aux.module 'stack'
private.state = nil
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'tooltip'
aux.module 'tooltip'
aux_tooltip_value = true
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'control'
aux.module 'control'
private.event_frame = CreateFrame('Frame')
private.listeners = {}
+50 -29
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'aux'
aux.module ''
public.bids_loaded = false
public.current_owner_page = nil
@@ -38,17 +38,39 @@ do
end
end
do
local temp
local mt = {
__call = function(self, object)
self._temp = object
return object
end,
__index = function(self)
return self._temp
end,
}
function public.temp(object)
local env = getfenv(2)
env.__ = object
return env.__(object)
end
end
function public.L(body_string)
return loadstring 'function()'
end
private.tabs = {}
function public.tab(index, title, name)
local tab = {title=title, name=name, module={m.module(name)}}
tab.module[2].ACTIVE = function()
function public.tab(index, name)
local module_env = getfenv(2)
local tab = {name=name, env=module_env}
module_env.public.ACTIVE = function()
return tab == m.active_tab()
end
for _, handler in {'OPEN', 'CLOSE', 'CLICK_LINK', 'USE_ITEM'} do
tab.module[3][handler] = nil
module_env.private[handler] = 5
end
m.tabs[index] = tab
return unpack(tab.module)
end
do
local active_tab_index
@@ -57,11 +79,11 @@ do
end)
function private.on_tab_click(index)
if active_tab_index then
m.call(m.active_tab.module[1].CLOSE)
m.call(m.active_tab.env.CLOSE)
end
active_tab_index = index
if active_tab_index then
m.call(m.active_tab.module[1].OPEN)
m.call(m.active_tab.env.OPEN)
end
end
end
@@ -78,7 +100,7 @@ function public.VARIABLES_LOADED()
frame:SetMovable(true)
frame:EnableMouse(true)
frame:SetClampedToScreen(true)
frame:RegisterForDrag('LeftButton')
frame:RegisterForDrag 'LeftButton'
frame:SetScript('OnDragStart', function()
this:StartMoving()
end)
@@ -86,10 +108,10 @@ function public.VARIABLES_LOADED()
this:StopMovingOrSizing()
end)
frame:SetScript('OnShow', function()
PlaySound('AuctionWindowOpen')
PlaySound 'AuctionWindowOpen'
end)
frame:SetScript('OnHide', function()
PlaySound('AuctionWindowClose')
PlaySound 'AuctionWindowClose'
CloseAuctionHouse()
end)
frame.content = CreateFrame('Frame', nil, frame)
@@ -98,32 +120,31 @@ function public.VARIABLES_LOADED()
frame:Hide()
public.frame = frame
end
do
local tab_group = m.gui.tab_group(m.frame, 'DOWN')
local tabs = m.gui.tabs(m.frame, 'DOWN')
for _, tab in m.tabs do
tab_group:create_tab(tab.title)
tabs:create_tab(tab.name)
end
tabs._on_select = m.on_tab_click
function public.set_tab(id)
tabs:select(id)
end
tab_group.on_select = m.on_tab_click
public.tab_group = tab_group
end
do
local btn = m.gui.button(m.frame, 16)
btn:SetPoint('BOTTOMRIGHT', -6, 6)
btn:SetWidth(65)
btn:SetHeight(24)
btn:SetText('Close')
btn:SetText 'Close'
btn:SetScript('OnClick', m._(m.frame.Hide, m.frame))
public.close_button = btn
end
do
local btn = m.gui.button(m.frame, 16)
btn:SetPoint('RIGHT', m.close_button, 'LEFT' , -5, 0)
btn:SetWidth(65)
btn:SetHeight(24)
btn:SetText('Default UI')
btn:SetText 'Default UI'
btn:SetScript('OnClick',function()
if AuctionFrame:IsVisible() then
HideUIPanel(AuctionFrame)
@@ -137,7 +158,7 @@ end
function private.AUCTION_HOUSE_SHOW()
AuctionFrame:Hide()
m.frame:Show()
m.tab_group:set_tab(1)
m.set_tab(1)
end
function private.AUCTION_HOUSE_CLOSED()
@@ -146,7 +167,7 @@ function private.AUCTION_HOUSE_CLOSED()
m.post.stop()
m.stack.stop()
m.scan.abort()
m.tab_group:set_tab()
m.set_tab()
m.frame:Hide()
end
@@ -198,7 +219,7 @@ do
break
end
local item_id, suffix_id = m.info.parse_hyperlink(link)
local count = ({GetCraftReagentInfo(id, i)})[3]
local count = aux.util.select(3, GetCraftReagentInfo(id, i))
local _, price, limited = m.cache.merchant_info(item_id)
local value = price and not limited and price or m.history.value(item_id..':'..suffix_id)
if not value then
@@ -230,7 +251,7 @@ do
break
end
local item_id, suffix_id = m.info.parse_hyperlink(link)
local count = ({GetTradeSkillReagentInfo(id, i)})[3]
local count = aux.util.select(3, GetTradeSkillReagentInfo(id, i))
local _, price, limited = m.cache.merchant_info(item_id)
local value = price and not limited and price or m.history.value(item_id..':'..suffix_id)
if not value then
@@ -280,20 +301,20 @@ function private.AuctionFrameAuctions_OnEvent(...)
end
function private.SetItemRef(...)
if arg[3] ~= 'RightButton' or not m.index(m.active_tab(), 'module', 1, 'CLICK_LINK') or not strfind(arg[1], '^item:%d+') then
if arg[3] ~= 'RightButton' or not m.index(m.active_tab(), 'env', 'CLICK_LINK') or not strfind(arg[1], '^item:%d+') then
return m.orig.SetItemRef(unpack(arg))
end
for _, item_info in {m.info.item(tonumber(({strfind(arg[1], '^item:(%d+)')})[3]))} do
return m.active_tab.module[1].CLICK_LINK(item_info)
for item_info in aux.util.present(m.info.item(tonumber(({strfind(arg[1], '^item:(%d+)')})[3]))) do
return m.active_tab.env.CLICK_LINK(item_info)
end
end
function private.UseContainerItem(...)
if m.modified() or not m.index(m.active_tab(), 'module', 1, 'USE_ITEM') then
if m.modified() or not m.index(m.active_tab(), 'env', 'USE_ITEM') then
return m.orig.UseContainerItem(unpack(arg))
end
for _, item_info in {m.info.container_item(arg[1], arg[2])} do
return m.active_tab.module[1].USE_ITEM(item_info)
return m.active_tab.env.USE_ITEM(item_info)
end
end
+92 -97
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'gui'
aux.module 'gui'
public.config = {
color = {
@@ -265,105 +265,99 @@ function public.resize_tab(tab, width, padding)
tab:SetWidth(width + padding + 10)
end
do
local mt = {__index={}}
function mt.__index:create_tab(text)
local id = getn(self._tabs) + 1
function public.tab_group(parent, orientation)
local tab = CreateFrame('Button', m.name(), self._frame)
tab.id = id
tab.group = self
tab:SetHeight(24)
tab:SetBackdrop{bgFile=[[Interface\Buttons\WHITE8X8]], edgeFile=[[Interface\Buttons\WHITE8X8]], edgeSize=m.config.edge_size}
tab:SetBackdropBorderColor(m.color.panel.border())
local dock = tab:CreateTexture(nil, 'OVERLAY')
dock:SetHeight(3)
if self._orientation == 'UP' then
dock:SetPoint('BOTTOMLEFT', 1, -1)
dock:SetPoint('BOTTOMRIGHT', -1, -1)
elseif self._orientation == 'DOWN' then
dock:SetPoint('TOPLEFT', 1, 1)
dock:SetPoint('TOPRIGHT', -1, 1)
end
dock:SetTexture(m.color.panel.background())
tab.dock = dock
local highlight = tab:CreateTexture(nil, 'HIGHLIGHT')
highlight:SetAllPoints()
highlight:SetTexture(1, 1, 1, .2)
highlight:SetBlendMode 'BLEND'
tab.highlight = highlight
local frame = CreateFrame('Frame', nil, parent)
frame:SetHeight(100)
frame:SetWidth(100)
tab.text = tab:CreateFontString()
tab.text:SetPoint('LEFT', 3, -1)
tab.text:SetPoint('RIGHT', -3, -1)
tab.text:SetJustifyH 'CENTER'
tab.text:SetJustifyV 'CENTER'
tab.text:SetFont(m.config.font, m.config.large_font_size2)
tab:SetFontString(tab.text)
local self = {
frame = parent,
tabs = {},
}
tab:SetText(text)
function self:create_tab(text)
local id = getn(self.tabs) + 1
tab:SetScript('OnClick', function()
if this.id ~= this.group.selected then
PlaySound 'igCharacterInfoTab'
this.group:select(this.id)
end
end)
local tab = CreateFrame('Button', m.name(), self.frame)
tab.id = id
tab.group = self
tab:SetHeight(24)
tab:SetBackdrop{bgFile=[[Interface\Buttons\WHITE8X8]], edgeFile=[[Interface\Buttons\WHITE8X8]], edgeSize=m.config.edge_size}
tab:SetBackdropBorderColor(unpack(m.color.panel.border))
local dock = tab:CreateTexture(nil, 'OVERLAY')
dock:SetHeight(3)
if orientation == 'UP' then
dock:SetPoint('BOTTOMLEFT', 1, -1)
dock:SetPoint('BOTTOMRIGHT', -1, -1)
elseif orientation == 'DOWN' then
dock:SetPoint('TOPLEFT', 1, 1)
dock:SetPoint('TOPRIGHT', -1, 1)
end
dock:SetTexture(unpack(m.color.panel.background))
tab.dock = dock
local highlight = tab:CreateTexture(nil, 'HIGHLIGHT')
highlight:SetAllPoints()
highlight:SetTexture(1, 1, 1, .2)
highlight:SetBlendMode('BLEND')
tab.highlight = highlight
if getn(self._tabs) == 0 then
if self._orientation == 'UP' then
tab:SetPoint('BOTTOMLEFT', self._frame, 'TOPLEFT', 4, -1)
elseif self._orientation == 'DOWN' then
tab:SetPoint('TOPLEFT', self._frame, 'BOTTOMLEFT', 4, 1)
end
else
if self._orientation == 'UP' then
tab:SetPoint('BOTTOMLEFT', self._tabs[getn(self._tabs)], 'BOTTOMRIGHT', 4, 0)
elseif self._orientation == 'DOWN' then
tab:SetPoint('TOPLEFT', self._tabs[getn(self._tabs)], 'TOPRIGHT', 4, 0)
end
end
tab.text = tab:CreateFontString()
tab.text:SetPoint('LEFT', 3, -1)
tab.text:SetPoint('RIGHT', -3, -1)
tab.text:SetJustifyH('CENTER')
tab.text:SetJustifyV('CENTER')
tab.text:SetFont(m.config.font, m.config.large_font_size2)
tab:SetFontString(tab.text)
m.resize_tab(tab, tab:GetFontString():GetStringWidth(), 4)
tab:SetText(text)
tab:SetScript('OnClick', function()
if this.id ~= this.group.selected then
PlaySound('igCharacterInfoTab')
this.group:set_tab(this.id)
end
end)
if getn(self.tabs) == 0 then
if orientation == 'UP' then
tab:SetPoint('BOTTOMLEFT', self.frame, 'TOPLEFT', 4, -1)
elseif orientation == 'DOWN' then
tab:SetPoint('TOPLEFT', self.frame, 'BOTTOMLEFT', 4, 1)
end
else
if orientation == 'UP' then
tab:SetPoint('BOTTOMLEFT', self.tabs[getn(self.tabs)], 'BOTTOMRIGHT', 4, 0)
elseif orientation == 'DOWN' then
tab:SetPoint('TOPLEFT', self.tabs[getn(self.tabs)], 'TOPRIGHT', 4, 0)
end
end
m.resize_tab(tab, tab:GetFontString():GetStringWidth(), 4)
tinsert(self.tabs, tab)
end
function self:set_tab(id)
self.selected = id
self:update_tabs()
aux.call(self.on_select, id)
end
function self:update_tabs()
for _, tab in self.tabs do
if tab.group.selected == tab.id then
tab.text:SetTextColor(unpack(m.color.label.enabled))
tab:Disable()
tab:SetBackdropColor(unpack(m.color.panel.background))
tab.dock:Show()
tab:SetHeight(29)
else
tab.text:SetTextColor(unpack(m.color.text.enabled))
tab:Enable()
tab:SetBackdropColor(unpack(m.color.content.background))
tab.dock:Hide()
tab:SetHeight(24)
end
end
end
return self
tinsert(self._tabs, tab)
end
function mt.__index:select(id)
self._selected = id
self:update()
aux.call(self._on_select, id)
end
function mt.__index:update()
for _, tab in self._tabs do
if tab.group.selected == tab.id then
tab.text:SetTextColor(m.color.label.enabled())
tab:Disable()
tab:SetBackdropColor(m.color.panel.background())
tab.dock:Show()
tab:SetHeight(29)
else
tab.text:SetTextColor(m.color.text.enabled())
tab:Enable()
tab:SetBackdropColor(m.color.content.background())
tab.dock:Hide()
tab:SetHeight(24)
end
end
end
function public.tabs(parent, orientation)
local self = {
_frame = parent,
_orientation = orientation,
_tabs = {},
}
return setmetatable(self, mt)
end
end
function public.editbox(parent)
@@ -384,6 +378,7 @@ function public.editbox(parent)
local x, y = GetCursorPosition()
-- local offset = x - editbox:GetLeft()*editbox:GetEffectiveScale() TODO use a fontstring to measure getstringwidth for structural highlighting
-- editbox:Insert'<ksejfkj>' TODO use insert with special tags to determine cursor position
-- or use an overlay with itemlinks
if last_click and GetTime() - last_click.t < .5 and x == last_click.x and y == last_click.y then
aux.control.thread(function() editbox:HighlightText() end)
end
@@ -412,10 +407,10 @@ function public.status_bar(parent)
do
-- minor status bar (gray one)
local status_bar = CreateFrame('STATUSBAR', nil, self, 'TextStatusBar')
status_bar:SetOrientation('HORIZONTAL')
status_bar:SetOrientation 'HORIZONTAL'
status_bar:SetMinMaxValues(0, 100)
status_bar:SetAllPoints()
status_bar:SetStatusBarTexture([[Interface\Buttons\WHITE8X8]])
status_bar:SetStatusBarTexture [[Interface\Buttons\WHITE8X8]]
status_bar:SetStatusBarColor(.42, .42, .42, .7)
status_bar:SetFrameLevel(level + 2)
status_bar:SetScript('OnUpdate', function()
@@ -431,10 +426,10 @@ function public.status_bar(parent)
do
-- major status bar (main blue one)
local status_bar = CreateFrame('STATUSBAR', nil, self, 'TextStatusBar')
status_bar:SetOrientation('HORIZONTAL')
status_bar:SetOrientation 'HORIZONTAL'
status_bar:SetMinMaxValues(0, 100)
status_bar:SetAllPoints()
status_bar:SetStatusBarTexture([[Interface\Buttons\WHITE8X8]])
status_bar:SetStatusBarTexture [[Interface\Buttons\WHITE8X8]]
status_bar:SetStatusBarColor(.19, .22, .33, .9)
status_bar:SetFrameLevel(level + 3)
status_bar:SetScript('OnUpdate', function()
+20 -22
View File
@@ -1,33 +1,34 @@
local addon = {aux_module()}
aux = tremove(addon, 1)
local m, public, private = unpack(addon)
setglobal('aux', aux_module())
public.version = '4.0.0'
private.modules = {}
private.module_envs = {}
function public.module(path)
if path == 'aux' then
return unpack(addon)
elseif m.modules[path] then
return unpack(m.modules[path])
local env
if path == '' then
env = getfenv()
elseif m.module_envs[path] then
env = m.module_envs[path]
else
local module, prefix
local prefix
for name in string.gfind(path, '[%a_][%w_]*') do
local qualified_name = prefix and prefix..'.'..name or name
module = m.modules[qualified_name]
if not module then
module = {aux_module()}
module[4].LOAD = nil
(prefix and m.modules[prefix] or addon)[2][name] = tremove(module, 1)
m.modules[qualified_name] = module
env = m.module_envs[qualified_name]
if not env then
(prefix and m.module_envs[prefix].public or public)[name], env = (function() return aux_module(), getfenv() end)()
env.private.LOAD = nil
m.module_envs[qualified_name] = env
end
prefix = qualified_name
end
return unpack(module)
end
setfenv(2, env)
end
local event_frame = CreateFrame('Frame')
for _, event in {'VARIABLES_LOADED', 'ADDON_LOADED', 'AUCTION_HOUSE_SHOW', 'AUCTION_HOUSE_CLOSED', 'AUCTION_BIDDER_LIST_UPDATE', 'AUCTION_OWNED_LIST_UPDATE'} do
event_frame:RegisterEvent(event)
end
private.ADDON_LOADED = {}
event_frame:SetScript('OnEvent', function()
if event == 'ADDON_LOADED' then
@@ -37,15 +38,12 @@ event_frame:SetScript('OnEvent', function()
else
m[event]()
if event == 'VARIABLES_LOADED' then
for _, module in m.modules do
if module[1].LOAD then
module[1].LOAD()
for _, env in m.module_envs do
if env.LOAD then
env.LOAD()
end
end
m.log('v'..m.version..' loaded.')
end
end
end)
for _, event in {'VARIABLES_LOADED', 'ADDON_LOADED', 'AUCTION_HOUSE_SHOW', 'AUCTION_HOUSE_CLOSED', 'AUCTION_BIDDER_LIST_UPDATE', 'AUCTION_OWNED_LIST_UPDATE'} do
event_frame:RegisterEvent(event)
end
+19 -4
View File
@@ -1,5 +1,14 @@
local PUBLIC, PRIVATE = 1, 2
local state = {}
local function_mt = {
__call = function(self, ...)
local f = state[self]
local temp = getfenv(f).__
getfenv(f).__ = {}
f(unpack(arg))
getfenv(f).__ = temp
end,
}
local interface_mt = {
__index = function(self, key)
if not state[self].access[state[self].type][key] then
@@ -30,11 +39,17 @@ local declarator_mt = {
end,
}
function aux_module()
local data, access = {}, {{}, {}}
local data, access = {}, {{}, {__=true}}
local public_state, private_state = {type=PUBLIC, data=data, access=access}, {type=PRIVATE, data=data, access=access}
local public_interface, private_interface = setmetatable({}, interface_mt), setmetatable({}, interface_mt)
local interface, private_interface = setmetatable({}, interface_mt), setmetatable({}, interface_mt)
local public_declarator, private_declarator = setmetatable({}, declarator_mt), setmetatable({}, declarator_mt)
state[public_interface], state[private_interface] = public_state, private_state
state[interface], state[private_interface] = public_state, private_state
state[public_declarator], state[private_declarator] = public_state, private_state
return public_interface, private_interface, public_declarator, private_declarator
local env = setmetatable({m=private_interface, public=public_declarator, private=private_declarator}, {__index=getfenv(0)})
-- public_state.env = env
-- private_state.env = env
setfenv(2, env)
return interface
end
+2 -2
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'auction_listing'
aux.module 'auction_listing'
local RT_COUNT = 1
local HEAD_HEIGHT = 27
@@ -654,7 +654,7 @@ local methods = {
elseif IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
ChatFrameEditBox:Insert(this.row.data.record.hyperlink)
elseif not aux.modified() and button == 'RightButton' then -- TODO not when alt (how?)
aux.tab_group:set_tab(1)
aux.set_tab(1)
aux.search_tab.set_filter(strlower(aux.info.item(this.row.data.record.item_id).name)..'/exact')
aux.search_tab.execute(nil, false)
else
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'item_listing'
aux.module 'item_listing'
local ROW_HEIGHT = 39
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'listing'
aux.module 'listing'
local ST_COUNT = 0
+2 -1
View File
@@ -1,4 +1,5 @@
local m, public, private = aux.tab(3, 'Auctions', 'auctions_tab')
aux.module 'auctions_tab'
aux.tab(3, 'Auctions', 'auctions_tab')
private.auction_records = nil
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'auctions_tab'
aux.module 'auctions_tab'
function private.create_frames()
private.frame = CreateFrame('Frame', nil, aux.frame)
+2 -1
View File
@@ -1,4 +1,5 @@
local m, public, private = aux.tab(4, 'Bids', 'bids_tab')
aux.module 'bids_tab'
aux.tab(4, 'Bids', 'bids_tab')
private.auction_records = nil
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'bids_tab'
aux.module 'bids_tab'
function private.create_frames()
private.frame = CreateFrame('Frame', nil, aux.frame)
+2 -1
View File
@@ -1,4 +1,5 @@
local m, public, private = aux.tab(2, 'Post', 'post_tab')
aux.module 'post_tab'
aux.tab(2, 'Post', 'post_tab')
local DURATION_4, DURATION_8, DURATION_24 = 120, 480, 1440
local settings_schema = {'record', '#', {stack_size='number'}, {duration='number'}, {start_price='number'}, {buyout_price='number'}, {hidden='boolean'}}
+2 -2
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'post_tab'
aux.module 'post_tab'
function private.create_frames()
private.frame = CreateFrame('Frame', nil, aux.frame)
@@ -46,7 +46,7 @@ function private.create_frames()
if arg1 == 'LeftButton' then
m.set_item(this.item_record)
elseif arg1 == 'RightButton' then
aux.tab_group:set_tab(1)
aux.set_tab(1)
aux.search_tab.set_filter(strlower(aux.info.item(this.item_record.item_id).name)..'/exact')
aux.search_tab.execute(nil, false)
end
+3 -1
View File
@@ -1,4 +1,5 @@
local m, public, private = aux.tab(1, 'Search', 'search_tab')
aux.module 'search_tab'
aux.tab(1, 'Search', 'search_tab')
StaticPopupDialogs['AUX_SEARCH_TABLE_FULL'] = {
text = 'Table full!\nFurther results from this search will still be processed but no longer displayed in the table.',
@@ -58,6 +59,7 @@ function m.LOAD()
end
function m.OPEN()
aux.log('kek2')
m.frame:Show()
m.update_search_listings()
end
+6 -34
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'search_tab'
aux.module 'search_tab'
function private.valid_level(str)
local level = tonumber(str)
@@ -109,7 +109,7 @@ function private.get_filter_builder_query()
end
local name = m.blizzard_query.name
if aux.index(aux.filter.parse_query_string(name), 'blizzard', 1, 1) ~= 'name' then
if not aux.index(aux.filter.parse_query_string(name), 'blizzard', 'name') then
name = aux.filter.quote(name)
end
add((name ~= '' or m.blizzard_query.exact) and name)
@@ -134,7 +134,7 @@ function private.get_filter_builder_query()
add(strlower(getglobal('ITEM_QUALITY'..quality..'_DESC')))
end
local post_filter_string = aux.filter.query_string({blizzard={}, post=m.post_filter})
local post_filter_string = aux.filter.query_string{blizzard={}, post=m.post_filter}
add(post_filter_string ~= '' and post_filter_string)
return query_string or ''
@@ -142,37 +142,9 @@ end
function private.set_form(components)
m.clear_form()
local class_index, subclass_index
for _, filter in components.blizzard do
if filter[1] == 'name' then
local name = filter[2]
if name and strsub(name, 1, 1) == '"' and strsub(name, -1, -1) == '"' then
name = strsub(name, 2, -2)
end
m.blizzard_query.name = aux.filter.unquote(filter[2])
elseif filter[1] == 'exact' then
m.blizzard_query.exact = true
elseif filter[1] == 'min_level' then
m.min_level_input:SetText(tonumber(filter[2]))
elseif filter[1] == 'max_level' then
m.max_level_input:SetText(tonumber(filter[2]))
elseif filter[1] == 'usable' then
m.blizzard_query.usable = true
elseif filter[1] == 'class' then
class_index = aux.info.item_class_index(filter[2])
m.blizzard_query.class = class_index
elseif filter[1] == 'subclass' then
subclass_index = aux.info.item_subclass_index(class_index, filter[2])
m.blizzard_query.subclass = subclass_index
elseif filter[1] == 'slot' then
m.blizzard_query.slot = ({GetAuctionInvTypes(class_index, subclass_index)})[aux.info.item_slot_index(class_index, subclass_index, filter[2])]
elseif filter[1] == 'quality' then
m.blizzard_query.quality = aux.info.item_quality_index(filter[2])
end
for key, filter in components.blizzard do
m.blizzard_query[key] = filter[2]
end
for _, component in components.post do
m.add_component(component)
end
@@ -199,7 +171,7 @@ function private.clear_form()
end
function private.import_query_string()
local components, error = aux.filter.parse_query_string(({strfind(m.search_box:GetText(), '^([^;]*)')})[3])
local components, error = aux.filter.parse_query_string(aux.util.select(3, strfind(m.search_box:GetText(), '^([^;]*)')))
if components then
m.set_form(components)
else
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'search_tab'
aux.module 'search_tab'
private.FILTER_SPACING = 28.5
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'search_tab'
aux.module 'search_tab'
aux_auto_buy_filter = ''
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'search_tab'
aux.module 'search_tab'
aux_favorite_searches = {}
aux_recent_searches = {}
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'completion'
aux.module 'completion'
function public:complete_filter()
if IsControlKeyDown() then -- TODO problem is ctrl-v, maybe find a better solution
+6 -5
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'util'
aux.module 'util'
function public.present(...)
local called
@@ -19,10 +19,11 @@ function public.unpack(array, ...)
end
function public.select(i, ...)
for _=1,i-1 do
tremove(arg, 1)
while i > 1 do
i = i - 1
tremove(arg, i)
end
return unpack(arg)
return tremove(arg, 1), unpack(arg)
end
function public.size(t)
@@ -219,7 +220,7 @@ function public.bag_type(bag)
if bag == 0 then
return 1
end
for _, link in {GetInventoryItemLink('player', ContainerIDToInventoryID(bag))} do
for link in aux.util.present(GetInventoryItemLink('player', ContainerIDToInventoryID(bag))) do
local item_id = aux.info.parse_hyperlink(link)
local item_info = aux.info.item(item_id)
return aux.info.item_subclass_index(3, item_info.subclass)
+108 -202
View File
@@ -1,9 +1,4 @@
local m, public, private = aux.module'filter'
private.OPERATOR_COLOR = ''
private.FILTER_COLOR = ''
private.PARAMETER_COLOR = ''
aux.module 'filter'
function private.default_filter(str)
return {
@@ -11,7 +6,7 @@ function private.default_filter(str)
validator = function()
return function(auction_record)
return aux.util.any(auction_record.tooltip, function(entry)
return strfind(strupper(entry.left_text or ''), strupper(str or ''), 1, true) or strfind(strupper(entry.right_text or ''), strupper(str or ''), 1, true)
return strfind(strlower(entry.left_text or ''), str, 1, true) or strfind(strlower(entry.right_text or ''), str, 1, true)
end)
end
end,
@@ -208,144 +203,92 @@ public.filters = {
}
function private.operator(str)
if str == 'not' then
return 'not', 1
end
local _, _, and_op, and_arity = strfind(str, '^(and)(%d*)$')
local _, _, or_op, or_arity = strfind(str, '^(or)(%d*)$')
local op = and_op or or_op
local arity = and_arity or or_arity
if op then
if arity == '' then
return op
elseif tonumber(arity) and tonumber(arity) >= 2 then
return op, tonumber(arity)
end
local operator = str == 'not' and {'operator', 'not', 1}
for _, name in {'and', 'or'} do
for arity in aux.util.present(aux.util.select(3, strfind(str, '^'..name..'(%d*)$'))) do
arity = tonumber(arity)
operator = not (arity and arity < 2) and {'operator', name, arity}
end
end
return operator or nil
end
function private.blizzard_filter_parser()
local class_index, subclass_index
local filters = {}
return function(str, first)
local filter
if strfind(str, '^%d+$') then
if tonumber(str) < 1 or tonumber(str) > 60 then
return nil, 'Erroneous level range modifier'
end
if not filters.min_level then
filter = {'min_level', str}
elseif not filters.max_level then
filter = {'max_level', str}
else
return nil, 'Erroneous level range modifier'
end
elseif aux.info.item_class_index(str) and not (filters.class and not filters.subclass and str == strlower(({ GetAuctionItemClasses() })[10])) then
class_index = aux.info.item_class_index(str)
if not filters.class then
filter = {'class', str}
else
return nil, 'Erroneous item class modifier'
end
elseif class_index and aux.info.item_subclass_index(class_index, str) then
subclass_index = aux.info.item_subclass_index(class_index, str)
if not filters.subclass then
filter = {'subclass', str}
else
return nil, 'Erroneous item subclass modifier'
end
elseif subclass_index and aux.info.item_slot_index(class_index, subclass_index, str) then
if not filters.slot then
filter = {'slot', str}
else
return nil, 'Erroneous item slot modifier'
end
elseif aux.info.item_quality_index(str) then
if not filters.quality then
filter = {'quality', str}
else
return nil, 'Erroneous quality modifier'
end
elseif str == 'usable' then
if not filters.usable then
filter = {'usable'}
else
return nil, 'Erroneous usable only modifier'
end
elseif str == 'exact' then
if filters.name and not filters.exact then
filter = {'exact'}
else
return nil, 'Erroneous exact only modifier'
end
elseif first then
if strlen(str) <= 63 then
filter = {'name', str }
else
return nil, 'The name must not be longer than 63 characters'
end
end
do
local mt = {
__call = function(self, str, i)
if not str then
self.max_level = self.max_level or self.min_level
return self
end
if self.exact then
return
end
for number in aux.util.present(tonumber(aux.util.select(3, strfind(str, '^(%d+)$')))) do
if number >= 1 and number <= 60 then
for _, filter in {'min_level', 'max_level'} do
if not self[filter] then
self[filter] = {str, number}
return true
end
end
end
end
for _, parser in {
{'class', aux.info.item_class_index},
{'subclass', aux._(aux.info.item_subclass_index, aux.index(self.class, 2) or 0, aux.arg1)},
{'slot', aux._(aux.info.item_slot_index, aux.index(self.class, 2) or 0, aux.index(self.subclass, 2) or 0, aux.arg1)},
{'quality', aux.info.item_quality_index},
} do
if not self[parser[1]] then
tinsert(parser, str)
for index, label in aux.util.present(parser[2](aux.util.select(3, unpack(parser)))) do
self[parser[1]] = {label, index}
return true
end
end
end
if not self[str] and (str == 'usable' or str == 'exact' and self.name and aux.util.size(self) == 1) then
self[str] = {str, 1}
elseif i == 1 and strlen(str) <= 63 then
self.name = {str, m.unquote(str)}
-- return nil, 'The name filter must not be longer than 63 characters'
else
return
end
return true
end,
}
if filter then
filters[filter[1]] = filter[2] or true
end
if filters.exact and
(
filters.min_level
or filters.max_level
or filters.class
or filters.subclass
or filters.slot
or filters.quality
or filters.usable
)
then
return false, 'Erroneous exact only modifier'
end
return filter
end
function private.blizzard_filter_parser()
return setmetatable({}, mt)
end
end
function private.parse_parameter(input_type, str)
if input_type == 'money' then
local money = aux.money.from_string(str)
if money and money > 0 then
return money
end
return money and money > 0 and money or nil
elseif input_type == 'number' then
local number = tonumber(str)
if number then
return number
end
return number and number > 0 and mod(number, 1) == 0 and number or nil
elseif input_type == 'string' then
if str ~= '' then
return str
end
return str ~= '' and str or nil
elseif type(input_type) == 'table' then
local choice = aux.util.key(str, input_type)
if choice then
return choice
end
return aux.util.key(str, input_type)
end
end
function public.parse_query_string(str)
local components = {blizzard = {}, post = {}}
local post_filter = {}
local blizzard_filter_parser = m.blizzard_filter_parser()
local parts = aux.util.map(aux.util.split(str, '/'), function(part) return strlower(aux.util.trim(part)) end)
local i = 1
while parts[i] do
local op, arity = m.operator(parts[i])
if op then
tinsert(components.post, {'operator', op, arity})
elseif m.filters[parts[i]] then
local input_type = m.filters[parts[i]].input_type
if aux.temp(m.operator(parts[i])) then
tinsert(post_filter, __.operator)
elseif __(m.filters[parts[i]]) then
local input_type = __.filter.input_type
if input_type ~= '' then
if not parts[i + 1] or not m.parse_parameter(input_type, parts[i + 1]) then
if parts[i] == 'item' then
@@ -356,27 +299,22 @@ function public.parse_query_string(str)
return nil, 'Invalid input for '..parts[i]..'. Expecting: '..input_type
end
end
tinsert(components.post, {'filter', parts[i], parts[i + 1]})
tinsert(post_filter, {'filter', parts[i], parts[i + 1]})
i = i + 1
else
tinsert(components.post, {'filter', parts[i]})
end
else
local component, error = blizzard_filter_parser(parts[i], i == 1)
if component then
tinsert(components.blizzard, component)
elseif error then
return nil, error
elseif parts[i] ~= '' then
tinsert(components.post, {'filter', 'tooltip', parts[i]})
else
return nil, 'Empty modifier'
tinsert(post_filter, {'filter', parts[i]})
end
elseif not blizzard_filter_parser(parts[i], i) then
if parts[i] ~= '' then
tinsert(post_filter, {'filter', 'tooltip', parts[i]})
else
return nil, 'Empty modifier'
end
end
i = i + 1
end
return components
return {blizzard=blizzard_filter_parser(), post=post_filter}
end
function public.query(query_string)
@@ -435,23 +373,9 @@ function public.queries(query_string)
end
function private.suggestions(components)
local blizzard_filters = {}
for _, filter in components.blizzard do
blizzard_filters[filter[1]] = filter[2] or true
end
local suggestions = {}
if blizzard_filters.name
and not blizzard_filters.min_level
and not blizzard_filters.max_level
and not blizzard_filters.class
and not blizzard_filters.subclass
and not blizzard_filters.slot
and not blizzard_filters.quality
and not blizzard_filters.usable
then
if components.blizzard.name and aux.util.size(components.blizzard) == 1 then
tinsert(suggestions, 'exact')
end
@@ -461,46 +385,44 @@ function private.suggestions(components)
tinsert(suggestions, 'tt')
for filter, _ in m.filters do
tinsert(suggestions, strlower(filter))
tinsert(suggestions, filter)
end
-- classes
if not blizzard_filters.class then
for _, class in { GetAuctionItemClasses() } do
if not components.blizzard.class then
for _, class in {GetAuctionItemClasses()} do
tinsert(suggestions, class)
end
end
-- subclasses
local class_index = blizzard_filters.class and aux.info.item_class_index(blizzard_filters.class)
if class_index and not blizzard_filters.subclass then
for _, subclass in { GetAuctionItemSubClasses(class_index) } do
if not components.blizzard.subclass then
for _, subclass in {GetAuctionItemSubClasses(aux.index(components.blizzard.class, 2) or 0)} do
tinsert(suggestions, subclass)
end
end
-- slots
local subclass_index = class_index and blizzard_filters.subclass and aux.info.item_subclass_index(class_index, blizzard_filters.subclass)
if subclass_index and not blizzard_filters.slot then
for _, invtype in { GetAuctionInvTypes(class_index, aux.info.item_subclass_index(class_index, blizzard_filters.subclass)) } do
if not components.blizzard.slot then
for _, invtype in {GetAuctionInvTypes(aux.index(components.blizzard.class, 2) or 0, aux.index(components.blizzard.subclass, 2) or 0)} do
tinsert(suggestions, getglobal(invtype))
end
end
-- usable
if not blizzard_filters.usable then
if not components.blizzard.usable then
tinsert(suggestions, 'usable')
end
-- rarities
if not blizzard_filters.quality then
if not components.blizzard.quality then
for i=0,4 do
tinsert(suggestions, getglobal('ITEM_QUALITY'..i..'_DESC'))
end
end
-- item names
if getn(components.blizzard) + getn(components.post) == 1 and blizzard_filters.name == '' then
if aux.util.size(components.blizzard) + getn(components.post) == 1 and components.blizzard.name == '' then
for _, name in aux_auctionable_items do
tinsert(suggestions, name..'/exact')
end
@@ -536,18 +458,16 @@ end
function private.prettified_query_string(components)
local prettified = m.query_builder()
local blizzard_filters = {}
for _, filter in components.blizzard do
blizzard_filters[filter[1]] = filter[2] or true
if filter[1] == 'exact' then
prettified.prepend(aux.info.display_name(aux.cache.item_id(m.unquote(blizzard_filters.name))) or aux.gui.color.blizzard('['..m.unquote(blizzard_filters.name)..']'))
elseif filter[1] ~= 'name' then
prettified.append(aux.gui.color.blizzard(filter[2] or filter[1]))
for key, filter in components.blizzard do
if key == 'exact' then
prettified.prepend(aux.info.display_name(aux.cache.item_id(components.blizzard.name[2])) or aux.gui.color.blizzard('['..components.blizzard.name[2]..']'))
elseif key ~= 'name' then
prettified.append(aux.gui.color.blizzard(filter[1]))
end
end
if blizzard_filters.name and not blizzard_filters.exact and blizzard_filters.name ~= '' then
prettified.prepend(aux.gui.color.blizzard(m.unquote(blizzard_filters.name)))
if components.blizzard.name and not components.blizzard.exact and components.blizzard.name[2] ~= '' then
prettified.prepend(aux.gui.color.blizzard(components.blizzard.name[2]))
end
for _, component in components.post do
@@ -582,47 +502,35 @@ function public.quote(name)
end
function public.unquote(name)
if name and strsub(name, 1, 1) == '<' and strsub(name, -1, -1) == '>' then
name = strsub(name, 2, -2)
end
return name
return aux.util.select(3, strfind(name, '^<(.*)>$')) or name
end
function private.blizzard_query(components)
local filters = {}
for _, filter in components.blizzard do
filters[filter[1]] = filter[2] or true
end
local filters = components.blizzard
local query = { name = filters.name and m.unquote(filters.name) }
local query = {name=filters.name and filters.name[2]}
local item_info, class_index, subclass_index, slot_index
if filters.exact then
local item_id = aux.cache.item_id(filters.name)
item_info = aux.info.item(item_id)
class_index = item_info and aux.info.item_class_index(item_info.class)
subclass_index = class_index and item_info.subclass and aux.info.item_subclass_index(class_index, item_info.subclass)
slot_index = subclass_index and item_info.slot and aux.info.item_slot_index(class_index, subclass_index, item_info.slot)
if filters.exact and aux.temp(aux.cache.item_id(filters.name[2])) and __(aux.info.item(__.item_id)) then
item_info = __.item_info
class_index = aux.info.item_class_index(item_info.class)
subclass_index = aux.info.item_subclass_index(class_index or 0, item_info.subclass)
slot_index = aux.info.item_slot_index(class_index or 0, subclass_index or 0, item_info.slot)
end
if item_info then
query.min_level = item_info.level
query.max_level = item_info.level
query.usable = item_info.usable
query.class = class_index
query.subclass = subclass_index
query.slot = item_info.class
query.usable = item_info.usable
query.slot = slot_index
query.quality = item_info.quality
else
query.min_level = tonumber(filters.min_level)
query.max_level = tonumber(filters.max_level)
query.class = filters.class and filters.class and aux.info.item_class_index(filters.class)
query.subclass = query.class and filters.subclass and aux.info.item_subclass_index(query.class, filters.subclass)
query.slot = query.subclass and filters.slot and aux.info.item_slot_index(query.class, query.subclass, filters.slot)
query.usable = filters.usable and 1
query.quality = filters.quality and aux.info.item_quality_index(filters.quality)
for _, key in {'min_level', 'max_level', 'class', 'subclass', 'slot', 'usable', 'quality'} do
query[key] = aux.index(filters[key], 2)
end
end
return query
end
@@ -636,10 +544,8 @@ function private.validator(components)
end
return function(record)
for _, filter in components.blizzard do
if filter[1] == 'exact' and strlower(aux.info.item(record.item_id).name) ~= components.blizzard[1][2] then
return false
end
if components.blizzard.exact and strlower(aux.info.item(record.item_id).name) ~= components.blizzard.name[2] then
return false
end
local stack = {}
for i=getn(components.post),1,-1 do
+8 -8
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'info'
aux.module 'info'
CreateFrame('GameTooltip', 'AuxTooltip', nil, 'GameTooltipTemplate')
AuxTooltip:SetScript('OnTooltipAddMoney', function()
@@ -377,25 +377,25 @@ function public.item(item_id, suffix_id)
end
function public.item_class_index(item_class)
for i, class in { GetAuctionItemClasses() } do
for i, class in {GetAuctionItemClasses()} do
if strupper(class) == strupper(item_class) then
return i
return i, class
end
end
end
function public.item_subclass_index(class_index, item_subclass)
for i, subclass in { GetAuctionItemSubClasses(class_index) } do
for i, subclass in {GetAuctionItemSubClasses(class_index)} do
if strupper(subclass) == strupper(item_subclass) then
return i
return i, subclass
end
end
end
function public.item_slot_index(class_index, subclass_index, slot_name)
for i, slot in { GetAuctionInvTypes(class_index, subclass_index) } do
for i, slot in {GetAuctionInvTypes(class_index, subclass_index)} do
if strupper(getglobal(slot)) == strupper(slot_name) then
return i
return i, getglobal(slot)
end
end
end
@@ -404,7 +404,7 @@ function public.item_quality_index(item_quality)
for i=0,4 do
local quality = getglobal('ITEM_QUALITY'..i..'_DESC')
if strupper(item_quality) == strupper(quality) then
return i
return i, quality
end
end
end
+16 -19
View File
@@ -1,23 +1,21 @@
local m, public, private = aux.module'money'
aux.module 'money'
private.GOLD_TEXT = '|cffffd70ag|r'
private.SILVER_TEXT = '|cffc7c7cfs|r'
private.COPPER_TEXT = '|cffeda55fc|r'
do
local COPPER_PER_SILVER = 100
local COPPER_PER_GOLD = 10000
private.COPPER_PER_SILVER = 100
private.COPPER_PER_GOLD = 10000
function public.gsc(money)
local gold = floor(money / COPPER_PER_GOLD)
local silver = floor(mod(money, COPPER_PER_GOLD) / COPPER_PER_SILVER)
local copper = mod(money, COPPER_PER_SILVER)
return gold, silver, copper
end
function public.gsc(money)
local gold = floor(money / m.COPPER_PER_GOLD)
local silver = floor(mod(money, m.COPPER_PER_GOLD) / m.COPPER_PER_SILVER)
local copper = mod(money, m.COPPER_PER_SILVER)
return gold, silver, copper
end
function public.copper(gold, silver, copper)
return gold * COPPER_PER_GOLD + silver * COPPER_PER_SILVER + copper
end
function public.copper(gold, silver, copper)
return gold * m.COPPER_PER_GOLD + silver * m.COPPER_PER_SILVER + copper
end
function public.format(money, exact, color)
@@ -115,18 +113,17 @@ function public.to_string(money, pad, trim, decimal_points, color, no_color)
end
function public.from_string(value)
local number = tonumber(value)
if number and number >= 0 then
return number * COPPER_PER_GOLD
if aux.temp(tonumber(value)) and __.number >= 0 then
return __.number * m.COPPER_PER_GOLD
end
-- remove any colors
value = gsub(gsub(strlower(value), '|c%x%x%x%x%x%x%x%x', ''), FONT_COLOR_CODE_CLOSE, '')
-- extract gold/silver/copper values
local gold = tonumber(({strfind(value, '(%d*%.?%d+)g')})[3])
local silver = tonumber(({strfind(value, '(%d*%.?%d+)s')})[3])
local copper = tonumber(({strfind(value, '(%d*%.?%d+)c')})[3])
local gold = tonumber(aux.util.select(3, strfind(value, '(%d*%.?%d+)g')))
local silver = tonumber(aux.util.select(3, strfind(value, '(%d*%.?%d+)s')))
local copper = tonumber(aux.util.select(3, strfind(value, '(%d*%.?%d+)c')))
if not gold and not silver and not copper then return end
-- test that there are no extra characters (other than spaces)
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'persistence'
aux.module 'persistence'
aux_datasets = {}
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'scan_util'
aux.module 'scan_util'
function public.find(auction_record, status_bar, on_abort, on_failure, on_success)
+1 -1
View File
@@ -1,4 +1,4 @@
local m, public, private = aux.module'sort'
aux.module 'sort'
public.LT = {}
public.EQ = {}