фикс журнала
This commit is contained in:
+110
-5
@@ -49,10 +49,19 @@ local rolesByFlag = {
|
||||
}
|
||||
|
||||
local EJ_Tabs = {};
|
||||
local EJ_BROKEN_BAKED_MODEL = {};
|
||||
local EJ_MODEL_CAMERA = {
|
||||
-- Avatar of Hakkar is unusually small and anchored too low.
|
||||
[8053] = { scale = 2.0, x = 0, y = 0.16, z = 0 },
|
||||
-- Gahz'rilla's native UI camera is an extreme facial close-up.
|
||||
[7271] = { scale = 0.42, x = 0, y = 0.04, z = 0 },
|
||||
};
|
||||
local EJ_MODEL_USER_SCALE = {};
|
||||
|
||||
EJ_Tabs[1] = { frame = "overviewScroll", button = "overviewTab" };
|
||||
EJ_Tabs[2] = { frame = "lootScroll", button = "lootTab" };
|
||||
EJ_Tabs[3] = { frame = "detailsScroll", button = "bossTab" };
|
||||
EJ_Tabs[4] = { frame = "model", button = "modelTab" };
|
||||
|
||||
|
||||
local EJ_section_openTable = {};
|
||||
@@ -1124,6 +1133,7 @@ function EncounterJournal_DisplayEncounter(encounterID, noButton, scrollToEncoun
|
||||
|
||||
-- Setup Creatures
|
||||
local id, name, description, displayInfo, iconImage, creatureID;
|
||||
local hasCreatureModel = false;
|
||||
for i = 1, MAX_CREATURES_PER_ENCOUNTER do
|
||||
id, name, description, displayInfo, iconImage, creatureID = EJ_GetCreatureInfo(i);
|
||||
if id then
|
||||
@@ -1134,12 +1144,17 @@ function EncounterJournal_DisplayEncounter(encounterID, noButton, scrollToEncoun
|
||||
button.id = id;
|
||||
button.description = description;
|
||||
button.displayInfo = displayInfo;
|
||||
button.creatureID = creatureID or displayInfo;
|
||||
button.iconImage = iconImage;
|
||||
button.creatureID = creatureID;
|
||||
if creatureID and creatureID > 0 then
|
||||
hasCreatureModel = true;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--enable abilities tab
|
||||
EncounterJournal_SetTabEnabled(EncounterJournal.encounter.info.bossTab, true);
|
||||
EncounterJournal_SetTabEnabled(EncounterJournal.encounter.info.modelTab, hasCreatureModel);
|
||||
|
||||
if (overviewFound) then
|
||||
EncounterJournal_ToggleHeaders(self.overviewFrame);
|
||||
@@ -1173,12 +1188,30 @@ function EncounterJournal_DisplayCreature(self)
|
||||
|
||||
local model = EncounterJournal.encounter.info.model;
|
||||
local displayInfo = self.displayInfo;
|
||||
if model.ResetFull then
|
||||
model:ResetFull();
|
||||
elseif model.ClearModel then
|
||||
if model.ClearModel then
|
||||
model:ClearModel();
|
||||
end
|
||||
EncounterJournal.creatureDisplayID = displayInfo;
|
||||
model.displayInfo = displayInfo;
|
||||
local useStaticPortrait = EJ_BROKEN_BAKED_MODEL[displayInfo];
|
||||
if model.fallbackPortrait then
|
||||
if useStaticPortrait then
|
||||
model.fallbackPortrait:SetTexture(self.iconImage or
|
||||
(MoonWellEncounterPortraitByDisplayInfo and MoonWellEncounterPortraitByDisplayInfo[displayInfo]) or
|
||||
QUESTION_MARK_ICON);
|
||||
model.fallbackPortrait:Show();
|
||||
else
|
||||
model.fallbackPortrait:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
-- WarcraftXL accepts displayInfo as an optional second argument and can
|
||||
-- therefore render entries which are not present in the creature cache.
|
||||
-- Stock 3.3.5 safely ignores the extra argument and keeps its old fallback.
|
||||
if not useStaticPortrait and self.creatureID and self.creatureID > 0 and model.SetCreature then
|
||||
model:SetCreature(self.creatureID, displayInfo);
|
||||
EncounterJournal_Model_ApplyCamera(model);
|
||||
end
|
||||
|
||||
model.imageTitle:SetText(self.name)
|
||||
|
||||
@@ -1197,6 +1230,74 @@ function EncounterJournal_ShowCreatures()
|
||||
end
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnLoad(self)
|
||||
self.rotation = 0;
|
||||
self:SetRotation(self.rotation);
|
||||
self:EnableMouse(true);
|
||||
self:EnableMouseWheel(true);
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_ApplyCamera(self)
|
||||
if not self or not self.displayInfo or EJ_BROKEN_BAKED_MODEL[self.displayInfo] then
|
||||
return;
|
||||
end
|
||||
|
||||
local camera = EJ_MODEL_CAMERA[self.displayInfo];
|
||||
local scale = EJ_MODEL_USER_SCALE[self.displayInfo] or (camera and camera.scale) or 1;
|
||||
if self.SetModelScale then
|
||||
self:SetModelScale(scale);
|
||||
end
|
||||
if self.SetPosition then
|
||||
self:SetPosition(camera and camera.x or 0, camera and camera.y or 0, camera and camera.z or 0);
|
||||
end
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnMouseWheel(self, delta)
|
||||
if not self.displayInfo or EJ_BROKEN_BAKED_MODEL[self.displayInfo] then
|
||||
return;
|
||||
end
|
||||
|
||||
local camera = EJ_MODEL_CAMERA[self.displayInfo];
|
||||
local scale = EJ_MODEL_USER_SCALE[self.displayInfo] or (camera and camera.scale) or 1;
|
||||
if delta > 0 then
|
||||
scale = scale * 1.12;
|
||||
else
|
||||
scale = scale / 1.12;
|
||||
end
|
||||
scale = math.max(0.15, math.min(4, scale));
|
||||
EJ_MODEL_USER_SCALE[self.displayInfo] = scale;
|
||||
EncounterJournal_Model_ApplyCamera(self);
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnUpdateModel(self)
|
||||
EncounterJournal_Model_ApplyCamera(self);
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnMouseDown(self, button)
|
||||
if button == "LeftButton" then
|
||||
self.dragCursorX = GetCursorPosition();
|
||||
elseif button == "RightButton" and self.displayInfo then
|
||||
EJ_MODEL_USER_SCALE[self.displayInfo] = nil;
|
||||
EncounterJournal_Model_ApplyCamera(self);
|
||||
end
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnMouseUp(self)
|
||||
self.dragCursorX = nil;
|
||||
end
|
||||
|
||||
function EncounterJournal_Model_OnUpdate(self)
|
||||
if not self.dragCursorX then
|
||||
return;
|
||||
end
|
||||
|
||||
local cursorX = GetCursorPosition();
|
||||
local delta = cursorX - self.dragCursorX;
|
||||
self.dragCursorX = cursorX;
|
||||
self.rotation = (self.rotation or 0) + delta * 0.01;
|
||||
self:SetRotation(self.rotation);
|
||||
end
|
||||
|
||||
function EncounterJournal_HideCreatures(clearDisplayInfo)
|
||||
for index, creatureButton in ipairs(EncounterJournal.encounter.info.creatureButtons) do
|
||||
creatureButton:Hide();
|
||||
@@ -2066,6 +2167,7 @@ function EncounterJournal_ClearDetails()
|
||||
|
||||
local clearDisplayInfo = true;
|
||||
EncounterJournal_HideCreatures(clearDisplayInfo);
|
||||
EncounterJournal_SetTabEnabled(EncounterJournal.encounter.info.modelTab, false);
|
||||
|
||||
local bossIndex = 1
|
||||
local bossButton = _G["EncounterJournalBossButton" .. bossIndex];
|
||||
@@ -2093,12 +2195,15 @@ function EncounterJournal_SetTab(tabType)
|
||||
|
||||
local info = EncounterJournal.encounter.info;
|
||||
info.tab = tabType;
|
||||
if info.model then
|
||||
if info.model and tabType ~= 4 then
|
||||
info.model:Hide();
|
||||
end
|
||||
for key, data in pairs(EJ_Tabs) do
|
||||
if key == tabType then
|
||||
info[data.frame]:Show();
|
||||
if key == 4 then
|
||||
EncounterJournal_ShowCreatures();
|
||||
end
|
||||
info[data.button].selected:Show();
|
||||
info[data.button].unselected:Hide();
|
||||
info[data.button]:LockHighlight();
|
||||
|
||||
+20
-13
@@ -467,7 +467,7 @@
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentText" parentKey="Text" inherits="PKBT_Font_14" text="UNAVAILABLE">
|
||||
<FontString name="$parentText" parentKey="Text" inherits="GameFontNormal" text="UNAVAILABLE">
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="0"/>
|
||||
</Anchors>
|
||||
@@ -2510,7 +2510,7 @@
|
||||
<OnClick function="EncounterTabTemplate_OnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentModelTab" inherits="EncounterTabTemplate" parentKey="modelTab" id="4" hidden="true">
|
||||
<Button name="$parentModelTab" inherits="EncounterTabTemplate" parentKey="modelTab" id="4">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="$parentBossTab" relativePoint="BOTTOM" x="0" y="2"/>
|
||||
</Anchors>
|
||||
@@ -2532,8 +2532,8 @@
|
||||
<OnLoad>
|
||||
self.tooltip = MODEL;
|
||||
self:Disable();
|
||||
self:Hide();
|
||||
</OnLoad>
|
||||
<OnClick function="EncounterTabTemplate_OnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<ScrollFrame name="$parentBossesScrollFrame" parentKey="bossesScroll" inherits="UIPanelScrollFrameCodeTemplate">
|
||||
@@ -2844,7 +2844,7 @@
|
||||
</OnShow>
|
||||
</Scripts>
|
||||
</ScrollFrame>
|
||||
<DressUpModel name="$parentModelFrame" parentKey="model" inherits="PKBT_ModelTemplate,ModelTemplate">
|
||||
<DressUpModel name="$parentModelFrame" parentKey="model" hidden="true" enableMouse="true">
|
||||
<Size x="390" y="423"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT" x="-3" y="1"/>
|
||||
@@ -2859,6 +2859,14 @@
|
||||
<TexCoords left="0.76953125" right="0" top="0" bottom="0.830078125"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentFallbackPortrait" parentKey="fallbackPortrait" hidden="true">
|
||||
<Size x="256" y="256"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="8"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentShadow" file="Interface\EncounterJournal\UI-EJ-BossModelPaperFrame">
|
||||
<Size x="393" y="424"/>
|
||||
@@ -2892,20 +2900,20 @@
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, PKBT_ModelMixin)
|
||||
SharedXML_Model_OnLoad(self);
|
||||
EncounterJournal_Model_OnLoad(self);
|
||||
self.imageTitle = self.overlayFrame.imageTitle;
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
self:OnShow()
|
||||
EncounterJournal_ShowCreatures();
|
||||
EncounterJournal.encounter.info.TitleFrame.encounterTitle:Hide();
|
||||
EncounterJournal.encounter.info.rightShadow:Hide();
|
||||
EncounterJournal.encounter.info.difficulty:Hide();
|
||||
</OnShow>
|
||||
<OnEvent>
|
||||
self:OnEvent(event, ...)
|
||||
SharedXML_Model_OnEvent(event, ...)
|
||||
</OnEvent>
|
||||
<OnMouseDown function="EncounterJournal_Model_OnMouseDown"/>
|
||||
<OnMouseUp function="EncounterJournal_Model_OnMouseUp"/>
|
||||
<OnMouseWheel function="EncounterJournal_Model_OnMouseWheel"/>
|
||||
<OnUpdateModel function="EncounterJournal_Model_OnUpdateModel"/>
|
||||
<OnUpdate function="EncounterJournal_Model_OnUpdate"/>
|
||||
</Scripts>
|
||||
</DressUpModel>
|
||||
<Button name="$parentCreatureButton1" inherits="EncounterCreatureButtonTemplate">
|
||||
@@ -2919,8 +2927,7 @@
|
||||
SetParentFrameLevel(self.overviewTab, 10)
|
||||
SetParentFrameLevel(self.lootTab, 10)
|
||||
SetParentFrameLevel(self.bossTab, 10)
|
||||
self.modelTab:Hide()
|
||||
self.model:Hide()
|
||||
SetParentFrameLevel(self.modelTab, 10)
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
-544
@@ -1,544 +0,0 @@
|
||||
UIPanelWindows["ItemBrowser"] = { area = "left", pushable = 0, whileDead = 1, width = 830, xOffset = "15", yOffset = "-10"}
|
||||
|
||||
local type = type
|
||||
local mathmax = math.max
|
||||
local strfind, strlower, strtrim = string.find, string.lower, string.trim
|
||||
local tinsert, twipe = table.insert, table.wipe
|
||||
local debugprofilestop = debugprofilestop
|
||||
|
||||
local COLUMNS = {
|
||||
{
|
||||
name = "Name",
|
||||
dataProviderKey = "name",
|
||||
template = "ItemBrowserListCellNameIconTemplate",
|
||||
},
|
||||
{
|
||||
name = "ItemLevel",
|
||||
dataProviderKey = "itemLevel",
|
||||
width = 70,
|
||||
template = "ItemBrowserListCellItemLevelTemplate",
|
||||
},
|
||||
{
|
||||
name = "ID",
|
||||
dataProviderKey = "itemID",
|
||||
width = 90,
|
||||
template = "ItemBrowserListCellItemIDTemplate",
|
||||
},
|
||||
}
|
||||
|
||||
ItemBrowserMixin = {}
|
||||
|
||||
function ItemBrowserMixin:OnLoad()
|
||||
self.TitleText:SetText(ITEM_BROWSER)
|
||||
SetPortraitToTexture(self.portrait, [[Interface\Icons\Achievement_General_ClassicBattles_64]])
|
||||
|
||||
self.inset.Bgs:SetAtlas("UI-EJ-BattleforAzeroth")
|
||||
|
||||
do -- tabs
|
||||
self:RegisterCustomEvent("SERVICE_DATA_UPDATE")
|
||||
self:RegisterCustomEvent("CUSTOM_CHALLENGE_DEACTIVATED")
|
||||
|
||||
self.tab1:SetFrameLevel(1)
|
||||
self.tab2:SetFrameLevel(1)
|
||||
self.tab3:SetFrameLevel(1)
|
||||
self.tab4:SetFrameLevel(1)
|
||||
|
||||
self.maxTabWidth = (self:GetWidth() - 19) / 4
|
||||
|
||||
PanelTemplates_SetNumTabs(self, 4)
|
||||
end
|
||||
|
||||
do -- coroutine
|
||||
self.COROUTINE_HANDLER = CreateFrame("Frame")
|
||||
self.COROUTINE_HANDLER:Hide()
|
||||
|
||||
self.COROUTINE_HANDLER.FRAMETIME_TARGET = 1 / 55
|
||||
self.COROUTINE_HANDLER.FRAMETIME_AVAILABLE = 8
|
||||
self.COROUTINE_HANDLER.FRAMETIME_RESERVE = 4
|
||||
self.COROUTINE_HANDLER.DEBUG = false
|
||||
|
||||
self.COROUTINE_HANDLER:SetScript("OnUpdate", function(this, elapsed)
|
||||
local frametimeStep = this.FRAMETIME_TARGET - elapsed
|
||||
|
||||
if frametimeStep ~= 0 then
|
||||
frametimeStep = frametimeStep * 1000
|
||||
this.FRAMETIME_AVAILABLE = mathmax(5, this.FRAMETIME_AVAILABLE + frametimeStep)
|
||||
end
|
||||
|
||||
if this.COROUTINE then
|
||||
this.COROUTINE_TIMESTAMP = debugprofilestop()
|
||||
local status, result, progress = coroutine.resume(this.COROUTINE)
|
||||
if not status then
|
||||
this.COROUTINE = nil
|
||||
this:Hide()
|
||||
self.PROGRESS = 1
|
||||
error(result, 2)
|
||||
elseif not result then
|
||||
if this.DEBUG then print("ITEM_BROWSER_COROUTINE", progress) end
|
||||
self.PROGRESS = progress
|
||||
self:OnSearchResultUpdate()
|
||||
else
|
||||
if this.DEBUG then print("ITEM_BROWSER_COROUTINE", 1) end
|
||||
this.COROUTINE = nil
|
||||
this:Hide()
|
||||
self.PROGRESS = 1
|
||||
self:OnSearchResultUpdate()
|
||||
end
|
||||
else
|
||||
this:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self.BUTTON_OFFSET_Y = 0
|
||||
self.PROGRESS = 1
|
||||
|
||||
self.results = {}
|
||||
|
||||
self.Scroll.ScrollBar:SetBackgroundShown(false)
|
||||
self.Scroll.update = function(scrollFrame)
|
||||
self:UpdateResultList()
|
||||
end
|
||||
self.Scroll.ScrollBar.doNotHide = true
|
||||
self.Scroll.scrollBar = self.Scroll.ScrollBar
|
||||
HybridScrollFrame_CreateButtons(self.Scroll, "ItemBrowserListRowButtonTemplate", 0, 0, nil, nil, nil, -self.BUTTON_OFFSET_Y)
|
||||
|
||||
self.SearchBox:ToggleOnCharFilter(true, 0.3)
|
||||
|
||||
self.tableBuilder = CreateTableBuilder(HybridScrollFrame_GetButtons(self.Scroll))
|
||||
self.tableBuilder:SetHeaderContainer(self.HeaderHolder)
|
||||
self:ConstructTable()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:OnShow()
|
||||
SetParentFrameLevel(self.inset)
|
||||
PanelTemplates_SetTab(self, 4)
|
||||
|
||||
self.dirty = true
|
||||
self.Scroll.ScrollBar:SetValue(0)
|
||||
self:UpdateResultList()
|
||||
|
||||
self.SearchBox:SetFocus()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:OnEvent(event, ...)
|
||||
if event == "SERVICE_DATA_UPDATE"
|
||||
or (event == "CUSTOM_CHALLENGE_DEACTIVATED" and select(2, ...) ~= Enum.HardcoreDeathReason.FAILED_DEATH)
|
||||
then
|
||||
if not C_Service.IsRenegadeRealm() then
|
||||
PanelTemplates_HideTab(self, 2)
|
||||
self.tab3:SetPoint("LEFT", self.tab1, "RIGHT", -16, 0);
|
||||
end
|
||||
if not C_Service.IsHardcoreEnabledOnRealm() then
|
||||
PanelTemplates_HideTab(self, 3)
|
||||
end
|
||||
if not C_Service.IsGMAccount() and not IsInterfaceDevClient() then
|
||||
PanelTemplates_HideTab(self, 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:GetRowProvider()
|
||||
return function(itemIndex)
|
||||
if itemIndex > #self.results then
|
||||
return nil
|
||||
end
|
||||
|
||||
local itemID = self.results[itemIndex]
|
||||
local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, vendorPrice = C_Item.GetItemInfo(itemID, false, nil, true, true)
|
||||
|
||||
return {
|
||||
itemID = itemID,
|
||||
name = itemName,
|
||||
itemLink = itemLink,
|
||||
itemLevel = itemLevel,
|
||||
itemType = itemType,
|
||||
itemSubType = itemSubType,
|
||||
icon = itemTexture,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:ConstructTable()
|
||||
local textPadding = 1
|
||||
local cellPadding = 10
|
||||
|
||||
self.tableBuilder:Reset()
|
||||
self.tableBuilder:SetDataProvider(self:GetRowProvider())
|
||||
self.tableBuilder:SetTableMargins(5)
|
||||
self.tableBuilder:SetTableWidth(self.Scroll:GetWidth() or select(3, self.Scroll:GetRect()))
|
||||
|
||||
for index, columnInfo in ipairs(COLUMNS) do
|
||||
local column = self.tableBuilder:AddColumn()
|
||||
column:ConstructHeader("Button", "ItemBrowserListHeaderButtonTemplate", columnInfo.name)
|
||||
column:ConstrainToHeader(textPadding)
|
||||
column:ConstructCells("Frame", columnInfo.template)
|
||||
|
||||
if columnInfo.width then
|
||||
column:SetFixedConstraints(columnInfo.width, cellPadding)
|
||||
else
|
||||
column:SetFillConstraints(1, cellPadding)
|
||||
end
|
||||
end
|
||||
|
||||
self.tableBuilder:Arrange()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:GetNumItems()
|
||||
if not self.NUM_ITEMS then
|
||||
self.NUM_ITEMS = tCount(ItemsCache)
|
||||
end
|
||||
return self.NUM_ITEMS
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:SearchItem(item)
|
||||
item = strtrim(item)
|
||||
if item == "" then
|
||||
self:ClearResults()
|
||||
return
|
||||
end
|
||||
|
||||
local itemID = C_Item.GetItemIDFromString(item)
|
||||
local searchField, searchValue, useStringFind
|
||||
|
||||
if itemID then
|
||||
searchField = Enum.ItemCacheField.ITEM_ID
|
||||
searchValue = itemID
|
||||
elseif item ~= "" then
|
||||
searchField = GetLocale() == "ruRU" and Enum.ItemCacheField.NAME_RURU or Enum.ItemCacheField.NAME_ENGB
|
||||
searchValue = strlower(item)
|
||||
useStringFind = true
|
||||
end
|
||||
|
||||
if not searchField then
|
||||
self:ClearResults()
|
||||
return
|
||||
end
|
||||
|
||||
self:StartSearch(searchField, searchValue, useStringFind)
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:StartSearch(searchField, searchValue, useStringFind)
|
||||
if self.SEARCH_FIELD == searchField and self.SEARCH_VALUE == searchValue then
|
||||
return
|
||||
end
|
||||
|
||||
if self.COROUTINE then
|
||||
coroutine.close(self.COROUTINE)
|
||||
self.COROUTINE = nil
|
||||
self:ClearResults()
|
||||
end
|
||||
|
||||
self.SEARCH_FIELD = searchField
|
||||
self.SEARCH_VALUE = searchValue
|
||||
self.USE_STRING_FIND = useStringFind
|
||||
|
||||
local framerate = GetFramerate()
|
||||
self.COROUTINE_HANDLER.FRAMETIME_TARGET = framerate > 63 and (1 / 60) or (1 / 55)
|
||||
self.COROUTINE_HANDLER.FRAMETIME_BUDGET = 1000 / framerate - self.COROUTINE_HANDLER.FRAMETIME_RESERVE
|
||||
|
||||
self.COROUTINE_HANDLER.COROUTINE = coroutine.create(self.SearchProcess)
|
||||
self.COROUTINE_HANDLER.COROUTINE_TIMESTAMP = debugprofilestop()
|
||||
|
||||
local status, result, progress = coroutine.resume(self.COROUTINE_HANDLER.COROUTINE, self)
|
||||
if not status then
|
||||
self.COROUTINE_HANDLER.COROUTINE = nil
|
||||
self.COROUTINE_HANDLER:Hide()
|
||||
self.PROGRESS = 1
|
||||
self:ClearResults()
|
||||
geterrorhandler()(result)
|
||||
elseif coroutine.status(self.COROUTINE_HANDLER.COROUTINE) == "dead" then
|
||||
self.COROUTINE_HANDLER.COROUTINE = nil
|
||||
self.PROGRESS = 1
|
||||
else
|
||||
if self.COROUTINE_HANDLER.DEBUG then print("ITEM_BROWSER_COROUTINE", progress) end
|
||||
self.PROGRESS = progress
|
||||
self.COROUTINE_HANDLER:Show()
|
||||
end
|
||||
|
||||
self:OnSearchResultUpdate()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:SearchProcess()
|
||||
twipe(self.results)
|
||||
|
||||
if not ItemsCache then
|
||||
return true, 1
|
||||
end
|
||||
|
||||
local processedEntries = 0
|
||||
local fieldValue
|
||||
|
||||
for itemID, itemInfo in pairs(ItemsCache) do
|
||||
processedEntries = processedEntries + 1
|
||||
|
||||
fieldValue = itemInfo[self.SEARCH_FIELD]
|
||||
|
||||
if type(fieldValue) == "string" then
|
||||
fieldValue = strlower(fieldValue)
|
||||
end
|
||||
|
||||
if fieldValue == self.SEARCH_VALUE
|
||||
or (self.USE_STRING_FIND and strfind(fieldValue, self.SEARCH_VALUE, 1, true))
|
||||
then
|
||||
tinsert(self.results, itemInfo[Enum.ItemCacheField.ITEM_ID])
|
||||
end
|
||||
|
||||
if (debugprofilestop() - self.COROUTINE_HANDLER.COROUTINE_TIMESTAMP) > self.COROUTINE_HANDLER.FRAMETIME_BUDGET then
|
||||
coroutine.yield(false, processedEntries / self:GetNumItems())
|
||||
end
|
||||
end
|
||||
|
||||
return true, 1
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:OnSearchResultUpdate()
|
||||
self.dirty = true
|
||||
self:UpdateSearchProgress()
|
||||
self:UpdateResultList()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:UpdateSearchProgress()
|
||||
local progress = Clamp(self.PROGRESS or 1, 0, 1)
|
||||
self.SearchProgressBar:SetValue(progress)
|
||||
self.SearchProgressBar:SetAlpha(progress < 1 and 1 or 0)
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:ClearResults()
|
||||
twipe(self.results)
|
||||
|
||||
self.SEARCH_FIELD = nil
|
||||
self.SEARCH_VALUE = nil
|
||||
self.USE_STRING_FIND = nil
|
||||
|
||||
self.PROGRESS = 1
|
||||
self.dirty = true
|
||||
|
||||
self:UpdateSearchProgress()
|
||||
self:UpdateResultList()
|
||||
end
|
||||
|
||||
function ItemBrowserMixin:UpdateResultList()
|
||||
local scrollFrame = self.Scroll
|
||||
local offset = HybridScrollFrame_GetOffset(scrollFrame)
|
||||
local numResults = self.results and #self.results or 0
|
||||
|
||||
if self.numItems ~= numResults then
|
||||
self.numItems = numResults
|
||||
self.dirty = true
|
||||
end
|
||||
|
||||
local populateCount = math.min(#scrollFrame.buttons, numResults)
|
||||
self.tableBuilder:Populate(offset, populateCount)
|
||||
|
||||
local mouseFocus = GetMouseFocus()
|
||||
for index, button in ipairs(scrollFrame.buttons) do
|
||||
button:SetOwner(self)
|
||||
button:SetShown(index <= numResults)
|
||||
if button == mouseFocus then
|
||||
button:OnEnter()
|
||||
end
|
||||
end
|
||||
|
||||
if self.dirty then
|
||||
local buttonHeight = scrollFrame.buttons[1] and scrollFrame.buttons[1]:GetHeight() or 0
|
||||
local scrollHeight = buttonHeight * numResults + self.BUTTON_OFFSET_Y * (numResults - 1) + self.BUTTON_OFFSET_Y / 3
|
||||
HybridScrollFrame_Update(scrollFrame, scrollHeight, scrollFrame:GetHeight())
|
||||
self.dirty = nil
|
||||
end
|
||||
end
|
||||
|
||||
ItemBrowserSearchBoxMixin = CreateFromMixins(PKBT_EditBoxMixin)
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnLoad()
|
||||
PKBT_EditBoxMixin.OnLoad(self)
|
||||
|
||||
local l, r, t, b = self:GetTextInsets()
|
||||
self:SetTextInsets(l + 10, r + 10, t - 1, b)
|
||||
|
||||
self:SetInstructions(SEARCH)
|
||||
self.Instructions:ClearAllPoints()
|
||||
self.Instructions:SetPoint("LEFT", 19, -2)
|
||||
|
||||
self.searchIcon:SetVertexColor(0.6, 0.6, 0.6)
|
||||
|
||||
self:SetCustomCharFilter(function(text)
|
||||
text = string.gsub(text, "%s%s+", " ")
|
||||
text = utf8.gsub(text, "[^A-zА-я0-9':%- ]+", "")
|
||||
return text
|
||||
end)
|
||||
|
||||
self.value = ""
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnHide()
|
||||
self:StopOnCharSearchDelay()
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnEnterPressed()
|
||||
self:ClearFocus()
|
||||
self:DoSearch()
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnEditFocusLost()
|
||||
SearchBoxTemplate_OnEditFocusLost(self)
|
||||
self:HighlightText(0, 0)
|
||||
self:DoSearch()
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnUpdate(elapsed)
|
||||
self.searchDelay = self.searchDelay - elapsed
|
||||
|
||||
if self.searchDelay <= 0 then
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self.searchDelay = nil
|
||||
self:DoSearch()
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:DoSearch()
|
||||
local newValue = self:GetText()
|
||||
if self.value ~= newValue and not (self.value == nil and newValue == "") then
|
||||
self.value = newValue
|
||||
self:GetParent():SearchItem(newValue)
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:ToggleOnCharFilter(state, searchUpdateDelay)
|
||||
if state then
|
||||
self.searchUpdateDelay = searchUpdateDelay
|
||||
self.searchDelay = searchUpdateDelay
|
||||
else
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self.searchUpdateDelay = nil
|
||||
self.searchDelay = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnTextChanged(userInput)
|
||||
PKBT_EditBoxMixin.OnTextChanged(self, userInput)
|
||||
SearchBoxTemplate_OnTextChanged(self)
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnTextValueChanged(value, userInput)
|
||||
if userInput then
|
||||
if self.searchUpdateDelay then
|
||||
self.searchDelay = self.searchUpdateDelay
|
||||
self:SetScript("OnUpdate", self.OnUpdate)
|
||||
end
|
||||
else
|
||||
self:StopOnCharSearchDelay()
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnUpdate(elapsed)
|
||||
self.searchDelay = self.searchDelay - elapsed
|
||||
|
||||
if self.searchDelay <= 0 then
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self.searchDelay = nil
|
||||
self:DoSearch()
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:StopOnCharSearchDelay()
|
||||
self:SetScript("OnUpdate", nil)
|
||||
|
||||
if self.searchUpdateDelay then
|
||||
self.searchDelay = self.searchUpdateDelay
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserSearchBoxMixin:OnClearClick(button)
|
||||
SearchBoxTemplateClearButton_OnClick(self.clearButton, button)
|
||||
self:StopOnCharSearchDelay()
|
||||
self:DoSearch()
|
||||
end
|
||||
|
||||
ItemBrowserListHeaderButtonMixin = CreateFromMixins(TableBuilderElementMixin)
|
||||
|
||||
function ItemBrowserListHeaderButtonMixin:Init(name)
|
||||
self:SetText(name)
|
||||
end
|
||||
|
||||
function ItemBrowserListHeaderButtonMixin:OnClick(button)
|
||||
end
|
||||
|
||||
ItemBrowserListRowButton = CreateFromMixins(PKBT_OwnerMixin, TableBuilderRowMixin)
|
||||
|
||||
function ItemBrowserListRowButton:OnLoad()
|
||||
self.UpdateTooltip = self.OnEnter
|
||||
end
|
||||
|
||||
function ItemBrowserListRowButton:OnEnter()
|
||||
if self.itemLink then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetHyperlink(self.itemLink)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserListRowButton:OnLeave()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
function ItemBrowserListRowButton:OnClick(button)
|
||||
if self.itemLink then
|
||||
HandleModifiedItemClick(self.itemLink)
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBrowserListRowButton:Populate(rowData, dataIndex)
|
||||
self:SetID(dataIndex)
|
||||
self.itemID = rowData.itemID
|
||||
self.itemLink = rowData.itemLink
|
||||
end
|
||||
|
||||
ItemBrowserListCellMixin = {}
|
||||
|
||||
function ItemBrowserListCellMixin:OnLoad()
|
||||
end
|
||||
|
||||
function ItemBrowserListCellMixin:Init(dataProviderKey)
|
||||
self.dataProviderKey = dataProviderKey
|
||||
end
|
||||
|
||||
function ItemBrowserListCellMixin:Populate(rowData, dataIndex)
|
||||
local value = rowData[self.dataProviderKey]
|
||||
self.Text:SetJustifyH(self.textAlignment or "CENTER")
|
||||
self.Text:SetText(value or "?")
|
||||
end
|
||||
|
||||
ItemBrowserListCellNameIconMixin = CreateFromMixins(ItemBrowserListCellMixin)
|
||||
|
||||
function ItemBrowserListCellNameIconMixin:Populate(rowData, dataIndex)
|
||||
local textWidth = self:GetWidth() - 10
|
||||
|
||||
self.Text:SetText(rowData.name or UNKNOWN)
|
||||
self.Text:SetWidth(textWidth)
|
||||
self.SubText:SetWidth(textWidth)
|
||||
|
||||
if rowData.itemType and rowData.itemSubType then
|
||||
self.SubText:SetFormattedText("%s - %s", rowData.itemType, rowData.itemSubType)
|
||||
elseif rowData.itemType or rowData.itemSubType then
|
||||
self.SubText:SetText(rowData.itemType or rowData.itemSubType)
|
||||
else
|
||||
self.SubText:SetText("")
|
||||
end
|
||||
|
||||
self.Icon:SetTexture(rowData.icon or QUESTION_MARK_ICON)
|
||||
local r, g, b = GetItemQualityColor(rowData.rarity or 1)
|
||||
self.Border:SetVertexColor(r, g, b)
|
||||
end
|
||||
|
||||
ItemBrowserListCellItemLevelMixin = CreateFromMixins(ItemBrowserListCellMixin)
|
||||
|
||||
function ItemBrowserListCellItemLevelMixin:Populate(rowData, dataIndex)
|
||||
self.Text:SetText(rowData.itemLevel and rowData.itemLevel ~= 0 and rowData.itemLevel or "")
|
||||
end
|
||||
|
||||
ItemBrowserListCellItemIDMixin = CreateFromMixins(ItemBrowserListCellMixin)
|
||||
|
||||
function ItemBrowserListCellItemIDMixin:Populate(rowData, dataIndex)
|
||||
self.Text:SetText(rowData.itemID)
|
||||
end
|
||||
-331
@@ -1,331 +0,0 @@
|
||||
<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/
|
||||
..\..\FrameXML\UI.xsd">
|
||||
<Script file="Custom_ItemBrowser.lua"/>
|
||||
|
||||
<Button name="ItemBrowserListHeaderButtonTemplate" virtual="true">
|
||||
<Size x="50" y="30"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBackground" parentKey="Background" setAllPoints="true">
|
||||
<Color r="0.2" g="0.2" b="0.2"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<!--
|
||||
<Layer level="HIGHLIGHT">
|
||||
<Texture name="$parentHighlight" parentKey="Highlight" setAllPoints="true" alpha="0.2" alphaMode="ADD">
|
||||
<Color r="1" g="1" b="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
-->
|
||||
</Layers>
|
||||
|
||||
<NormalFont style="SystemFont_Shadow_Small"/>
|
||||
<PushedTextOffset x="0" y="0"/>
|
||||
<!--
|
||||
<PushedTextOffset x="1" y="-1"/>
|
||||
<ButtonText name="$parentButtonText" parentKey="ButtonText">
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="0"/>
|
||||
</Anchors>
|
||||
</ButtonText>
|
||||
-->
|
||||
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserListHeaderButtonMixin)
|
||||
</OnLoad>
|
||||
<!--
|
||||
<OnClick>
|
||||
self:OnClick(button)
|
||||
</OnClick>
|
||||
-->
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="ItemBrowserListRowButtonTemplate" virtual="true">
|
||||
<Size x="0" y="46"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" x="1" y="0"/>
|
||||
<Anchor point="RIGHT" x="-1" y="0"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBackground" parentKey="Background" setAllPoints="true" inherits="_SearchBarLg"/>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<HighlightTexture file="Interface\Common\Search">
|
||||
<TexCoords left="0.001953" right="0.501953" top="0.234375" bottom="0.601562"/>
|
||||
</HighlightTexture>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserListRowButton)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
<OnEvent>
|
||||
self:OnEvent(event, ...)
|
||||
</OnEvent>
|
||||
<OnEnter>
|
||||
self:OnEnter()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
self:OnLeave()
|
||||
</OnLeave>
|
||||
<OnClick>
|
||||
self:OnClick()
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Frame name="ItemBrowserListCellNameIconTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentBorder" parentKey="Border" file="Interface\Common\Search">
|
||||
<Size x="40" y="40"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" x="10" y="0"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.755859" right="0.830078" top="0.234375" bottom="0.531250"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentIcon" parentKey="Icon">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorder" x="1" y="-2"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorder" x="-1" y="1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<FontString name="$parentText" parentKey="Text" inherits="GameFontNormalLarge" justifyH="LEFT" maxLines="1">
|
||||
<Size x="0" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentIcon" relativePoint="RIGHT" x="10" y="8"/>
|
||||
</Anchors>
|
||||
<Color r="0.96875" g="0.8984375" b="0.578125" a="1"/>
|
||||
</FontString>
|
||||
<FontString name="$parentSubText" parentKey="SubText" inherits="GameFontNormal" justifyH="LEFT">
|
||||
<Size x="400" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentText" relativePoint="BOTTOMLEFT" x="0" y="-5"/>
|
||||
</Anchors>
|
||||
<Color r="0.66796875" g="0.51171875" b="0.3359375" a="1"/>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserListCellNameIconMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Frame name="ItemBrowserListCellItemLevelTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentText" parentKey="Text" inherits="GameFontNormalLarge" maxLines="1">
|
||||
<Size x="0" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="0"/>
|
||||
</Anchors>
|
||||
<Color r="1" g="1" b="1"/>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserListCellItemLevelMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Frame name="ItemBrowserListCellItemIDTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentText" parentKey="Text" inherits="GameFontNormalLarge" maxLines="1">
|
||||
<Size x="0" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="0"/>
|
||||
</Anchors>
|
||||
<Color r="1" g="1" b="1"/>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserListCellItemIDMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<Frame name="ItemBrowser" inherits="PortraitFrameTemplate" toplevel="true" enableMouse="true" parent="UIParent" hidden="true">
|
||||
<Size x="800" y="496"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" x="0" y="0"/>
|
||||
</Anchors>
|
||||
|
||||
<Frames>
|
||||
<Frame name="$parentInset" inherits="InsetFrameTemplate" parentKey="inset">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" x="-4" y="-60"/>
|
||||
<Anchor point="BOTTOMLEFT" x="4" y="5"/>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
|
||||
<EditBox name="$parentSearchBox" parentKey="SearchBox" inherits="PKBT_EditBoxTemplate" letters="64">
|
||||
<Size x="130" y="36"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="60" y="-22"/>
|
||||
<Anchor point="TOPRIGHT" x="-10" y="-22"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentSearchIcon" parentKey="searchIcon" file="Interface\Common\UI-Searchbox-Icon">
|
||||
<Size x="14" y="14"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" x="5" y="-2"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentClearButton" parentKey="clearButton" hidden="true">
|
||||
<Size x="22" y="22"/>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" x="-5" y="-1"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture parentKey="texture" file="Interface\FriendsFrame\ClearBroadcastIcon" alpha="0.5" setAllPoints="true"/>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
self.texture:SetAlpha(1.0)
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
self.texture:SetAlpha(0.5)
|
||||
</OnLeave>
|
||||
<OnMouseDown>
|
||||
if self:IsEnabled() == 1 then
|
||||
self.texture:SetPoint("TOPLEFT", self, "TOPLEFT", 1, -1)
|
||||
end
|
||||
</OnMouseDown>
|
||||
<OnMouseUp>
|
||||
self.texture:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
|
||||
</OnMouseUp>
|
||||
<OnClick>
|
||||
self:GetParent():OnClearClick(button)
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserSearchBoxMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
<OnHide>
|
||||
self:OnHide()
|
||||
</OnHide>
|
||||
<OnTextChanged>
|
||||
self:OnTextChanged(userInput)
|
||||
</OnTextChanged>
|
||||
<OnEnterPressed>
|
||||
self:OnEnterPressed()
|
||||
</OnEnterPressed>
|
||||
<OnEditFocusLost>
|
||||
self:OnEditFocusLost()
|
||||
</OnEditFocusLost>
|
||||
<OnEditFocusGained function="SearchBoxTemplate_OnEditFocusGained"/>
|
||||
</Scripts>
|
||||
</EditBox>
|
||||
|
||||
<StatusBar name="$parentSearchProgressBar" parentKey="SearchProgressBar" minValue="0" maxValue="1" alpha="0">
|
||||
<Size x="0" y="6"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentSearchBox" relativePoint="BOTTOMLEFT" x="7" y="1"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentSearchBox" relativePoint="BOTTOMRIGHT" x="-7" y="1"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture parentKey="Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
<Color r="0" g="0" b="0" a="0.3"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
||||
<BarColor r="0" g="1" b="0"/>
|
||||
</StatusBar>
|
||||
|
||||
<ScrollFrame name="$parentScroll" parentKey="Scroll" inherits="HybridScrollFrameTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentInset" relativePoint="TOPLEFT" x="10" y="-50"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentInset" relativePoint="BOTTOMRIGHT" x="-36" y="10"/>
|
||||
</Anchors>
|
||||
<Frames>
|
||||
<Slider name="$parentScrollBar" parentKey="ScrollBar" inherits="PKBT_HybridScrollBarTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativePoint="TOPRIGHT" x="5" y="-25"/>
|
||||
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT" x="5" y="27"/>
|
||||
</Anchors>
|
||||
</Slider>
|
||||
</Frames>
|
||||
</ScrollFrame>
|
||||
|
||||
<Frame name="$parentHeaderHolder" parentKey="HeaderHolder">
|
||||
<Size x="0" y="30"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentScroll" relativePoint="TOPLEFT" x="0" y="12"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentScroll" relativePoint="TOPRIGHT" x="0" y="12"/>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
|
||||
<Button name="$parentTab1" inherits="CharacterFrameTabButtonTemplate" text="ADVENTURE_JOURNAL" id="1" parentKey="tab1">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="19" y="-30"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="Adventure_TabOnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentTab2" inherits="CharacterFrameTabButtonTemplate" text="HEADHUNTING" id="2" parentKey="tab2">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentTab1" relativePoint="RIGHT" x="-16" y="0"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="Adventure_TabOnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentTab3" inherits="CharacterFrameTabButtonTemplate" text="HARDCORE_CHALLENGES_TITLE" id="3" parentKey="tab3">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentTab2" relativePoint="RIGHT" x="-16" y="0"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="Adventure_TabOnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentTab4" inherits="CharacterFrameTabButtonTemplate" text="ITEM_BROWSER" id="4" parentKey="tab4">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentTab3" relativePoint="RIGHT" x="-16" y="0"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="Adventure_TabOnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, ItemBrowserMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
self:OnShow()
|
||||
</OnShow>
|
||||
<OnEvent>
|
||||
self:OnEvent(event, ...)
|
||||
</OnEvent>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
-483
@@ -1,483 +0,0 @@
|
||||
do
|
||||
local tonumber = tonumber
|
||||
local unpack = unpack
|
||||
local bitband = bit.band
|
||||
local strsub = string.sub
|
||||
|
||||
local LJ_BUFFER = {}
|
||||
|
||||
local NO_CLASS_FILTER = 0
|
||||
local NO_SPEC_FILTER = 0
|
||||
|
||||
local function getPlayerFactionID()
|
||||
local factionGroup = UnitFactionGroup("player") or "NEUTRAL"
|
||||
if factionGroup == "Renegade" then
|
||||
return (C_FactionManager.GetFactionInfoOriginal())
|
||||
end
|
||||
return PLAYER_FACTION_GROUP[factionGroup]
|
||||
end
|
||||
|
||||
local function filterByFaction(factionID, playerFactionID)
|
||||
if factionID == PLAYER_FACTION_GROUP.Neutral then
|
||||
return true
|
||||
elseif factionID == playerFactionID then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function filterByClassAndSpecFilters(classID, specID, classFilter, specFilter)
|
||||
if classFilter and specFilter then
|
||||
if specFilter == 3 then
|
||||
specFilter = 4
|
||||
end
|
||||
|
||||
if classFilter == NO_CLASS_FILTER and specFilter == NO_SPEC_FILTER then
|
||||
return true
|
||||
elseif classFilter == classID and specFilter == NO_SPEC_FILTER then
|
||||
return true
|
||||
elseif classFilter == classID and bitband(specFilter, specID) == specFilter then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function sortItemSets(a, b)
|
||||
if a[4] == b[4] then
|
||||
if a[6] ~= b[6] then
|
||||
return a[6]
|
||||
end
|
||||
return (tonumber(strsub(a[3], 3, -1) or 0)) > (tonumber(strsub(b[3], 3, -1) or 0))
|
||||
end
|
||||
return a[4] > b[4]
|
||||
end
|
||||
|
||||
C_LootJournal = {}
|
||||
|
||||
function C_LootJournal.GenerateLootData(classFilter, specFilter)
|
||||
table.wipe(LJ_BUFFER)
|
||||
|
||||
local serverID = C_Service and C_Service.GetRealmID and C_Service.GetRealmID() or 0
|
||||
local playerFactionID = getPlayerFactionID()
|
||||
local itemSetSourceRealm = EJ_ITEMSET_SOURCE_REALM and EJ_ITEMSET_SOURCE_REALM[serverID]
|
||||
|
||||
for setIndex, itemSetData in pairs(EJ_ITEMSET_DATA) do
|
||||
local name, itemlevel, tierName, sourceID, classID, specID, isPVP, itemList, factionID, realmFlag = unpack(itemSetData, 1, 10)
|
||||
if not factionID then
|
||||
factionID = 0
|
||||
end
|
||||
|
||||
if filterByClassAndSpecFilters(classID, specID, classFilter or 0, specFilter or 0)
|
||||
and filterByFaction(factionID, playerFactionID)
|
||||
then
|
||||
if itemSetSourceRealm and itemSetSourceRealm[setIndex] then
|
||||
sourceID = itemSetSourceRealm[setIndex]
|
||||
end
|
||||
local sourceText = EJ_ITEMSET_SOURCE[sourceID] or ""
|
||||
|
||||
local numItems = type(itemList) == "table" and #itemList or 0
|
||||
local items = {}
|
||||
|
||||
for i = 1, numItems do
|
||||
local itemID = itemList[i]
|
||||
items[i] = {
|
||||
itemID = itemID,
|
||||
icon = GetItemIcon(itemID) or [[Interface\Icons\INV_Misc_QuestionMark]],
|
||||
}
|
||||
end
|
||||
|
||||
LJ_BUFFER[#LJ_BUFFER + 1] = {setIndex, name, tierName or "", itemlevel, sourceText, isPVP == 1, items, numItems}
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(LJ_BUFFER, sortItemSets)
|
||||
|
||||
return LJ_BUFFER
|
||||
end
|
||||
|
||||
function C_LootJournal.GetNumItemSets()
|
||||
return #LJ_BUFFER
|
||||
end
|
||||
|
||||
function C_LootJournal.GetItemSetInfo(index)
|
||||
if index and LJ_BUFFER[index] then
|
||||
return unpack(LJ_BUFFER[index])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local NO_SPEC_FILTER = 0;
|
||||
local NO_CLASS_FILTER = 0;
|
||||
local NO_INV_TYPE_FILTER = 0;
|
||||
|
||||
--===================================================================================================================================
|
||||
LootJournalItemsMixin = { };
|
||||
|
||||
function LootJournalItemsMixin:OnLoad()
|
||||
self.Background:SetAtlas("loottab-background", true)
|
||||
self:SetView(LOOT_JOURNAL_ITEM_SETS);
|
||||
local _, _, classID = UnitClass("player");
|
||||
local specIndex = C_Talent.GetCurrentSpecTabIndex()
|
||||
self:SetClassAndSpecFilters(classID, specIndex);
|
||||
end
|
||||
|
||||
function LootJournalItemsMixin:SetClassAndSpecFilters(classID, specID)
|
||||
self.classFilter = classID;
|
||||
self.specFilter = specID;
|
||||
end
|
||||
|
||||
function LootJournalItemsMixin:GetClassAndSpecFilters()
|
||||
return self.classFilter or NO_CLASS_FILTER, self.specFilter or NO_SPEC_FILTER;
|
||||
end
|
||||
|
||||
function LootJournalItemsMixin:SetView(view)
|
||||
if ( self.view == view ) then
|
||||
return;
|
||||
end
|
||||
|
||||
self.view = view;
|
||||
self.ItemSetsFrame:Show();
|
||||
end
|
||||
|
||||
function LootJournalItemsMixin:GetActiveList()
|
||||
return self.ItemSetsFrame;
|
||||
end
|
||||
|
||||
function LootJournalItemsMixin:Refresh()
|
||||
self:GetActiveList():Refresh();
|
||||
end
|
||||
|
||||
function LootJournalItemButtonTemplate_OnEnter(self)
|
||||
local listFrame = self:GetParent();
|
||||
while ( listFrame and not listFrame.ShowItemTooltip ) do
|
||||
listFrame = listFrame:GetParent();
|
||||
end
|
||||
if ( listFrame ) then
|
||||
listFrame:ShowItemTooltip(self);
|
||||
self:SetScript("OnUpdate", LootJournalItemButton_OnUpdate);
|
||||
self.UpdateTooltip = LootJournalItemButtonTemplate_OnEnter;
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemButtonTemplate_OnLeave(self)
|
||||
self.UpdateTooltip = nil;
|
||||
GameTooltip:Hide();
|
||||
self:SetScript("OnUpdate", nil);
|
||||
ResetCursor();
|
||||
end
|
||||
|
||||
function LootJournalItemButton_OnClick(self, button)
|
||||
if HandleModifiedItemClick(self.itemLink) then
|
||||
return
|
||||
end
|
||||
|
||||
LootJournal_OpenItemByEntry(self.itemID)
|
||||
end
|
||||
|
||||
--===================================================================================================================================
|
||||
LootJournalItemSetsMixin = {}
|
||||
|
||||
local LJ_ITEMSET_X_OFFSET = 10;
|
||||
local LJ_ITEMSET_Y_OFFSET = 10;
|
||||
local LJ_ITEMSET_BUTTON_SPACING = 13;
|
||||
local LJ_ITEMSET_BOTTOM_BUFFER = 4;
|
||||
|
||||
function LootJournalItemSetsMixin:Refresh()
|
||||
self.dirty = true;
|
||||
local offset = self.scrollBar:GetValue();
|
||||
if ( offset == 0 ) then
|
||||
self:UpdateList();
|
||||
else
|
||||
self.scrollBar:SetValue(0);
|
||||
end
|
||||
if ( self.ClassButton ) then
|
||||
self:UpdateClassButtonText();
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:GetClassAndSpecFilters()
|
||||
return self:GetParent():GetClassAndSpecFilters();
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:UpdateClassButtonText()
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:ShowItemTooltip(button)
|
||||
-- itemLink may not be available
|
||||
if not button.itemLink then
|
||||
GameTooltip:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
GameTooltip:SetOwner(button, "ANCHOR_RIGHT");
|
||||
GameTooltip:SetHyperlink(button.itemLink);
|
||||
|
||||
if LootJournal_CanOpenItemByEntry(button.itemID) then
|
||||
GameTooltip:AddLine(LOOTJOURNAL_ITEM_CLICK_TO_OPEN_LOOT, 0, 0.8, 1)
|
||||
end
|
||||
|
||||
self.tooltipItemID = button.itemID;
|
||||
GameTooltip:Show();
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:CheckItemButtonTooltip(button)
|
||||
if ( GameTooltip:GetOwner() == button and self.tooltipItemID ~= button.itemID ) then
|
||||
self:ShowItemTooltip(button);
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:GetClassFilter()
|
||||
local classFilter, specFilter = self:GetClassAndSpecFilters();
|
||||
return classFilter;
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:GetSpecFilter()
|
||||
local classFilter, specFilter = self:GetClassAndSpecFilters();
|
||||
return specFilter;
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:SetClassAndSpecFilters(newClassFilter, newSpecFilter)
|
||||
local classFilter, specFilter = self:GetClassAndSpecFilters();
|
||||
if not self.classAndSpecFiltersSet or classFilter ~= newClassFilter or specFilter ~= newSpecFilter then
|
||||
--[[
|
||||
-- if choosing just a class without a spec, pick a spec
|
||||
if newClassFilter ~= NO_CLASS_FILTER and newSpecFilter == NO_SPEC_FILTER then
|
||||
local _, _, classID = UnitClass("player");
|
||||
-- if player's class, choose active spec
|
||||
-- otherwise use 1st spec
|
||||
if classID == newClassFilter then
|
||||
local specIndex = C_Talent.GetCurrentSpecTabIndex()
|
||||
newSpecFilter = specIndex
|
||||
else
|
||||
newSpecFilter = 1
|
||||
end
|
||||
end
|
||||
--]]
|
||||
self:GetParent():SetClassAndSpecFilters(newClassFilter, newSpecFilter);
|
||||
self.scrollBar:SetValue(0);
|
||||
self:Refresh();
|
||||
end
|
||||
|
||||
CloseDropDownMenus(1);
|
||||
self.classAndSpecFiltersSet = true;
|
||||
end
|
||||
|
||||
do
|
||||
function LootJournalItemButton_OnUpdate(self)
|
||||
if GameTooltip:IsOwned(self) then
|
||||
if IsModifiedClick("DRESSUP") then
|
||||
ShowInspectCursor();
|
||||
else
|
||||
ResetCursor();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function OpenClassFilterDropDown(self, level)
|
||||
if level then
|
||||
self:GetParent():GetActiveList():OpenClassFilterDropDown(level);
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemsClassDropDown_OnLoad(self)
|
||||
UIDropDownMenu_Initialize(self, OpenClassFilterDropDown, "MENU");
|
||||
end
|
||||
|
||||
local CLASS_DROPDOWN = 1;
|
||||
|
||||
function LootJournalItemSetsMixin:OpenClassFilterDropDown(level)
|
||||
local filterClassID = self:GetClassFilter();
|
||||
local filterSpecID = self:GetSpecFilter();
|
||||
local classDisplayName, classTag, classID;
|
||||
|
||||
local function SetClassAndSpecFilters(_, classFilter, specFilter)
|
||||
self:SetClassAndSpecFilters(classFilter, specFilter);
|
||||
end
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
|
||||
if UIDROPDOWNMENU_MENU_VALUE == CLASS_DROPDOWN then
|
||||
info.text = ALL_CLASSES;
|
||||
info.checked = filterClassID == NO_CLASS_FILTER;
|
||||
info.arg1 = NO_CLASS_FILTER;
|
||||
info.arg2 = NO_SPEC_FILTER;
|
||||
info.func = SetClassAndSpecFilters;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
|
||||
local numClasses = GetNumClasses();
|
||||
for i = 1, numClasses do
|
||||
classDisplayName, classTag, classID = GetClassInfo(i);
|
||||
if classID ~= 10 then
|
||||
info.text = classDisplayName;
|
||||
info.checked = filterClassID == classID;
|
||||
info.arg1 = classID;
|
||||
info.arg2 = NO_SPEC_FILTER;
|
||||
info.func = SetClassAndSpecFilters;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if level == 1 then
|
||||
info.text = CLASS;
|
||||
info.func = nil;
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
info.value = CLASS_DROPDOWN;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
|
||||
local classDisplayName, classTag, classID;
|
||||
if filterClassID ~= NO_CLASS_FILTER then
|
||||
classID = filterClassID;
|
||||
classDisplayName = GetClassInfo(classID)
|
||||
else
|
||||
classDisplayName, classTag, classID = UnitClass("player");
|
||||
end
|
||||
|
||||
info.text = classDisplayName;
|
||||
info.notCheckable = true;
|
||||
info.arg1 = nil;
|
||||
info.arg2 = nil;
|
||||
info.func = nil;
|
||||
info.hasArrow = false;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
|
||||
info.notCheckable = nil;
|
||||
for i = 1, GetNumSpecializationsForClassID(classID) do
|
||||
local _, specName = GetSpecializationInfoForClassID(classID, i)
|
||||
info.leftPadding = 10;
|
||||
info.text = specName;
|
||||
info.checked = filterSpecID == i;
|
||||
info.arg1 = classID;
|
||||
info.arg2 = i;
|
||||
info.func = SetClassAndSpecFilters;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
end
|
||||
|
||||
info.text = ALL_SPECS;
|
||||
info.leftPadding = 10;
|
||||
info.checked = (classID == filterClassID and filterSpecID == NO_SPEC_FILTER) or (filterClassID == NO_CLASS_FILTER and filterSpecID == NO_SPEC_FILTER);
|
||||
info.arg1 = classID;
|
||||
info.arg2 = NO_SPEC_FILTER;
|
||||
info.func = SetClassAndSpecFilters;
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:OnLoad()
|
||||
self.scrollBar.trackBG:Hide();
|
||||
self.update = LootJournalItemSetsMixin.UpdateList;
|
||||
HybridScrollFrame_CreateButtons(self, "LootJournalItemSetButtonTemplate", LJ_ITEMSET_X_OFFSET, -LJ_ITEMSET_Y_OFFSET, "TOPLEFT", nil, nil, -LJ_ITEMSET_BUTTON_SPACING);
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:OnShow()
|
||||
if not self.init then
|
||||
self.init = true;
|
||||
self:Refresh();
|
||||
end
|
||||
end
|
||||
|
||||
local function onItemLoaded(itemID)
|
||||
local self = EncounterJournal.LootJournalItems.ItemSetsFrame
|
||||
for i = 1, #self.buttons do
|
||||
local itemButtons = self.buttons[i].ItemButtons;
|
||||
for j = 1, #itemButtons do
|
||||
if ( itemButtons[j].itemID == itemID ) then
|
||||
self:ConfigureItemButton(itemButtons[j]);
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:ConfigureItemButton(button)
|
||||
local _, itemLink, itemQuality, _, _, _, _, _, _, icon = C_Item.GetItemInfo(button.itemID, false, onItemLoaded, true);
|
||||
button.itemLink = itemLink;
|
||||
itemQuality = itemQuality or Enum.ItemQuality.Epic; -- sets are most likely rare
|
||||
if ( itemQuality == Enum.ItemQuality.Uncommon ) then
|
||||
button.Border:SetAtlas("loottab-set-itemborder-green", true);
|
||||
elseif ( itemQuality == Enum.ItemQuality.Rare ) then
|
||||
button.Border:SetAtlas("loottab-set-itemborder-blue", true);
|
||||
elseif ( itemQuality == Enum.ItemQuality.Epic ) then
|
||||
button.Border:SetAtlas("loottab-set-itemborder-purple", true);
|
||||
end
|
||||
|
||||
button.Icon:SetTexture(icon or "Interface\\ICONS\\temp")
|
||||
|
||||
button:GetParent().SetName:SetTextColor(GetItemQualityColor(itemQuality));
|
||||
self:CheckItemButtonTooltip(button);
|
||||
end
|
||||
|
||||
function LootJournalItemSetsMixin:UpdateList()
|
||||
if ( self.dirty ) then
|
||||
C_LootJournal.GenerateLootData(self:GetClassAndSpecFilters())
|
||||
self.dirty = nil;
|
||||
end
|
||||
|
||||
local buttons = self.buttons;
|
||||
local offset = HybridScrollFrame_GetOffset(self);
|
||||
|
||||
local numSets = C_LootJournal.GetNumItemSets()
|
||||
|
||||
for i = 1, #buttons do
|
||||
local button = buttons[i];
|
||||
local index = offset + i;
|
||||
if ( index <= numSets ) then
|
||||
local setIndex, name, tierName, itemlevel, sourceText, isPVP, items, numItems = C_LootJournal.GetItemSetInfo(index)
|
||||
|
||||
button:Show();
|
||||
button.SetName:SetText(name);
|
||||
button.ItemLevel:SetFormattedText(EJ_SET_ITEM_LEVEL, tierName, itemlevel);
|
||||
button.PVPIcon:SetShown(isPVP);
|
||||
|
||||
button.setIndex = setIndex
|
||||
button.tooltipText = sourceText
|
||||
button:CheckItemButtonTooltip()
|
||||
|
||||
for j = 1, numItems do
|
||||
local itemButton = button.ItemButtons[j];
|
||||
if ( not itemButton ) then
|
||||
itemButton = CreateFrame("BUTTON", string.format("$parentItemButton%i", j), button, "LootJournalItemSetItemButtonTemplate");
|
||||
button[string.format("$parentItemButton%i", j)] = itemButton
|
||||
itemButton:SetPoint("LEFT", button.ItemButtons[j-1], "RIGHT", 5, 0);
|
||||
end
|
||||
itemButton.Icon:SetTexture(items[j].icon);
|
||||
itemButton.itemID = items[j].itemID;
|
||||
itemButton:Show();
|
||||
self:ConfigureItemButton(itemButton);
|
||||
end
|
||||
for j = numItems + 1, #button.ItemButtons do
|
||||
button.ItemButtons[j].itemID = nil;
|
||||
button.ItemButtons[j]:Hide();
|
||||
end
|
||||
else
|
||||
button:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
local totalHeight = numSets * buttons[1]:GetHeight() + (numSets - 1) * LJ_ITEMSET_BUTTON_SPACING + LJ_ITEMSET_Y_OFFSET + LJ_ITEMSET_BOTTOM_BUFFER
|
||||
HybridScrollFrame_Update(self, totalHeight, self:GetHeight());
|
||||
end
|
||||
|
||||
LootJournalItemSetButtonMixin = {}
|
||||
|
||||
function LootJournalItemSetButtonMixin:OnEnter()
|
||||
if self.tooltipText then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOP")
|
||||
GameTooltip:SetText(LOOTJOURNAL_SOURCE_TOOLTIP_HEAD, 1, 1, 1)
|
||||
GameTooltip:AddLine(self.tooltipText, nil, nil, nil, 1)
|
||||
self.tooltipSetIndex = self.setIndex
|
||||
GameTooltip:Show()
|
||||
else
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function LootJournalItemSetButtonMixin:CheckItemButtonTooltip()
|
||||
if ( GameTooltip:GetOwner() == self and self.tooltipSetIndex ~= self.setIndex ) then
|
||||
self:OnEnter();
|
||||
end
|
||||
end
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
<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/
|
||||
..\..\FrameXML\UI.xsd">
|
||||
<Script file="Custom_LootJournalItems.lua"/>
|
||||
|
||||
<Button name="LootJournalItemButtonTemplate" virtual="true">
|
||||
<Scripts>
|
||||
<OnEnter function="LootJournalItemButtonTemplate_OnEnter"/>
|
||||
<OnLeave function="LootJournalItemButtonTemplate_OnLeave"/>
|
||||
<OnClick function="LootJournalItemButton_OnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Button name="LootJournalItemSetItemButtonTemplate" inherits="LootJournalItemButtonTemplate" virtual="true" hidden="true">
|
||||
<Size x="32" y="32"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentIcon" parentKey="Icon">
|
||||
<Size x="28" y="28"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture parentKey="Border">
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativeTo="$parentIcon" relativePoint="CENTER" x="20" y="1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:SetParentArray("ItemButtons")
|
||||
self.Border:SetAtlas("loottab-set-itemborder-green", true)
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Button name="LootJournalItemSetButtonTemplate" virtual="true">
|
||||
<Size x="744" y="41"/>
|
||||
<HitRectInsets left="34" right="390" top="1" bottom="1"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture parentKey="Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="0" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentSetName" parentKey="SetName" inherits="GameFontNormalMed2" maxLines="1" justifyH="LEFT">
|
||||
<Size x="320" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="38" y="-6"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentItemLevel" parentKey="ItemLevel" inherits="GameFontNormal" text="Item Level" maxLines="1" justifyH="LEFT">
|
||||
<Size x="320" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentSetName" relativePoint="BOTTOMLEFT" x="0" y="-2"/>
|
||||
</Anchors>
|
||||
<Color r="0.718" g="0.561" b="0.416"/>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="$parentPVPIcon" parentKey="PVPIcon" hidden="true">
|
||||
<Size x="30" y="30"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="LEFT" x="0" y="2"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentIcon" parentKey="Icon" file="Interface\PVPFrame\Icons\prestige-icon-4"/>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip:AddLine(LOOTJOURNAL_PVPICON_TOOLTIP_HEAD, 1, 1, 1)
|
||||
GameTooltip:AddLine(LOOTJOURNAL_PVPICON_TOOLTIP, nil, nil, nil, 1)
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave function="GameTooltip_Hide"/>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Button name="$parentItemButton1" parentKey="ItemButton1" inherits="LootJournalItemSetItemButtonTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" x="397" y="0"/>
|
||||
</Anchors>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, LootJournalItemSetButtonMixin)
|
||||
self.Background:SetAtlas("loottab-set-background", true)
|
||||
</OnLoad>
|
||||
<OnEnter>
|
||||
self:OnEnter()
|
||||
</OnEnter>
|
||||
<OnLeave function="GameTooltip_Hide"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Frame parent="EncounterJournal" name="$parentLootJournalItems" parentKey="LootJournalItems" hidden="true">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentInset" x="4" y="-51" />
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentInset" x="-4" y="0"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture parentKey="Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" x="0" y="4"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="LootJournalItemsClassDropDown" parentKey="ClassDropDown" inherits="UIDropDownMenuTemplate" hidden="true">
|
||||
<Scripts>
|
||||
<OnLoad function="LootJournalItemsClassDropDown_OnLoad"/>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<ScrollFrame name="$parentItemSetsFrame" parentKey="ItemSetsFrame" inherits="MinimalHybridScrollFrameTemplate" hidden="true">
|
||||
<Size x="762" y="332"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" x="0" y="3"/>
|
||||
</Anchors>
|
||||
<Frames>
|
||||
<Button parentKey="ClassButton" inherits="EJButtonTemplate" text="FILTER">
|
||||
<Size x="114" y="26"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" x="-12" y="35"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnMouseDown>
|
||||
EJButtonMixin.OnMouseDown(self, button);
|
||||
ToggleDropDownMenu(1, nil, self:GetParent():GetParent().ClassDropDown, self, 5, 0);
|
||||
PlaySound("igMainMenuOptionCheckBoxOn");
|
||||
</OnMouseDown>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, LootJournalItemSetsMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
self:OnShow()
|
||||
</OnShow>
|
||||
</Scripts>
|
||||
</ScrollFrame>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, LootJournalItemsMixin)
|
||||
self:OnLoad()
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
-15
@@ -365,21 +365,6 @@ LOOT_JOURNAL_ITEM_SETS = LOOT_JOURNAL_ITEM_SETS or "Комплекты"
|
||||
-- compact form on 3.3.5.
|
||||
BOSS_INFO_STRING = BOSS_INFO_STRING or "Босс: %s"
|
||||
|
||||
-- Sirus ships a PKBT model mixin in SharedXML/SharedUIPanelPKBTTemplates;
|
||||
-- we don't carry it. The EJ DressUpModel OnShow does `self:OnShow()` and
|
||||
-- OnEvent does `self:OnEvent(...)`, expecting the mixin to provide them.
|
||||
PKBT_ModelMixin = PKBT_ModelMixin or {}
|
||||
PKBT_ModelMixin.OnShow = PKBT_ModelMixin.OnShow or function() end
|
||||
PKBT_ModelMixin.OnEvent = PKBT_ModelMixin.OnEvent or function() end
|
||||
PKBT_ModelMixin.OnLoad = PKBT_ModelMixin.OnLoad or function() end
|
||||
|
||||
if not SharedXML_Model_OnLoad then
|
||||
function SharedXML_Model_OnLoad() end
|
||||
end
|
||||
if not SharedXML_Model_OnEvent then
|
||||
function SharedXML_Model_OnEvent() end
|
||||
end
|
||||
|
||||
ITEM_CLASS_2 = ITEM_CLASS_2 or 2
|
||||
ITEM_CLASS_4 = ITEM_CLASS_4 or 4
|
||||
|
||||
|
||||
+21
-2
@@ -119,13 +119,32 @@ end
|
||||
-- 3.3.5 has no SetPortraitTextureFromCreatureDisplayID equivalent, so leave
|
||||
-- the texture blank — the static UI-EJ-BOSS-* icon set elsewhere is enough.
|
||||
do
|
||||
local portraitByDisplayInfo = {}
|
||||
local data = MoonWellEncounterJournalData
|
||||
if data and data.creatures then
|
||||
for _, creatureList in pairs(data.creatures) do
|
||||
for _, creature in ipairs(creatureList) do
|
||||
local displayInfo = creature[3]
|
||||
local icon = creature[4]
|
||||
if displayInfo and displayInfo > 0 and icon and icon ~= "" then
|
||||
portraitByDisplayInfo[displayInfo] = icon
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Ogom is a nested encounter variant and has no top-level portrait row.
|
||||
portraitByDisplayInfo[6709] = [[Interface\EncounterJournal\UI-EJ-BOSS-Jammalan the Prophet]]
|
||||
MoonWellEncounterPortraitByDisplayInfo = portraitByDisplayInfo
|
||||
|
||||
local frame = CreateFrame("Frame")
|
||||
local texture = frame:CreateTexture()
|
||||
local meta = getmetatable(texture)
|
||||
local methods = meta and meta.__index
|
||||
if type(methods) == "table" and not methods.SetPortrait then
|
||||
methods.SetPortrait = function(self)
|
||||
self:SetTexture(nil)
|
||||
methods.SetPortrait = function(self, displayInfo)
|
||||
self:SetTexture(portraitByDisplayInfo[displayInfo] or QUESTION_MARK_ICON)
|
||||
self:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-24958
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -62,7 +62,7 @@ MoonWellEncounterJournalData = {
|
||||
[281] = { 'Нексус', 'Аспект из рода синих драконов, Малигос, вознамерился вновь обрести контроль над силами магии. Он начал ожесточенную борьбу за то, чтобы разорвать связь смертных с тайной энергией Азерота. Теперь синие драконы направляют потоки энергии всего мира к Нексусу, гигантскому логову Малигоса.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-thenexus.blp', 'interface\\lfgframe\\lfgicon-thenexus.blp', 'interface\\encounterjournal\\ui-ej-background-thenexus.blp', 'interface\\encounterjournal\\ui-ej-lorebg-thenexus.blp', 576, 0, 11, 1, 281, 520 },
|
||||
[282] = { 'Окулус', 'Аспект из рода синих драконов, Малигос, вознамерился вновь обрести контроль над силами магии. Он начал ожесточенную борьбу за то, чтобы разорвать связь смертных с тайной энергией Азерота. Теперь синие драконы направляют потоки энергии всего мира к Нексусу, гигантскому логову Малигоса.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-theoculus.blp', 'interface\\lfgframe\\lfgicon-theoculus.blp', 'interface\\encounterjournal\\ui-ej-background-theoculus.blp', 'interface\\encounterjournal\\ui-ej-lorebg-theoculus.blp', 578, 0, 12, 0, 282, 528 },
|
||||
[761] = { 'Рубиновое святилище', 'После обнаружения кладки яиц сумеречных драконов в Обсидиановом святилище, Кориалстраз попросил Совет Шести отправить искателей приключений уничтожить их. Это было сделано быстро и без лишнего шума. И хотя все со временем успокоилось, по необъяснимым причинам связь со стражами Рубинового святилища была утеряна. Привратники, стоявшие у портала, оказались убитыми, а магические камни – разрушены. Нынешнее положение Рубинового святилища неизвестно, и ещё меньше известно о напавших на него, так как число чёрных драконов в Нордсколе слишком мало для подобного нападения. Что же за сила посмела напасть на оплот красных драконов, и как они смогли проскользнуть мимо стражников незамеченными?', 'interface\\encounterjournal\\ui-ej-dungeonbutton-rubysanctum.blp', 'interface\\lfgframe\\lfgicon-rubysanctum.blp', 'interface\\encounterjournal\\ui-ej-background-rubysanctum.blp', 'interface\\encounterjournal\\ui-ej-lorebg-rubysanctum.blp', 724, 0, 12, 16, 761, 609 },
|
||||
[772] = { 'Старые предгорья Хилсбрада', 'В Глубине пещер Времени пробудился погруженный в раздумья дракон Ноздорму. Еще на заре мироздания бронзовые драконы неусыпно хранили запутанный лабиринт временных потоков и следили за хрупким равновесием времени.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-CavernsOfTime.blpp', 'interface\\lfgframe\\LFGIcon-CavernsOfTime.BLP', 'interface\\encounterjournal\\UI-EJ-BACKGROUND-CavernsOfTime.blp', 'interface\\encounterjournal\\UI-EJ-LOREBG-CavernsOfTime.blp', 560, 0, 12, 1024, 772, 845 },
|
||||
[772] = { 'Старые предгорья Хилсбрада', 'В Глубине пещер Времени пробудился погруженный в раздумья дракон Ноздорму. Еще на заре мироздания бронзовые драконы неусыпно хранили запутанный лабиринт временных потоков и следили за хрупким равновесием времени.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-CavernsOfTime.blp', 'interface\\lfgframe\\LFGIcon-CavernsOfTime.BLP', 'interface\\encounterjournal\\UI-EJ-BACKGROUND-CavernsOfTime.blp', 'interface\\encounterjournal\\UI-EJ-LOREBG-CavernsOfTime.blp', 560, 0, 12, 1024, 772, 845 },
|
||||
[253] = { 'Темный лабиринт', 'Дренорским изгнанникам смерть казалась неприятным и неблаговидным последствием жизни. Поэтому дренеи скрывали своих мертвых в подземном некрополе Аукиндоне. Этот чудо-лабиринт раскинулся под самым лесом Тероккар.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-auchindoun.blp', 'interface\\lfgframe\\lfgicon-auchindoun.blp', 'interface\\encounterjournal\\ui-ej-background-auchindoun.blp', 'interface\\encounterjournal\\ui-ej-lorebg-auchindoun.blp', 555, 0, 13, 0, 253, 834 },
|
||||
[769] = { 'Очищение Стратхольма', 'В Глубине пещер Времени пробудился погруженный в раздумья дракон Ноздорму. Еще на заре мироздания бронзовые драконы неусыпно хранили запутанный лабиринт временных потоков и следили за хрупким равновесием времени.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-TheCullingOfStratholme.blp', 'interface\\lfgframe\\LFGIcon-CavernsOfTime.BLP', 'interface\\encounterjournal\\UI-EJ-BACKGROUND-TheCullingOfStratholme.blp', 'interface\\encounterjournal\\UI-EJ-LOREBG-TheCullingOfStratholme.blp', 595, 0, 13, 1024, 769, 521 },
|
||||
[277] = { 'Чертоги Камня', 'Покидая Азерот, титаны доверили лучшим защитникам охрану Ульдуара, таинственного города, укрытого пиками Грозовой гряды. Первым среди своих братьев был назван страж по имени Локен, но осознав, какую мощь оставили после себя титаны, он поддался тьме и вверг город в пучину хаоса.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-hallsofstone.blp', 'interface\\lfgframe\\lfgicon-hallsofstone.blp', 'interface\\encounterjournal\\ui-ej-background-hallsofstone.blp', 'interface\\encounterjournal\\ui-ej-lorebg-hallsofstone.blp', 599, 0, 14, 0, 277, 526 },
|
||||
@@ -72,7 +72,7 @@ MoonWellEncounterJournalData = {
|
||||
[275] = { 'Чертоги Молний', 'Покидая Азерот, титаны доверили лучшим защитникам охрану Ульдуара, таинственного города, укрытого пиками Грозовой гряды. Первым среди своих братьев был назван страж по имени Локен, но осознав, какую мощь оставили после себя титаны, он поддался тьме и вверг город в пучину хаоса.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-hallsoflightning.blp', 'interface\\lfgframe\\lfgicon-hallsoflightning.blp', 'interface\\encounterjournal\\ui-ej-background-hallsoflightning.blp', 'interface\\encounterjournal\\ui-ej-lorebg-hallsoflightning.blp', 602, 0, 15, 1, 275, 525 },
|
||||
[229] = { 'Нижняя часть пика Черной горы', 'Потрясающая крепость, вырезанная в огненном сердце Черной горы, веками служила образцом мощи клана Черного Железа. Но не так давно черный дракон Нефариан и его род захватили верхние ярусы крепости и развязали жестокую войну с дворфами. Армии драконов нашли союзника в лице вождя Ренда Чернорука и его \'Орды\', и теперь их объединенные силы хозяйничают на Пике Черной горы, проводя эксперименты, призванные расширить их ряды, и строя планы по уничтожению дворфов Черного Железа.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-blackrockspire.blp', 'interface\\lfgframe\\lfgicon-blackrockspire.blp', 'interface\\encounterjournal\\ui-ej-background-blackrockspire.blp', 'interface\\encounterjournal\\ui-ej-lorebg-blackrockspire.blp', 229, 0, 16, 0, 229, 882 },
|
||||
[278] = { 'Яма Сарона', 'Противостояние защитников Азерота и армии Короля-лича продолжалось долгие годы. За это время пало множество героев, а после смерти они были вынуждены присоединиться к чудовищной армии нежити. В ходе этого безустанного противостояния Тирион Фордринг из Серебряного Авангарда объединил силы с рыцарями Черного Клинка под командованием Дариона Могрейна. Теперь эта объединенная армия, получившая название Пепельный союз, собирается взять штурмом цитадель Ледяной Короны.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-pitofsaron.blp', 'interface\\lfgframe\\lfgicon-pitofsaron.blp', 'interface\\encounterjournal\\ui-ej-background-pitofsaron.blp', 'interface\\encounterjournal\\ui-ej-lorebg-pitofsaron.blp', 658, 0, 16, 1, 278, 602 },
|
||||
[768] = { 'Черные топи ', 'В Глубине пещер Времени пробудился погруженный в раздумья дракон Ноздорму. Еще на заре мироздания бронзовые драконы неусыпно хранили запутанный лабиринт временных потоков и следили за хрупким равновесием времени.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-CavernsOfTime.blpp', 'interface\\lfgframe\\LFGIcon-CavernsOfTime.BLP', 'interface\\encounterjournal\\UI-EJ-BACKGROUND-CavernsOfTime.blp', 'interface\\encounterjournal\\UI-EJ-LOREBG-CavernsOfTime.blp', 269, 0, 16, 1024, 768, 844 },
|
||||
[768] = { 'Черные топи ', 'В Глубине пещер Времени пробудился погруженный в раздумья дракон Ноздорму. Еще на заре мироздания бронзовые драконы неусыпно хранили запутанный лабиринт временных потоков и следили за хрупким равновесием времени.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-CavernsOfTime.blp', 'interface\\lfgframe\\LFGIcon-CavernsOfTime.BLP', 'interface\\encounterjournal\\UI-EJ-BACKGROUND-CavernsOfTime.blp', 'interface\\encounterjournal\\UI-EJ-LOREBG-CavernsOfTime.blp', 269, 0, 16, 1024, 768, 844 },
|
||||
[762] = { 'Огненная Пропасть', 'Огненная Пропасть залегает глубоко под Оргриммаром. Ee вулканическими пещерами некогда владели дикие трогги, пока туда не пришли жуткие сектанты из клана Пламенеющего Клинка. Сектанты вызвали в этот мир жуткое создание, имя которому Тарагаман Ненасытный. С помощью его мощи, ходят слухи, что они хотят выбраться из подземелья и захватить Оргриммар. В помощь себе они также призвали к себе в ряды сатира Баззалана, который будет руководить армией сектантов.', 'interface\\encounterjournal\\UI-EJ-DUNGEONBUTTON-RagefireChasm.blp', 'interface\\lfgframe\\lfgicon-RAGEFIRECHASM.blp', 'interface\\encounterjournal\\ui-ej-background-ragefirechasm.blp', 'interface\\encounterjournal\\ui-ej-lorebg-ragefirechasm.blp', 389, 0, 17, 0, 762, 680 },
|
||||
[240] = { 'Пещеры Стенаний', 'Много лет назад прославленный друид ночных эльфов Наралекс спустился в темные Пещеры Стенаний со своими спутниками. Своим названием пещеры обязаны похожим на плач звукам, сопровождающим вырывающийся на свободу пар. Он намеревался использовать подземные источники, чтобы вернуть Степям их былое плодородие, но стоило ему окунуться в Изумрудный Сон, как его прекрасное видение обернулось жутким кошмаром. С тех самых пор над этим местом нависло страшное проклятие.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-wailingcaverns.blp', 'interface\\lfgframe\\lfgicon-wailingcaverns.blp', 'interface\\encounterjournal\\ui-ej-background-wailingcaverns.blp', 'interface\\encounterjournal\\ui-ej-lorebg-wailingcaverns.blp', 43, 0, 18, 0, 240, 749 },
|
||||
[236] = { 'Стратхольм', 'Стратхольм был настоящей жемчужиной северного Лордерона, но сейчас все помнят лишь его сокрушительное падение. Именно здесь принц Артас когда-то ослушался своего наставника, благородного паладина Утера Светоносного, и вырезал сотни горожан, якобы зараженных чумой нежити. С тех пор в городе царят смерть, предательство и отчаяние.', 'interface\\encounterjournal\\ui-ej-dungeonbutton-stratholme.blp', 'interface\\lfgframe\\lfgicon-stratholme.blp', 'interface\\encounterjournal\\ui-ej-background-stratholme.blp', 'interface\\encounterjournal\\ui-ej-lorebg-stratholme.blp', 329, 0, 19, 0, 236, 892 },
|
||||
|
||||
-45002
File diff suppressed because it is too large
Load Diff
-45002
File diff suppressed because it is too large
Load Diff
-119789
File diff suppressed because it is too large
Load Diff
-128
@@ -1,128 +0,0 @@
|
||||
local securecall = securecall
|
||||
local ipairs = ipairs
|
||||
local next = next
|
||||
local type = type
|
||||
local strsplit = string.split
|
||||
|
||||
local ExecuteFrameScript = ExecuteFrameScript
|
||||
local GetFramesRegisteredForEvent = GetFramesRegisteredForEvent
|
||||
local UnitName = UnitName
|
||||
local UnitTokenFromGUID = UnitTokenFromGUID
|
||||
|
||||
local REGISTERED_CUSTOM_EVENTS = {}
|
||||
local REGISTERED_CUSTOM_EVENTS_ALL
|
||||
|
||||
local function SecureNext(elements, key)
|
||||
return securecall(next, elements, key)
|
||||
end
|
||||
|
||||
function FireClientEvent(event, ...)
|
||||
for _, frame in SecureNext, {GetFramesRegisteredForEvent(event)} do
|
||||
securecall(ExecuteFrameScript, frame, "OnEvent", event, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function FireCustomClientEvent(event, ...)
|
||||
if REGISTERED_CUSTOM_EVENTS[event] then
|
||||
for frame in SecureNext, REGISTERED_CUSTOM_EVENTS[event] do
|
||||
securecall(ExecuteFrameScript, frame, "OnEvent", event, ...)
|
||||
end
|
||||
end
|
||||
if REGISTERED_CUSTOM_EVENTS_ALL then
|
||||
for frame in SecureNext, REGISTERED_CUSTOM_EVENTS_ALL do
|
||||
securecall(ExecuteFrameScript, frame, "OnEvent", event, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local eventRegistrar = CreateFrame("Frame")
|
||||
eventRegistrar:SetScript("OnAttributeChanged", function(this, name, value)
|
||||
if name == "1" then
|
||||
if not REGISTERED_CUSTOM_EVENTS[value] then
|
||||
REGISTERED_CUSTOM_EVENTS[value] = {}
|
||||
end
|
||||
REGISTERED_CUSTOM_EVENTS[value][this:GetAttribute("f")] = true
|
||||
elseif name == "0" then
|
||||
if REGISTERED_CUSTOM_EVENTS[value] then
|
||||
REGISTERED_CUSTOM_EVENTS[value][this:GetAttribute("f")] = nil
|
||||
end
|
||||
elseif name == "2" then
|
||||
REGISTERED_CUSTOM_EVENTS_ALL[value] = true
|
||||
elseif name == "3" then
|
||||
REGISTERED_CUSTOM_EVENTS_ALL[value] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
function RegisterCustomEvent(self, event)
|
||||
eventRegistrar:SetAttribute("f", self)
|
||||
eventRegistrar:SetAttribute("1", event)
|
||||
end
|
||||
|
||||
function UnregisterCustomEvent(self, event)
|
||||
eventRegistrar:SetAttribute("f", self)
|
||||
eventRegistrar:SetAttribute("0", event)
|
||||
end
|
||||
|
||||
function RegisterAllCustomEvents(self)
|
||||
if not REGISTERED_CUSTOM_EVENTS_ALL then
|
||||
REGISTERED_CUSTOM_EVENTS_ALL = {}
|
||||
end
|
||||
eventRegistrar:SetAttribute("2", self)
|
||||
end
|
||||
|
||||
function UnregisterAllCustomEvents(self)
|
||||
if not REGISTERED_CUSTOM_EVENTS_ALL then
|
||||
return
|
||||
end
|
||||
eventRegistrar:SetAttribute("3", self)
|
||||
end
|
||||
|
||||
function FireCustomClientUnitGroupEvent(event, unitGUID, ...)
|
||||
if event and REGISTERED_CUSTOM_EVENTS[event] and unitGUID then
|
||||
local units = {UnitTokenFromGUID(unitGUID)}
|
||||
if #units > 0 then
|
||||
for frame in SecureNext, REGISTERED_CUSTOM_EVENTS[event] do
|
||||
for _, unit in ipairs(units) do
|
||||
securecall(ExecuteFrameScript, frame, "OnEvent", event, unit, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EventHandler = setmetatable(
|
||||
{
|
||||
events = {}, -- Original events
|
||||
listeners = {}, -- New tables for handling events outside og EventHandler
|
||||
RegisterListener = function(self, listener)
|
||||
self.listeners[listener] = true
|
||||
end,
|
||||
Handle = function(self, opcode, message, unk, sender)
|
||||
if sender == UnitName("player") then
|
||||
for listener in SecureNext, self.listeners do
|
||||
if listener[opcode] then
|
||||
securecall(listener[opcode], listener, message)
|
||||
end
|
||||
end
|
||||
|
||||
if self.events[opcode] then
|
||||
securecall(self.events[opcode], self, message)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
{
|
||||
__newindex = function(self, key, value)
|
||||
if type(value) == "function" then
|
||||
self.events[key] = value
|
||||
end
|
||||
rawset(self, key, value)
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
local EventHandlerFrame = CreateFrame("Frame")
|
||||
EventHandlerFrame:RegisterEvent("CHAT_MSG_ADDON")
|
||||
EventHandlerFrame:SetScript("OnEvent", function(self, event, opcode, message, unk, sender)
|
||||
EventHandler:Handle(opcode, message, unk, sender)
|
||||
end)
|
||||
-422
@@ -1,422 +0,0 @@
|
||||
local pairs = pairs
|
||||
local ipairs = ipairs
|
||||
local next = next
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
ObjectPoolMixin = {};
|
||||
|
||||
function ObjectPoolMixin:OnLoad(creationFunc, resetterFunc)
|
||||
self.creationFunc = creationFunc;
|
||||
self.resetterFunc = resetterFunc;
|
||||
|
||||
self.activeObjects = {};
|
||||
self.inactiveObjects = {};
|
||||
|
||||
self.numActiveObjects = 0;
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:Acquire()
|
||||
local numInactiveObjects = #self.inactiveObjects;
|
||||
if numInactiveObjects > 0 then
|
||||
local obj = self.inactiveObjects[numInactiveObjects];
|
||||
self.activeObjects[obj] = true;
|
||||
self.numActiveObjects = self.numActiveObjects + 1;
|
||||
self.inactiveObjects[numInactiveObjects] = nil;
|
||||
return obj, false;
|
||||
end
|
||||
|
||||
local newObj = self.creationFunc(self);
|
||||
if self.resetterFunc and not self.disallowResetIfNew then
|
||||
self.resetterFunc(self, newObj);
|
||||
end
|
||||
self.activeObjects[newObj] = true;
|
||||
self.numActiveObjects = self.numActiveObjects + 1;
|
||||
return newObj, true;
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:Release(obj)
|
||||
if self:IsActive(obj) then
|
||||
self.inactiveObjects[#self.inactiveObjects + 1] = obj;
|
||||
self.activeObjects[obj] = nil;
|
||||
self.numActiveObjects = self.numActiveObjects - 1;
|
||||
if self.resetterFunc then
|
||||
self.resetterFunc(self, obj);
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:ReleaseAll()
|
||||
for obj in pairs(self.activeObjects) do
|
||||
self:Release(obj);
|
||||
end
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:SetResetDisallowedIfNew(disallowed)
|
||||
self.disallowResetIfNew = disallowed;
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:EnumerateActive()
|
||||
return pairs(self.activeObjects);
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:GetNextActive(current)
|
||||
return (next(self.activeObjects, current));
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:GetNextInactive(current)
|
||||
return (next(self.inactiveObjects, current));
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:IsActive(object)
|
||||
return (self.activeObjects[object] ~= nil);
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:GetNumActive()
|
||||
return self.numActiveObjects;
|
||||
end
|
||||
|
||||
function ObjectPoolMixin:EnumerateInactive()
|
||||
return ipairs(self.inactiveObjects);
|
||||
end
|
||||
|
||||
function CreateObjectPool(creationFunc, resetterFunc)
|
||||
local objectPool = CreateFromMixins(ObjectPoolMixin);
|
||||
objectPool:OnLoad(creationFunc, resetterFunc);
|
||||
return objectPool;
|
||||
end
|
||||
|
||||
FramePoolMixin = CreateFromMixins(ObjectPoolMixin);
|
||||
|
||||
local pollFrameIndex = 0
|
||||
local function FramePoolFactory(framePool)
|
||||
framePool.createdFrames = framePool.createdFrames + 1
|
||||
pollFrameIndex = pollFrameIndex + 1
|
||||
local parentName, frameName = framePool.parent and framePool.parent:GetName()
|
||||
if parentName then
|
||||
frameName = string.format("%sPoolFrame%s%i_%i", parentName, framePool.frameTemplate or "NoTemplate", framePool.createdFrames, pollFrameIndex)
|
||||
elseif framePool.frameTemplate then
|
||||
frameName = string.format("UnnamedPoolFrame%s%i_%i", framePool.frameTemplate, framePool.createdFrames, pollFrameIndex)
|
||||
else
|
||||
frameName = string.format("UnnamedPoolFrameNoTemplate%i_%i", framePool.createdFrames, pollFrameIndex)
|
||||
end
|
||||
return CreateFrame(framePool.frameType, frameName, framePool.parent, framePool.frameTemplate);
|
||||
end
|
||||
|
||||
local function ForbiddenFramePoolFactory(framePool)
|
||||
return FramePoolFactory(framePool)
|
||||
end
|
||||
|
||||
function FramePoolMixin:OnLoad(frameType, parent, frameTemplate, resetterFunc, forbidden, frameInitFunc)
|
||||
if forbidden then
|
||||
local creationFunc = ForbiddenFramePoolFactory;
|
||||
if frameInitFunc ~= nil then
|
||||
creationFunc = function(framePool)
|
||||
local frame = ForbiddenFramePoolFactory(framePool);
|
||||
frameInitFunc(frame);
|
||||
return frame;
|
||||
end
|
||||
end
|
||||
|
||||
ObjectPoolMixin.OnLoad(self, creationFunc, resetterFunc);
|
||||
else
|
||||
local creationFunc = FramePoolFactory;
|
||||
if frameInitFunc ~= nil then
|
||||
creationFunc = function(framePool)
|
||||
local frame = FramePoolFactory(framePool);
|
||||
frameInitFunc(frame);
|
||||
return frame;
|
||||
end
|
||||
end
|
||||
|
||||
ObjectPoolMixin.OnLoad(self, creationFunc, resetterFunc);
|
||||
end
|
||||
self.createdFrames = 0;
|
||||
self.frameType = frameType;
|
||||
self.parent = parent;
|
||||
self.frameTemplate = frameTemplate;
|
||||
end
|
||||
|
||||
function FramePoolMixin:GetTemplate()
|
||||
return self.frameTemplate;
|
||||
end
|
||||
|
||||
function FramePool_Hide(framePool, frame)
|
||||
frame:Hide();
|
||||
end
|
||||
|
||||
function FramePool_HideAndClearAnchors(framePool, frame)
|
||||
frame:Hide();
|
||||
frame:ClearAllPoints();
|
||||
end
|
||||
|
||||
function CreateFramePool(frameType, parent, frameTemplate, resetterFunc, forbidden, frameInitFunc)
|
||||
local framePool = CreateFromMixins(FramePoolMixin);
|
||||
framePool:OnLoad(frameType, parent, frameTemplate, resetterFunc or FramePool_HideAndClearAnchors, forbidden, frameInitFunc);
|
||||
return framePool;
|
||||
end
|
||||
|
||||
TexturePoolMixin = CreateFromMixins(ObjectPoolMixin);
|
||||
|
||||
local function TexturePoolFactory(texturePool)
|
||||
return texturePool.parent:CreateTexture(nil, texturePool.layer, texturePool.textureTemplate, texturePool.subLayer);
|
||||
end
|
||||
|
||||
function TexturePoolMixin:OnLoad(parent, layer, subLayer, textureTemplate, resetterFunc)
|
||||
ObjectPoolMixin.OnLoad(self, TexturePoolFactory, resetterFunc);
|
||||
self.parent = parent;
|
||||
self.layer = layer;
|
||||
self.subLayer = subLayer;
|
||||
self.textureTemplate = textureTemplate;
|
||||
end
|
||||
|
||||
TexturePool_Hide = FramePool_Hide;
|
||||
TexturePool_HideAndClearAnchors = FramePool_HideAndClearAnchors;
|
||||
|
||||
function CreateTexturePool(parent, layer, subLayer, textureTemplate, resetterFunc)
|
||||
local texturePool = CreateFromMixins(TexturePoolMixin);
|
||||
texturePool:OnLoad(parent, layer, subLayer, textureTemplate, resetterFunc or TexturePool_HideAndClearAnchors);
|
||||
return texturePool;
|
||||
end
|
||||
|
||||
FontStringPoolMixin = CreateFromMixins(ObjectPoolMixin);
|
||||
|
||||
local function FontStringPoolFactory(fontStringPool)
|
||||
return fontStringPool.parent:CreateFontString(nil, fontStringPool.layer, fontStringPool.fontStringTemplate, fontStringPool.subLayer);
|
||||
end
|
||||
|
||||
function FontStringPoolMixin:OnLoad(parent, layer, subLayer, fontStringTemplate, resetterFunc)
|
||||
ObjectPoolMixin.OnLoad(self, FontStringPoolFactory, resetterFunc);
|
||||
self.parent = parent;
|
||||
self.layer = layer;
|
||||
self.subLayer = subLayer;
|
||||
self.fontStringTemplate = fontStringTemplate;
|
||||
end
|
||||
|
||||
FontStringPool_Hide = FramePool_Hide;
|
||||
FontStringPool_HideAndClearAnchors = FramePool_HideAndClearAnchors;
|
||||
|
||||
function CreateFontStringPool(parent, layer, subLayer, fontStringTemplate, resetterFunc)
|
||||
local fontStringPool = CreateFromMixins(FontStringPoolMixin);
|
||||
fontStringPool:OnLoad(parent, layer, subLayer, fontStringTemplate, resetterFunc or FontStringPool_HideAndClearAnchors);
|
||||
return fontStringPool;
|
||||
end
|
||||
|
||||
ActorPoolMixin = CreateFromMixins(ObjectPoolMixin);
|
||||
|
||||
local function ActorPoolFactory(actorPool)
|
||||
return actorPool.parent:CreateActor(nil, actorPool.actorTemplate);
|
||||
end
|
||||
|
||||
function ActorPoolMixin:OnLoad(parent, actorTemplate, resetterFunc)
|
||||
ObjectPoolMixin.OnLoad(self, ActorPoolFactory, resetterFunc);
|
||||
self.parent = parent;
|
||||
self.actorTemplate = actorTemplate;
|
||||
end
|
||||
|
||||
ActorPool_Hide = FramePool_Hide;
|
||||
function ActorPool_HideAndClearModel(actorPool, actor)
|
||||
actor:ClearModel();
|
||||
actor:Hide();
|
||||
end
|
||||
|
||||
function CreateActorPool(parent, actorTemplate, resetterFunc)
|
||||
local actorPool = CreateFromMixins(ActorPoolMixin);
|
||||
actorPool:OnLoad(parent, actorTemplate, resetterFunc or ActorPool_HideAndClearModel);
|
||||
return actorPool;
|
||||
end
|
||||
|
||||
FramePoolCollectionMixin = {};
|
||||
|
||||
function CreateFramePoolCollection()
|
||||
local poolCollection = CreateFromMixins(FramePoolCollectionMixin);
|
||||
poolCollection:OnLoad();
|
||||
return poolCollection;
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:OnLoad()
|
||||
self.pools = {};
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:GetNumActive()
|
||||
local numTotalActive = 0;
|
||||
for _, pool in pairs(self.pools) do
|
||||
numTotalActive = numTotalActive + pool:GetNumActive();
|
||||
end
|
||||
return numTotalActive;
|
||||
end
|
||||
|
||||
-- Returns the pool, and whether or not the pool needed to be created.
|
||||
function FramePoolCollectionMixin:GetOrCreatePool(frameType, parent, template, resetterFunc, forbidden)
|
||||
local pool = self:GetPool(template);
|
||||
if not pool then
|
||||
return self:CreatePool(frameType, parent, template, resetterFunc, forbidden), true;
|
||||
end
|
||||
return pool, false;
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:CreatePool(frameType, parent, template, resetterFunc, forbidden, frameInitFunc)
|
||||
assert(self:GetPool(template) == nil);
|
||||
local pool = CreateFramePool(frameType, parent, template, resetterFunc, forbidden, frameInitFunc);
|
||||
self.pools[template] = pool;
|
||||
return pool;
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:GetPool(template)
|
||||
return self.pools[template];
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:Acquire(template)
|
||||
local pool = self:GetPool(template);
|
||||
assert(pool);
|
||||
return pool:Acquire();
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:Release(object)
|
||||
for _, pool in pairs(self.pools) do
|
||||
if pool:Release(object) then
|
||||
-- Found it! Just return
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
-- Huh, we didn't find that object
|
||||
assert(false);
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:ReleaseAllByTemplate(template)
|
||||
local pool = self:GetPool(template);
|
||||
if pool then
|
||||
pool:ReleaseAll();
|
||||
end
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:ReleaseAll()
|
||||
for key, pool in pairs(self.pools) do
|
||||
pool:ReleaseAll();
|
||||
end
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:EnumerateActiveByTemplate(template)
|
||||
local pool = self:GetPool(template);
|
||||
if pool then
|
||||
return pool:EnumerateActive();
|
||||
end
|
||||
|
||||
return nop;
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:EnumerateActive()
|
||||
local currentPoolKey, currentPool = next(self.pools, nil);
|
||||
local currentObject = nil;
|
||||
return function()
|
||||
if currentPool then
|
||||
currentObject = currentPool:GetNextActive(currentObject);
|
||||
while not currentObject do
|
||||
currentPoolKey, currentPool = next(self.pools, currentPoolKey);
|
||||
if currentPool then
|
||||
currentObject = currentPool:GetNextActive();
|
||||
else
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return currentObject;
|
||||
end, nil;
|
||||
end
|
||||
|
||||
function FramePoolCollectionMixin:EnumerateInactiveByTemplate(template)
|
||||
local pool = self:GetPool(template);
|
||||
if pool then
|
||||
return pool:EnumerateInactive();
|
||||
end
|
||||
|
||||
return nop;
|
||||
end
|
||||
|
||||
FixedSizeFramePoolCollectionMixin = CreateFromMixins(FramePoolCollectionMixin);
|
||||
|
||||
function CreateFixedSizeFramePoolCollection()
|
||||
local poolCollection = CreateFromMixins(FixedSizeFramePoolCollectionMixin);
|
||||
poolCollection:OnLoad();
|
||||
return poolCollection;
|
||||
end
|
||||
|
||||
function FixedSizeFramePoolCollectionMixin:OnLoad()
|
||||
FramePoolCollectionMixin.OnLoad(self);
|
||||
self.sizes = {};
|
||||
end
|
||||
|
||||
function FixedSizeFramePoolCollectionMixin:CreatePool(frameType, parent, template, resetterFunc, forbidden, maxPoolSize, preallocate)
|
||||
local pool = FramePoolCollectionMixin.CreatePool(self, frameType, parent, template, resetterFunc, forbidden);
|
||||
|
||||
if preallocate then
|
||||
for i = 1, maxPoolSize do
|
||||
pool:Acquire();
|
||||
end
|
||||
pool:ReleaseAll();
|
||||
end
|
||||
|
||||
self.sizes[template] = maxPoolSize;
|
||||
|
||||
return pool;
|
||||
end
|
||||
|
||||
function FixedSizeFramePoolCollectionMixin:Acquire(template)
|
||||
local pool = self:GetPool(template);
|
||||
assert(pool);
|
||||
|
||||
if pool:GetNumActive() < self.sizes[template] then
|
||||
return pool:Acquire();
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
|
||||
FontStringPoolCollectionMixin = CreateFromMixins(FramePoolCollectionMixin);
|
||||
|
||||
function CreateFontStringPoolCollection()
|
||||
local poolCollection = CreateFromMixins(FontStringPoolCollectionMixin);
|
||||
poolCollection:OnLoad();
|
||||
return poolCollection;
|
||||
end
|
||||
|
||||
function FontStringPoolCollectionMixin:GetOrCreatePool(parent, layer, subLayer, fontStringTemplate, resetterFunc)
|
||||
local pool = self:GetPool(fontStringTemplate);
|
||||
if not pool then
|
||||
pool = self:CreatePool(parent, layer, subLayer, fontStringTemplate, resetterFunc);
|
||||
end
|
||||
return pool;
|
||||
end
|
||||
|
||||
function FontStringPoolCollectionMixin:CreatePool(parent, layer, subLayer, fontStringTemplate, resetterFunc)
|
||||
assert(self:GetPool(fontStringTemplate) == nil);
|
||||
local pool = CreateFontStringPool(parent, layer, subLayer, fontStringTemplate, resetterFunc);
|
||||
self.pools[fontStringTemplate] = pool;
|
||||
return pool;
|
||||
end
|
||||
|
||||
function FontStringPoolCollectionMixin:CreatePoolIfNeeded(parent, layer, subLayer, fontStringTemplate, resetterFunc)
|
||||
if not self:GetPool(fontStringTemplate) then
|
||||
self:CreatePool(parent, layer, subLayer, fontStringTemplate, resetterFunc);
|
||||
end
|
||||
end
|
||||
|
||||
function FontStringPoolCollectionMixin:Acquire(fontStringTemplate, parent, layer, subLayer, resetterFunc)
|
||||
local pool = self:GetOrCreatePool(parent, layer, subLayer, fontStringTemplate, resetterFunc);
|
||||
local newString = pool:Acquire();
|
||||
|
||||
if parent then
|
||||
newString:SetParent(parent);
|
||||
end
|
||||
|
||||
if layer then
|
||||
newString:SetDrawLayer(layer, subLayer);
|
||||
end
|
||||
|
||||
return newString;
|
||||
end
|
||||
-660
@@ -1,660 +0,0 @@
|
||||
local function getObjTypeMeta(objType)
|
||||
local obj = CreateFrame(objType)
|
||||
obj:Hide()
|
||||
return getmetatable(obj).__index, obj
|
||||
end
|
||||
|
||||
local FrameMeta, FrameObj = getObjTypeMeta("Frame")
|
||||
local FontStringMeta = getmetatable(FrameObj:CreateFontString()).__index
|
||||
local TextureMeta = getmetatable(FrameObj:CreateTexture()).__index
|
||||
|
||||
local ButtonMeta = getObjTypeMeta("Button")
|
||||
local CheckButtonMeta = getObjTypeMeta("CheckButton")
|
||||
local EditBoxMeta = getObjTypeMeta("EditBox")
|
||||
local SimpleHTMLMeta = getObjTypeMeta("SimpleHTML")
|
||||
local SliderMeta = getObjTypeMeta("Slider")
|
||||
local StatusBarMeta = getObjTypeMeta("StatusBar")
|
||||
local ScrollFrameMeta = getObjTypeMeta("ScrollFrame")
|
||||
local MessageFrameMeta = getObjTypeMeta("MessageFrame")
|
||||
local ScrollingMessageFrameMeta = getObjTypeMeta("ScrollingMessageFrame")
|
||||
local ModelMeta = getObjTypeMeta("Model")
|
||||
--local ColorSelectMeta = createAndGetMeta("ColorSelect")
|
||||
--local MovieFrameMeta = createAndGetMeta("MovieFrame")
|
||||
|
||||
local AnimationGroup = FrameObj:CreateAnimationGroup()
|
||||
local AnimationGroupMeta = getmetatable(AnimationGroup).__index
|
||||
local AnimationAnimationMeta = getmetatable(AnimationGroup:CreateAnimation("Animation")).__index
|
||||
local AnimationAlphaMeta = getmetatable(AnimationGroup:CreateAnimation("Alpha")).__index
|
||||
local AnimationRotationMeta = getmetatable(AnimationGroup:CreateAnimation("Rotation")).__index
|
||||
local AnimationPathMeta = getmetatable(AnimationGroup:CreateAnimation("Path")).__index
|
||||
local AnimationScaleMeta = getmetatable(AnimationGroup:CreateAnimation("Scale")).__index
|
||||
local AnimationTranslationMeta = getmetatable(AnimationGroup:CreateAnimation("Translation")).__index
|
||||
|
||||
local GameTooltipMeta, PlayerModelMeta, DressUpModelMeta, TabardModelMeta, ModelFFXMeta
|
||||
|
||||
if IsOnGlueScreen() then
|
||||
ModelFFXMeta = getObjTypeMeta("ModelFFX")
|
||||
else
|
||||
GameTooltipMeta = getObjTypeMeta("GameTooltip")
|
||||
PlayerModelMeta = getObjTypeMeta("PlayerModel")
|
||||
DressUpModelMeta = getObjTypeMeta("DressUpModel")
|
||||
TabardModelMeta = getObjTypeMeta("TabardModel")
|
||||
|
||||
-- local CooldownMeta = createAndGetMeta("Cooldown")
|
||||
-- local MinimapMeta = createAndGetMeta("Minimap")
|
||||
-- local TaxiRouteFrameMeta = createAndGetMeta("TaxiRouteFrame")
|
||||
-- local QuestPOIFrameMeta = createAndGetMeta("QuestPOIFrame")
|
||||
-- local WorldFrameMeta = createAndGetMeta("WorldFrame")
|
||||
end
|
||||
|
||||
local function nop() end
|
||||
|
||||
local function ScriptRegion_SetShown(self, show)
|
||||
if show then
|
||||
self:Show()
|
||||
else
|
||||
self:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function ScriptRegion_GetScaledRect(self)
|
||||
local left, bottom, width, height = self:GetRect()
|
||||
if left and bottom and width and height then
|
||||
local scale = self:GetEffectiveScale()
|
||||
return left * scale, bottom * scale, width * scale, height * scale
|
||||
end
|
||||
end
|
||||
|
||||
local function ScriptRegion_IsMouseOverEx(self, ignoreVisibility, checkMouseFocus)
|
||||
if ignoreVisibility or self:IsVisible() then
|
||||
local l, r, t, b = self:GetHitRectInsets()
|
||||
return self:IsMouseOver(-t, b, l, -r) and (not checkMouseFocus or self == GetMouseFocus())
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function ScriptRegionResizing_ClearAndSetPoint(self, ...)
|
||||
self:ClearAllPoints()
|
||||
self:SetPoint(...)
|
||||
end
|
||||
|
||||
local function Region_GetEffectiveScale(self)
|
||||
return self:GetParent():GetEffectiveScale()
|
||||
end
|
||||
|
||||
local function LayoutFrame_SetParentArray(self, arrayName, element, setInSelf)
|
||||
local parent = not setInSelf and self:GetParent() or self
|
||||
|
||||
if not parent[arrayName] then
|
||||
parent[arrayName] = {}
|
||||
end
|
||||
|
||||
table.insert(parent[arrayName], element or self)
|
||||
end
|
||||
|
||||
local RegisterCustomEvent = RegisterCustomEvent
|
||||
local UnregisterCustomEvent = UnregisterCustomEvent
|
||||
|
||||
local function Frame_RegisterCustomEvent(self, event)
|
||||
RegisterCustomEvent(self, event)
|
||||
end
|
||||
|
||||
local function Frame_UnregisterCustomEvent(self, event)
|
||||
UnregisterCustomEvent(self, event)
|
||||
end
|
||||
|
||||
local function FontString_SetDesaturated(self, toggle, color)
|
||||
if toggle then
|
||||
self:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b)
|
||||
else
|
||||
if type(color) == "table" then
|
||||
self:SetTextColor(color.r, color.g, color.b)
|
||||
else
|
||||
self:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local SECONDS_PER_DAY = 86400
|
||||
local function FontString_SetRemainingTime(self, seconds, daysformat)
|
||||
if type(seconds) ~= "number" then
|
||||
self:SetText("")
|
||||
return
|
||||
end
|
||||
|
||||
if daysformat then
|
||||
if seconds >= SECONDS_PER_DAY then
|
||||
self:SetFormattedText(D_DAYS_FULL, math.floor(seconds / SECONDS_PER_DAY))
|
||||
else
|
||||
self:SetText(date("!%X", seconds))
|
||||
end
|
||||
elseif seconds >= SECONDS_PER_DAY then
|
||||
local days = string.format(DAY_ONELETTER_ABBR_SHORT, math.floor(seconds / SECONDS_PER_DAY))
|
||||
self:SetFormattedText("%s %s", days, date("!%X", seconds % SECONDS_PER_DAY))
|
||||
elseif seconds >= 0 then
|
||||
self:SetText(date("!%X", seconds))
|
||||
else
|
||||
self:SetText("")
|
||||
end
|
||||
end
|
||||
|
||||
local function Texture_SetSubTexCoord(self, left, right, top, bottom)
|
||||
local ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = self:GetTexCoord()
|
||||
|
||||
local leftedge = ULx
|
||||
local rightedge = URx
|
||||
local topedge = ULy
|
||||
local bottomedge = LLy
|
||||
|
||||
local width = rightedge - leftedge
|
||||
local height = bottomedge - topedge
|
||||
|
||||
leftedge = ULx + width * left
|
||||
topedge = ULy + height * top
|
||||
rightedge = math.max(rightedge * right, ULx)
|
||||
bottomedge = math.max(bottomedge * bottom, ULy)
|
||||
|
||||
ULx = leftedge
|
||||
ULy = topedge
|
||||
LLx = leftedge
|
||||
LLy = bottomedge
|
||||
URx = rightedge
|
||||
URy = topedge
|
||||
LRx = rightedge
|
||||
LRy = bottomedge
|
||||
|
||||
self:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
|
||||
end
|
||||
|
||||
local ATLAS_FIELD_WIDTH = 1
|
||||
local ATLAS_FIELD_HEIGHT = 2
|
||||
local ATLAS_FIELD_LEFT = 3
|
||||
local ATLAS_FIELD_RIGHT = 4
|
||||
local ATLAS_FIELD_TOP = 5
|
||||
local ATLAS_FIELD_BOTTOM = 6
|
||||
local ATLAS_FIELD_TILESHORIZ = 7
|
||||
local ATLAS_FIELD_TILESVERT = 8
|
||||
local ATLAS_FIELD_TEXTUREPATH = 9
|
||||
|
||||
local S_ATLAS_STORAGE = S_ATLAS_STORAGE
|
||||
|
||||
local function Texture_SetAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
if type(self) ~= "table" then
|
||||
error("Attempt to find 'this' in non-table object (used '.' instead of ':' ?)", 3)
|
||||
elseif type(atlasName) ~= "string" then
|
||||
error(string.format("Usage: %s:SetAtlas(\"atlasName\"[, useAtlasSize])", self:GetName() or tostring(self)), 3)
|
||||
end
|
||||
|
||||
local atlas = S_ATLAS_STORAGE[atlasName]
|
||||
if not atlas then
|
||||
error(string.format("%s:SetAtlas: Atlas %s does not exist", self:GetName() or tostring(self), atlasName), 3)
|
||||
end
|
||||
|
||||
local success = self:SetTexture(atlas[ATLAS_FIELD_TEXTUREPATH] or "", atlas[ATLAS_FIELD_TILESHORIZ], atlas[ATLAS_FIELD_TILESVERT])
|
||||
if success then
|
||||
if useAtlasSize then
|
||||
self:SetWidth(atlas[ATLAS_FIELD_WIDTH])
|
||||
self:SetHeight(atlas[ATLAS_FIELD_HEIGHT])
|
||||
end
|
||||
|
||||
self:SetTexCoord(atlas[ATLAS_FIELD_LEFT], atlas[ATLAS_FIELD_RIGHT], atlas[ATLAS_FIELD_TOP], atlas[ATLAS_FIELD_BOTTOM])
|
||||
|
||||
self:SetHorizTile(atlas[ATLAS_FIELD_TILESHORIZ])
|
||||
self:SetVertTile(atlas[ATLAS_FIELD_TILESVERT])
|
||||
end
|
||||
|
||||
return success
|
||||
end
|
||||
|
||||
local function Texture_SetPortrait(self, displayID)
|
||||
local portrait = strconcat("Interface\\PORTRAITS\\Portrait_model_", tonumber(displayID))
|
||||
local success = self:SetTexture(portrait)
|
||||
return success
|
||||
end
|
||||
|
||||
local function Button_SetEnabled(self, enabled)
|
||||
if enabled then
|
||||
self:Enable()
|
||||
else
|
||||
self:Disable()
|
||||
end
|
||||
end
|
||||
|
||||
local function Button_SetNormalAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetNormalTexture()
|
||||
if not texture then
|
||||
self:SetNormalTexture("")
|
||||
texture = self:GetNormalTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function Button_SetPushedAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetPushedTexture()
|
||||
if not texture then
|
||||
self:SetPushedTexture("")
|
||||
texture = self:GetPushedTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function Button_SetDisabledAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetDisabledTexture()
|
||||
if not texture then
|
||||
self:SetDisabledTexture("")
|
||||
texture = self:GetDisabledTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function Button_SetHighlightAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetHighlightTexture()
|
||||
if not texture then
|
||||
self:SetHighlightTexture("")
|
||||
texture = self:GetHighlightTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function Button_ClearNormalTexture(self)
|
||||
self:SetNormalTexture("")
|
||||
end
|
||||
|
||||
local function Button_ClearPushedTexture(self)
|
||||
self:SetPushedTexture("")
|
||||
end
|
||||
|
||||
local function Button_ClearDisabledTexture(self)
|
||||
self:SetDisabledTexture("")
|
||||
end
|
||||
|
||||
local function Button_ClearHighlightTexture(self)
|
||||
self:SetHighlightTexture("")
|
||||
end
|
||||
|
||||
local function CheckButton_SetCheckedAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetCheckedTexture()
|
||||
if not texture then
|
||||
self:SetCheckedTexture("")
|
||||
texture = self:GetCheckedTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function CheckButton_SetDisabledCheckedAtlas(self, atlasName, useAtlasSize, filterMode)
|
||||
local texture = self:GetDisabledCheckedTexture()
|
||||
if not texture then
|
||||
self:SetDisabledCheckedTexture("")
|
||||
texture = self:GetDisabledCheckedTexture()
|
||||
end
|
||||
Texture_SetAtlas(texture, atlasName, useAtlasSize, filterMode)
|
||||
end
|
||||
|
||||
local function CheckButton_ClearCheckedTexture(self)
|
||||
self:SetCheckedTexture("")
|
||||
end
|
||||
|
||||
local function CheckButton_ClearDisabledCheckedTexture(self)
|
||||
self:SetDisabledCheckedTexture("")
|
||||
end
|
||||
|
||||
local function EditBox_IsEnabled(self)
|
||||
return self.__ext_Disabled ~= true
|
||||
end
|
||||
|
||||
local function EditBox_Enabled(self)
|
||||
if self.__ext_mouseEnabled then
|
||||
self:EnableMouse(true)
|
||||
end
|
||||
if self.__ext_autoFocus then
|
||||
self:SetAutoFocus(true)
|
||||
self:SetFocus()
|
||||
self:HighlightText(0, 0)
|
||||
end
|
||||
self.SetFocus = nil
|
||||
self.__ext_Disabled = nil
|
||||
self.__ext_autoFocus = nil
|
||||
self.__ext_mouseEnabled = nil
|
||||
end
|
||||
|
||||
local function EditBox_Disable(self)
|
||||
if not self.__ext_Disabled then
|
||||
self.__ext_autoFocus = self:IsAutoFocus() == 1
|
||||
self.__ext_mouseEnabled = self:IsMouseEnabled() == 1
|
||||
end
|
||||
self:SetAutoFocus(false)
|
||||
self:ClearFocus()
|
||||
self:EnableMouse(false)
|
||||
self.SetFocus = nop
|
||||
self.__ext_Disabled = true
|
||||
end
|
||||
|
||||
local function PlayerModel_UpdateModelEffects(self)
|
||||
self:ResetAllSpells()
|
||||
|
||||
do -- 3D armor
|
||||
local displayIDs = self:GetDisplayIDs()
|
||||
if displayIDs then
|
||||
for index, displayID in ipairs(displayIDs) do
|
||||
if displayID ~= 0 then
|
||||
local spellID = ITEMS_WITH_3D[displayID]
|
||||
if spellID then
|
||||
self:SetSpell(spellID)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do -- customizations
|
||||
if not self.__hideCustomizations then
|
||||
local guid = self.__unitGUID
|
||||
if guid and guid == UnitGUID("player") then
|
||||
local activeCustomizationItems = C_CustomizationsCollection.GetActiveCustomizationItems(1)
|
||||
if activeCustomizationItems then
|
||||
for index, customizationItemID in ipairs(activeCustomizationItems) do
|
||||
local spellID = C_CustomizationsCollection.GetCustomizationSpellByItem(customizationItemID)
|
||||
if spellID then
|
||||
if spellID == 320799 then
|
||||
local SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS = {313589, 313590, 313591, 313592, 313593, 313594}
|
||||
spellID = SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS[math.random(1, #SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS)]
|
||||
end
|
||||
self:SetSpell(spellID)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function PlayerModel_SetUnit(self, unit, isCustomPosition, positionData)
|
||||
if type(unit) ~= "string" then
|
||||
error("Usage: SetUnit(\"unit\")", 2)
|
||||
end
|
||||
|
||||
local objectType = self:GetObjectType()
|
||||
if objectType == "PlayerModel" then
|
||||
self:SetUnitRaw(unit)
|
||||
return
|
||||
end
|
||||
|
||||
if isCustomPosition then
|
||||
if objectType == "TabardModel" then
|
||||
self:SetPosition(0, 0, 0)
|
||||
else
|
||||
self:SetPosition(1, 1, 1)
|
||||
end
|
||||
end
|
||||
|
||||
self:SetUnitRaw(unit)
|
||||
|
||||
self.__hideCustomizations = nil
|
||||
self.__unitGUID = UnitGUID(unit)
|
||||
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
|
||||
if isCustomPosition then
|
||||
local unitSex = UnitSex(unit) or 2
|
||||
local _, unitRace = UnitRace(unit)
|
||||
local positionStorage = positionData or (objectType == "TabardModel" and TABARDMODEL_CAMERA_POSITION or DRESSUPMODEL_CAMERA_POSITION)
|
||||
local data = positionStorage[string.format("%s%d", unitRace or "Human", unitSex)]
|
||||
|
||||
if data then
|
||||
local positionX, positionY, positionZ, facing = unpack(data, 1, 4)
|
||||
self.basePositionOverrideX = positionX
|
||||
self.basePositionOverrideY = positionY
|
||||
self.basePositionOverrideZ = positionZ
|
||||
self.basePositionOverrideXasZ = true
|
||||
self:SetPosition(positionX or 0, positionY or 0, positionZ or 0)
|
||||
|
||||
if facing then
|
||||
self:SetFacing(math.rad(facing))
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.basePositionOverrideX = nil
|
||||
self.basePositionOverrideY = nil
|
||||
self.basePositionOverrideZ = nil
|
||||
self.basePositionOverrideXasZ = nil
|
||||
end
|
||||
|
||||
local function PlayerModel_RefreshUnit(self)
|
||||
self:RefreshUnitRaw()
|
||||
|
||||
local objectType = self:GetObjectType()
|
||||
if objectType == "DressUpModel" or objectType == "TabardModel" then
|
||||
self.__hideCustomizations = nil
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function DressUpModel_Dress(self)
|
||||
self:DressRaw()
|
||||
self.__hideCustomizations = nil
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
end
|
||||
|
||||
local function DressUpModel_Undress(self)
|
||||
self:UndressRaw()
|
||||
self.__hideCustomizations = true
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
end
|
||||
|
||||
local function DressUpModel_TryOn(self, item)
|
||||
if C_CustomizationsCollection.CanPreviewCustomizationInDressUp(item) then
|
||||
local spellID, category, subcategory = C_CustomizationsCollection.GetCustomizationSpellByItem(item)
|
||||
if spellID then
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
|
||||
for index, activeSpellID in ipairs({self:GetAllSpells()}) do
|
||||
local isCustomizationSpell, activeSpellCategory, activeSpellSubCategory = C_CustomizationsCollection.IsCustomizationSpell(activeSpellID)
|
||||
if isCustomizationSpell and category == activeSpellCategory and subcategory == activeSpellSubCategory then
|
||||
self:ResetSpell(activeSpellID)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if spellID == 320799 then
|
||||
local SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS = {313589, 313590, 313591, 313592, 313593, 313594}
|
||||
spellID = SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS[math.random(1, #SPELL_EFFECTS_GIFT_OF_MOST_PRECIOUS)]
|
||||
end
|
||||
|
||||
self:SetSpell(spellID)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
self:TryOnRaw(item)
|
||||
PlayerModel_UpdateModelEffects(self)
|
||||
end
|
||||
|
||||
local function Animation_Restart(self)
|
||||
if self:IsPlaying() then
|
||||
self:Stop()
|
||||
end
|
||||
self:Play()
|
||||
end
|
||||
|
||||
FrameMeta.SetShown = ScriptRegion_SetShown
|
||||
FrameMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
FrameMeta.IsMouseOverEx = ScriptRegion_IsMouseOverEx
|
||||
FrameMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
FrameMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
FrameMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
FrameMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
FontStringMeta.SetShown = ScriptRegion_SetShown
|
||||
FontStringMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
FontStringMeta.GetEffectiveScale = Region_GetEffectiveScale
|
||||
FontStringMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
FontStringMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
FontStringMeta.SetDesaturated = FontString_SetDesaturated
|
||||
FontStringMeta.SetRemainingTime = FontString_SetRemainingTime
|
||||
|
||||
TextureMeta.SetShown = ScriptRegion_SetShown
|
||||
TextureMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
TextureMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
TextureMeta.GetEffectiveScale = Region_GetEffectiveScale
|
||||
TextureMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
TextureMeta.SetSubTexCoord = Texture_SetSubTexCoord
|
||||
TextureMeta.SetAtlas = Texture_SetAtlas
|
||||
TextureMeta.SetPortrait = Texture_SetPortrait
|
||||
|
||||
ButtonMeta.SetShown = ScriptRegion_SetShown
|
||||
ButtonMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
ButtonMeta.IsMouseOverEx = ScriptRegion_IsMouseOverEx
|
||||
ButtonMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
ButtonMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
ButtonMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
ButtonMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
ButtonMeta.SetEnabled = Button_SetEnabled
|
||||
ButtonMeta.SetNormalAtlas = Button_SetNormalAtlas
|
||||
ButtonMeta.SetPushedAtlas = Button_SetPushedAtlas
|
||||
ButtonMeta.SetDisabledAtlas = Button_SetDisabledAtlas
|
||||
ButtonMeta.SetHighlightAtlas = Button_SetHighlightAtlas
|
||||
ButtonMeta.ClearClearNormalTexture = Button_ClearNormalTexture
|
||||
ButtonMeta.ClearPushedTexture = Button_ClearPushedTexture
|
||||
ButtonMeta.ClearDisabledTexture = Button_ClearDisabledTexture
|
||||
ButtonMeta.ClearHighlightTexture = Button_ClearHighlightTexture
|
||||
|
||||
CheckButtonMeta.SetShown = ScriptRegion_SetShown
|
||||
CheckButtonMeta.IsMouseOverEx = ScriptRegion_IsMouseOverEx
|
||||
CheckButtonMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
CheckButtonMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
CheckButtonMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
CheckButtonMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
CheckButtonMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
CheckButtonMeta.SetEnabled = Button_SetEnabled
|
||||
CheckButtonMeta.SetNormalAtlas = Button_SetNormalAtlas
|
||||
CheckButtonMeta.SetPushedAtlas = Button_SetPushedAtlas
|
||||
CheckButtonMeta.SetDisabledAtlas = Button_SetDisabledAtlas
|
||||
CheckButtonMeta.SetHighlightAtlas = Button_SetHighlightAtlas
|
||||
CheckButtonMeta.SetCheckedAtlas = CheckButton_SetCheckedAtlas
|
||||
CheckButtonMeta.SetDisabledCheckedAtlas = CheckButton_SetDisabledCheckedAtlas
|
||||
CheckButtonMeta.ClearClearNormalTexture = Button_ClearNormalTexture
|
||||
CheckButtonMeta.ClearPushedTexture = Button_ClearPushedTexture
|
||||
CheckButtonMeta.ClearDisabledTexture = Button_ClearDisabledTexture
|
||||
CheckButtonMeta.ClearHighlightTexture = Button_ClearHighlightTexture
|
||||
CheckButtonMeta.ClearDisabledCheckedTexture = CheckButton_ClearCheckedTexture
|
||||
CheckButtonMeta.ClearDisabledCheckedTexture = CheckButton_ClearDisabledCheckedTexture
|
||||
|
||||
EditBoxMeta.SetShown = ScriptRegion_SetShown
|
||||
EditBoxMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
EditBoxMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
EditBoxMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
EditBoxMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
EditBoxMeta.SetEnabled = Button_SetEnabled
|
||||
EditBoxMeta.IsEnabled = EditBox_IsEnabled
|
||||
EditBoxMeta.Enable = EditBox_Enabled
|
||||
EditBoxMeta.Disable = EditBox_Disable
|
||||
|
||||
SimpleHTMLMeta.SetShown = ScriptRegion_SetShown
|
||||
SimpleHTMLMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
SimpleHTMLMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
SimpleHTMLMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
SimpleHTMLMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
SimpleHTMLMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
SliderMeta.SetShown = ScriptRegion_SetShown
|
||||
SliderMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
SliderMeta.IsMouseOverEx = ScriptRegion_IsMouseOverEx
|
||||
SliderMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
SliderMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
SliderMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
SliderMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
SliderMeta.SetEnabled = Button_SetEnabled
|
||||
|
||||
StatusBarMeta.SetShown = ScriptRegion_SetShown
|
||||
StatusBarMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
StatusBarMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
StatusBarMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
StatusBarMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
StatusBarMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
ScrollFrameMeta.SetShown = ScriptRegion_SetShown
|
||||
ScrollFrameMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
ScrollFrameMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
ScrollFrameMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
ScrollFrameMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
ScrollFrameMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
MessageFrameMeta.SetShown = ScriptRegion_SetShown
|
||||
MessageFrameMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
MessageFrameMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
MessageFrameMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
MessageFrameMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
MessageFrameMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
ScrollingMessageFrameMeta.SetShown = ScriptRegion_SetShown
|
||||
ScrollingMessageFrameMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
ScrollingMessageFrameMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
ScrollingMessageFrameMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
ScrollingMessageFrameMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
ScrollingMessageFrameMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
ModelMeta.SetShown = ScriptRegion_SetShown
|
||||
ModelMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
ModelMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
ModelMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
ModelMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
AnimationGroupMeta.Restart = Animation_Restart
|
||||
AnimationAnimationMeta.Restart = Animation_Restart
|
||||
AnimationAlphaMeta.Restart = Animation_Restart
|
||||
AnimationRotationMeta.Restart = Animation_Restart
|
||||
AnimationPathMeta.Restart = Animation_Restart
|
||||
AnimationScaleMeta.Restart = Animation_Restart
|
||||
AnimationTranslationMeta.Restart = Animation_Restart
|
||||
|
||||
if IsOnGlueScreen() then
|
||||
ModelFFXMeta.SetShown = ScriptRegion_SetShown
|
||||
ModelFFXMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
ModelFFXMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
else
|
||||
GameTooltipMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
GameTooltipMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
GameTooltipMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
|
||||
PlayerModelMeta.SetShown = ScriptRegion_SetShown
|
||||
PlayerModelMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
PlayerModelMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
PlayerModelMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
PlayerModelMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
PlayerModelMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
PlayerModelMeta.SetUnitRaw = PlayerModelMeta.SetUnit
|
||||
PlayerModelMeta.SetUnit = PlayerModel_SetUnit
|
||||
PlayerModelMeta.RefreshUnitRaw = PlayerModelMeta.RefreshUnit
|
||||
PlayerModelMeta.RefreshUnit = PlayerModel_RefreshUnit
|
||||
|
||||
DressUpModelMeta.SetShown = ScriptRegion_SetShown
|
||||
DressUpModelMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
DressUpModelMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
DressUpModelMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
DressUpModelMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
DressUpModelMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
DressUpModelMeta.SetUnitRaw = DressUpModelMeta.SetUnit
|
||||
DressUpModelMeta.SetUnit = PlayerModel_SetUnit
|
||||
DressUpModelMeta.RefreshUnitRaw = DressUpModelMeta.RefreshUnit
|
||||
DressUpModelMeta.RefreshUnit = PlayerModel_RefreshUnit
|
||||
DressUpModelMeta.TryOnRaw = DressUpModelMeta.TryOn
|
||||
DressUpModelMeta.TryOn = DressUpModel_TryOn
|
||||
DressUpModelMeta.DressRaw = DressUpModelMeta.Dress
|
||||
DressUpModelMeta.Dress = DressUpModel_Dress
|
||||
DressUpModelMeta.UndressRaw = DressUpModelMeta.Undress
|
||||
DressUpModelMeta.Undress = DressUpModel_Undress
|
||||
|
||||
TabardModelMeta.SetShown = ScriptRegion_SetShown
|
||||
TabardModelMeta.GetScaledRect = ScriptRegion_GetScaledRect
|
||||
TabardModelMeta.ClearAndSetPoint = ScriptRegionResizing_ClearAndSetPoint
|
||||
TabardModelMeta.SetParentArray = LayoutFrame_SetParentArray
|
||||
TabardModelMeta.RegisterCustomEvent = Frame_RegisterCustomEvent
|
||||
TabardModelMeta.UnregisterCustomEvent = Frame_UnregisterCustomEvent
|
||||
TabardModelMeta.SetUnitRaw = TabardModelMeta.SetUnit
|
||||
TabardModelMeta.SetUnit = PlayerModel_SetUnit
|
||||
TabardModelMeta.RefreshUnitRaw = TabardModelMeta.RefreshUnit
|
||||
TabardModelMeta.RefreshUnit = PlayerModel_RefreshUnit
|
||||
TabardModelMeta.SetSpell = function() end
|
||||
end
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
local function SetupTextFont(fontString, fontObject)
|
||||
if fontString and fontObject then
|
||||
fontString:SetFontObject(fontObject);
|
||||
end
|
||||
end
|
||||
|
||||
function SharedTooltip_OnLoad(self)
|
||||
local style = nil;
|
||||
local isEmbedded = false;
|
||||
SharedTooltip_SetBackdropStyle(self, style, isEmbedded);
|
||||
self:SetClampRectInsets(0, 0, 15, 0);
|
||||
|
||||
SetupTextFont(self.TextLeft1, self.textLeft1Font);
|
||||
SetupTextFont(self.TextRight1, self.textRight1Font);
|
||||
SetupTextFont(self.TextLeft2, self.textLeft2Font);
|
||||
SetupTextFont(self.TextRight2, self.textRight2Font);
|
||||
end
|
||||
|
||||
function SharedTooltip_OnHide(self)
|
||||
self:SetPadding(0, 0, 0, 0);
|
||||
end
|
||||
|
||||
local DEFAULT_TOOLTIP_OFFSET_X = -17;
|
||||
local DEFAULT_TOOLTIP_OFFSET_Y = 70;
|
||||
|
||||
function SharedTooltip_SetDefaultAnchor(tooltip, parent)
|
||||
tooltip:SetOwner(parent or GetAppropriateTopLevelParent(), "ANCHOR_NONE");
|
||||
tooltip:SetPoint("BOTTOMRIGHT", GetAppropriateTopLevelParent(), "BOTTOMRIGHT", DEFAULT_TOOLTIP_OFFSET_X, DEFAULT_TOOLTIP_OFFSET_Y);
|
||||
end
|
||||
|
||||
function SharedTooltip_ClearInsertedFrames(self)
|
||||
if self.insertedFrames then
|
||||
for i = 1, #self.insertedFrames do
|
||||
self.insertedFrames[i]:Hide();
|
||||
end
|
||||
end
|
||||
self.insertedFrames = nil;
|
||||
end
|
||||
|
||||
function SharedTooltip_SetBackdropStyle(self, style, embedded)
|
||||
if embedded or self.IsEmbedded then
|
||||
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 0)
|
||||
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b, 0);
|
||||
else
|
||||
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 1);
|
||||
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b, 1);
|
||||
end
|
||||
|
||||
if self.TopOverlay then
|
||||
if style and style.overlayAtlasTop then
|
||||
self.TopOverlay:SetAtlas(style.overlayAtlasTop, true);
|
||||
self.TopOverlay:SetScale(style.overlayAtlasTopScale or 1.0);
|
||||
self.TopOverlay:SetPoint("CENTER", self, "TOP", style.overlayAtlasTopXOffset or 0, style.overlayAtlasTopYOffset or 0);
|
||||
self.TopOverlay:Show();
|
||||
else
|
||||
self.TopOverlay:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
if self.BottomOverlay then
|
||||
if style and style.overlayAtlasBottom then
|
||||
self.BottomOverlay:SetAtlas(style.overlayAtlasBottom, true);
|
||||
self.BottomOverlay:SetScale(style.overlayAtlasBottomScale or 1.0);
|
||||
self.BottomOverlay:SetPoint("CENTER", self, "BOTTOM", style.overlayAtlasBottomXOffset or 0, style.overlayAtlasBottomYOffset or 0);
|
||||
self.BottomOverlay:Show();
|
||||
else
|
||||
self.BottomOverlay:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
if style and style.padding then
|
||||
self:SetPadding(style.padding.right, style.padding.bottom, style.padding.left, style.padding.top);
|
||||
end
|
||||
end
|
||||
|
||||
function GameTooltip_AddBlankLinesToTooltip(tooltip, numLines)
|
||||
if numLines ~= nil then
|
||||
for i = 1, numLines do
|
||||
tooltip:AddLine(" ");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GameTooltip_AddBlankLineToTooltip(tooltip)
|
||||
GameTooltip_AddBlankLinesToTooltip(tooltip, 1);
|
||||
end
|
||||
|
||||
function GameTooltip_SetTitle(tooltip, text, overrideColor, wrap)
|
||||
local titleColor = overrideColor or HIGHLIGHT_FONT_COLOR;
|
||||
local r, g, b, a = titleColor:GetRGBA();
|
||||
if wrap == nil then
|
||||
wrap = 1;
|
||||
end
|
||||
tooltip:SetText(text, r, g, b, a, wrap);
|
||||
end
|
||||
|
||||
function GameTooltip_ShowDisabledTooltip(tooltip, owner, text, tooltipAnchor)
|
||||
tooltip:SetOwner(owner, tooltipAnchor);
|
||||
|
||||
local wrap = 1;
|
||||
GameTooltip_SetTitle(tooltip, text, RED_FONT_COLOR, wrap);
|
||||
|
||||
tooltip:Show();
|
||||
end
|
||||
|
||||
function GameTooltip_AddNormalLine(tooltip, text, wrap, leftOffset)
|
||||
GameTooltip_AddColoredLine(tooltip, text, NORMAL_FONT_COLOR, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddHighlightLine(tooltip, text, wrap, leftOffset)
|
||||
GameTooltip_AddColoredLine(tooltip, text, HIGHLIGHT_FONT_COLOR, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddInstructionLine(tooltip, text, wrap, leftOffset)
|
||||
GameTooltip_AddColoredLine(tooltip, text, GREEN_FONT_COLOR, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddErrorLine(tooltip, text, wrap, leftOffset)
|
||||
GameTooltip_AddColoredLine(tooltip, text, RED_FONT_COLOR, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddDisabledLine(tooltip, text, wrap, leftOffset)
|
||||
GameTooltip_AddColoredLine(tooltip, text, DISABLED_FONT_COLOR, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddColoredLine(tooltip, text, color, wrap, leftOffset)
|
||||
local r, g, b = color:GetRGB();
|
||||
if wrap == nil then
|
||||
wrap = 1;
|
||||
end
|
||||
tooltip:AddLine(text, r, g, b, wrap, leftOffset);
|
||||
end
|
||||
|
||||
function GameTooltip_AddColoredDoubleLine(tooltip, leftText, rightText, leftColor, rightColor, wrap)
|
||||
local leftR, leftG, leftB = leftColor:GetRGB();
|
||||
local rightR, rightG, rightB = rightColor:GetRGB();
|
||||
if wrap == nil then
|
||||
wrap = 1;
|
||||
end
|
||||
tooltip:AddDoubleLine(leftText, rightText, leftR, leftG, leftB, rightR, rightG, rightB, wrap);
|
||||
end
|
||||
|
||||
function GameTooltip_InsertFrame(tooltipFrame, frame, verticalPadding)
|
||||
verticalPadding = verticalPadding or 0;
|
||||
|
||||
local textSpacing = 2;
|
||||
local textHeight = Round(_G[tooltipFrame:GetName().."TextLeft2"]:GetLineHeight());
|
||||
local neededHeight = Round(frame:GetHeight() + verticalPadding);
|
||||
local numLinesNeeded = math.ceil(neededHeight / (textHeight + textSpacing));
|
||||
local currentLine = tooltipFrame:NumLines();
|
||||
GameTooltip_AddBlankLinesToTooltip(tooltipFrame, numLinesNeeded);
|
||||
frame:SetParent(tooltipFrame);
|
||||
frame:ClearAllPoints();
|
||||
frame:SetPoint("TOPLEFT", tooltipFrame:GetName().."TextLeft"..(currentLine + 1), "TOPLEFT", 0, -verticalPadding);
|
||||
if not tooltipFrame.insertedFrames then
|
||||
tooltipFrame.insertedFrames = { };
|
||||
end
|
||||
local frameWidth = frame:GetWidth();
|
||||
if tooltipFrame:GetMinimumWidth() < frameWidth then
|
||||
tooltipFrame:SetMinimumWidth(frameWidth);
|
||||
end
|
||||
frame:Show();
|
||||
tinsert(tooltipFrame.insertedFrames, frame);
|
||||
-- return space taken so inserted frame can resize if needed
|
||||
return (numLinesNeeded * textHeight) + (numLinesNeeded - 1) * textSpacing;
|
||||
end
|
||||
|
||||
DisabledTooltipButtonMixin = {};
|
||||
|
||||
function DisabledTooltipButtonMixin:OnEnter()
|
||||
if not self:IsEnabled() then
|
||||
local disabledTooltip, disabledTooltipAnchor = self:GetDisabledTooltip();
|
||||
if disabledTooltip ~= nil then
|
||||
GameTooltip_ShowDisabledTooltip(GetAppropriateTooltip(), self, disabledTooltip, disabledTooltipAnchor);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DisabledTooltipButtonMixin:OnLeave()
|
||||
local tooltip = GetAppropriateTooltip();
|
||||
tooltip:Hide();
|
||||
end
|
||||
|
||||
function DisabledTooltipButtonMixin:SetDisabledTooltip(disabledTooltip, disabledTooltipAnchor)
|
||||
self.disabledTooltip = disabledTooltip;
|
||||
self.disabledTooltipAnchor = disabledTooltipAnchor;
|
||||
end
|
||||
|
||||
function DisabledTooltipButtonMixin:GetDisabledTooltip()
|
||||
return self.disabledTooltip, self.disabledTooltipAnchor;
|
||||
end
|
||||
|
||||
function DisabledTooltipButtonMixin:SetDisabledState(disabled, disabledTooltip, disabledTooltipAnchor)
|
||||
self:SetEnabled(not disabled);
|
||||
self:SetDisabledTooltip(disabledTooltip, disabledTooltipAnchor);
|
||||
end
|
||||
-191
@@ -1,191 +0,0 @@
|
||||
<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/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="SharedTooltipTemplates.lua"/>
|
||||
|
||||
<FontString name="TooltipTextLeftTemplate" inherits="GameTooltipText" justifyH="LEFT" hidden="true" virtual="true"/>
|
||||
<FontString name="TooltipTextRightTemplate" inherits="GameTooltipText" justifyH="RIGHT" hidden="true" virtual="true"/>
|
||||
|
||||
<Texture name="TooltipTextureTemplate" hidden="true" virtual="true">
|
||||
<Size x="12" y="12"/>
|
||||
</Texture>
|
||||
|
||||
<GameTooltip name="SharedTooltipTemplate" clampedToScreen="true" frameStrata="TOOLTIP" hidden="true" virtual="true">
|
||||
<Attributes>
|
||||
<Attribute name="textLeft1Font" value="GameTooltipHeaderText" type="string"/>
|
||||
<Attribute name="textRight1Font" value="GameTooltipHeaderText" type="string"/>
|
||||
<Attribute name="textLeft2Font" value="GameTooltipText" type="string"/>
|
||||
<Attribute name="textRight2Font" value="GameTooltipText" type="string"/>
|
||||
<Attribute name="layoutType" value="TooltipDefaultLayout" type="string"/>
|
||||
</Attributes>
|
||||
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||
<EdgeSize>
|
||||
<AbsValue val="16"/>
|
||||
</EdgeSize>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="5" right="5" top="5" bottom="5"/>
|
||||
</BackgroundInsets>
|
||||
</Backdrop>
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture parentKey="TopOverlay" hidden="true">
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativePoint="TOP" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BottomOverlay" hidden="true">
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativePoint="BOTTOM" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentTextLeft1" parentKey="TextLeft1" inherits="TooltipTextLeftTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="10" y="-10"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentTextRight1" parentKey="TextRight1" inherits="TooltipTextRightTemplate" justifyH="LEFT">
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativeTo="$parentTextLeft1" relativePoint="LEFT" x="40" y="0"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentTextLeft2" parentKey="TextLeft2" inherits="TooltipTextLeftTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTextLeft1" relativePoint="BOTTOMLEFT" x="0" y="-2"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentTextRight2" parentKey="TextRight2" inherits="TooltipTextRightTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativeTo="$parentTextLeft2" relativePoint="LEFT" x="40" y="0"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<Texture name="$parentTexture1" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture2" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture3" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture4" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture5" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture6" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture7" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture8" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture9" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture10" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture11" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture12" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture13" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture14" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture15" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture16" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture17" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture18" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture19" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture20" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture21" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture22" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture23" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture24" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture25" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture26" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture27" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture28" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture29" inherits="TooltipTextureTemplate"/>
|
||||
<Texture name="$parentTexture30" inherits="TooltipTextureTemplate"/>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad function="SharedTooltip_OnLoad"/>
|
||||
<OnHide function="SharedTooltip_OnHide"/>
|
||||
<OnTooltipSetDefaultAnchor function="SharedTooltip_SetDefaultAnchor"/>
|
||||
<OnTooltipCleared function="SharedTooltip_ClearInsertedFrames"/>
|
||||
</Scripts>
|
||||
</GameTooltip>
|
||||
|
||||
<GameTooltip name="SharedNoHeaderTooltipTemplate" inherits="SharedTooltipTemplate" virtual="true">
|
||||
<Attributes>
|
||||
<Attribute name="textLeft1Font" value="GameTooltipText" type="string"/>
|
||||
<Attribute name="textRight1Font" value="GameTooltipText" type="string"/>
|
||||
</Attributes>
|
||||
</GameTooltip>
|
||||
|
||||
<Frame name="TooltipBorderedFrameTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture parentKey="BorderTopLeft" name="$parentBorderTopLeft" file="Interface\Tooltips\UI-Tooltip-TL">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderTopRight" name="$parentBorderTopRight" file="Interface\Tooltips\UI-Tooltip-TR">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottomRight" name="$parentBorderBottomRight" file="Interface\Tooltips\UI-Tooltip-BR">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottomLeft" name="$parentBorderBottomLeft" file="Interface\Tooltips\UI-Tooltip-BL">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderTop" file="Interface\Tooltips\UI-Tooltip-T">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorderTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentBorderTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderRight" file="Interface\Tooltips\UI-Tooltip-R">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentBorderTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorderBottomRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottom" file="Interface\Tooltips\UI-Tooltip-B">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBorderBottomLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorderBottomRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderLeft" file="Interface\Tooltips\UI-Tooltip-L">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorderTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBorderBottomLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorderTopLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorderBottomRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<Color r="0" g="0" b="0" a="0.8"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
|
||||
<Button name="DisabledTooltipButtonTemplate" motionScriptsWhileDisabled="true" virtual="true">
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Mixin(self, DisabledTooltipButtonMixin)
|
||||
</OnLoad>
|
||||
<OnEnter>
|
||||
self:OnEnter()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
self:OnLeave()
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Ui>
|
||||
-4548
File diff suppressed because it is too large
Load Diff
-2128
File diff suppressed because it is too large
Load Diff
-499
@@ -1,499 +0,0 @@
|
||||
local ColumnWidthConstraints = {
|
||||
Fill = 1, -- Width will be distributed by available space.
|
||||
Fixed = 2, -- Width is specified when initializing the column.
|
||||
};
|
||||
|
||||
-- Any row or cell is expected to initialize itself in terms of the row data. The dataIndex is provided
|
||||
-- in case the derived mixin needs to make additional CAPI calls involving it's relative index. The row
|
||||
-- data may also be needed for a tooltip, so it will be assigned to the row and cells on update.
|
||||
TableBuilderElementMixin = {};
|
||||
|
||||
--Derive
|
||||
function TableBuilderElementMixin:Init(...)
|
||||
end
|
||||
|
||||
--Derive
|
||||
function TableBuilderElementMixin:Populate(rowData, dataIndex)
|
||||
end
|
||||
|
||||
TableBuilderCellMixin = CreateFromMixins(TableBuilderElementMixin);
|
||||
|
||||
--Derive
|
||||
function TableBuilderCellMixin:OnLineEnter()
|
||||
end
|
||||
|
||||
--Derive
|
||||
function TableBuilderCellMixin:OnLineLeave()
|
||||
end
|
||||
|
||||
|
||||
TableBuilderRowMixin = CreateFromMixins(TableBuilderElementMixin);
|
||||
|
||||
--Derive
|
||||
function TableBuilderRowMixin:OnLineEnter()
|
||||
end
|
||||
|
||||
--Derive
|
||||
function TableBuilderRowMixin:OnLineLeave()
|
||||
end
|
||||
|
||||
|
||||
function TableBuilderRowMixin:OnEnter()
|
||||
self:OnLineEnter();
|
||||
for i, cell in ipairs(self.cells) do
|
||||
cell:OnLineEnter();
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderRowMixin:OnLeave()
|
||||
self:OnLineLeave();
|
||||
for i, cell in ipairs(self.cells) do
|
||||
cell:OnLineLeave();
|
||||
end
|
||||
end
|
||||
|
||||
-- Defines an entire column within the table builder, by default a column's sizing constraints are set to fill.
|
||||
TableBuilderColumnMixin = {};
|
||||
function TableBuilderColumnMixin:Init(table)
|
||||
self.cells = {};
|
||||
self.table = table;
|
||||
|
||||
local fillCoefficient = 1.0;
|
||||
local padding = 0;
|
||||
self:SetFillConstraints(fillCoefficient, padding);
|
||||
end
|
||||
|
||||
-- Constructs the header frame with an optional initializer.
|
||||
function TableBuilderColumnMixin:ConstructHeader(templateType, template, ...)
|
||||
local frame = self.table:ConstructHeader(templateType, template);
|
||||
self.headerFrame = frame;
|
||||
if frame.Init then
|
||||
frame:Init(...);
|
||||
end
|
||||
frame:Show();
|
||||
end
|
||||
|
||||
-- Constructs cells corresponding to each row with an optional initializer.
|
||||
function TableBuilderColumnMixin:ConstructCells(templateType, template, ...)
|
||||
local cells = self.table:ConstructCells(templateType, template);
|
||||
self.cells = cells;
|
||||
for k, cell in pairs(cells) do
|
||||
if cell.Init then
|
||||
cell:Init(...);
|
||||
end
|
||||
cell:Show();
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetCellByRowIndex(rowIndex)
|
||||
return self.cells[rowIndex];
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetFillCoefficient()
|
||||
return self.fillCoefficient;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetFillCoefficient(fillCoefficient)
|
||||
self.fillCoefficient = fillCoefficient;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetPadding()
|
||||
return self.padding;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetPadding(padding)
|
||||
self.padding = padding;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetCellPadding()
|
||||
return self.leftCellPadding or 0, self.rightCellPadding or 0;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetCellPadding(leftCellPadding, rightCellPadding)
|
||||
self.leftCellPadding = leftCellPadding;
|
||||
self.rightCellPadding = rightCellPadding;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetHeaderFrame()
|
||||
return self.headerFrame;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetHeaderFrame(headerFrame)
|
||||
self.headerFrame = headerFrame;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetWidthConstraints()
|
||||
return self.widthConstraints;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetFixedWidth()
|
||||
return self.fixedWidth;
|
||||
end
|
||||
|
||||
-- A header frame for the column is expected to be constructed or assigned prior to calling this.
|
||||
-- See ConstructHeader() or SetHeaderFrame().
|
||||
function TableBuilderColumnMixin:ConstrainToHeader(padding)
|
||||
local header = self:GetHeaderFrame();
|
||||
assert(header, "ConstrainToHeader() called with a nil header frame. Use ConstructHeader() or assign one with SetHeaderFrame(), or use SetFixedConstraints to have a headerless column.");
|
||||
self:SetFixedConstraints(header:GetWidth(), padding or 0);
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetFixedConstraints(fixedWidth, padding)
|
||||
self.widthConstraints = ColumnWidthConstraints.Fixed;
|
||||
self.fixedWidth = fixedWidth;
|
||||
self:SetFillCoefficient(0);
|
||||
self:SetPadding(padding or 0);
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetFillConstraints(fillCoefficient, padding)
|
||||
self.widthConstraints = ColumnWidthConstraints.Fill;
|
||||
self.fixedWidth = 0;
|
||||
self:SetFillCoefficient(fillCoefficient);
|
||||
self:SetPadding(padding or 0);
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetCalculatedWidth(calculatedWidth)
|
||||
self.calculatedWidth = calculatedWidth;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetCalculatedWidth()
|
||||
return self.calculatedWidth;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetCellWidth()
|
||||
local leftCellPadding, rightCellPadding = self:GetCellPadding();
|
||||
return (self.calculatedWidth - leftCellPadding) - rightCellPadding;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetFullWidth()
|
||||
return self:GetCalculatedWidth() + self:GetPadding();
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:SetDisplayUnderPreviousHeader(displayUnderPreviousHeader)
|
||||
self.displayUnderPreviousHeader = displayUnderPreviousHeader;
|
||||
end
|
||||
|
||||
function TableBuilderColumnMixin:GetDisplayUnderPreviousHeader()
|
||||
return self.displayUnderPreviousHeader;
|
||||
end
|
||||
|
||||
-- Constructs a table of frames within an existing set of row frames. These row frames could originate from
|
||||
-- a hybrid scroll frame or statically fixed set. To populate the table, assign a data provider (CAPI or lua function)
|
||||
-- that can retrieve an object by index (number).
|
||||
TableBuilderMixin = {};
|
||||
function TableBuilderMixin:Init(rows)
|
||||
self.columns = {};
|
||||
self.leftMargin = 0;
|
||||
self.rightMargin = 0;
|
||||
self.columnHeaderOverlap = 0;
|
||||
self.tableWidth = 0;
|
||||
self.headerPoolCollection = CreateFramePoolCollection();
|
||||
self:SetRows(rows);
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetDataProvider()
|
||||
return self.dataProvider;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:SetDataProvider(dataProvider)
|
||||
self.dataProvider = dataProvider;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetDataProviderData(dataIndex)
|
||||
local dataProvider = self:GetDataProvider();
|
||||
return dataProvider and dataProvider(dataIndex) or nil;
|
||||
end
|
||||
|
||||
-- Controls the margins of the left-most and right-most columns within the table.
|
||||
function TableBuilderMixin:SetTableMargins(leftMargin, rightMargin)
|
||||
rightMargin = rightMargin or leftMargin; -- Use leftMargin as the default for both.
|
||||
self.leftMargin = leftMargin;
|
||||
self.rightMargin = rightMargin;
|
||||
end
|
||||
|
||||
-- Column headers overlap to make a consistent display.
|
||||
function TableBuilderMixin:SetColumnHeaderOverlap(columnHeaderOverlap)
|
||||
self.columnHeaderOverlap = columnHeaderOverlap;
|
||||
end
|
||||
|
||||
-- Can be used to set the table width, particularly if no header frames are involved.
|
||||
function TableBuilderMixin:SetTableWidth(tableWidth)
|
||||
self.tableWidth = tableWidth;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetTableWidth()
|
||||
return self.tableWidth;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetTableMargins()
|
||||
return self.leftMargin, self.rightMargin;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetColumnHeaderOverlap()
|
||||
return self.columnHeaderOverlap;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetColumns()
|
||||
return self.columns;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetHeaderContainer()
|
||||
return self.headerContainer;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:SetHeaderContainer(headerContainer)
|
||||
assert(headerContainer, "SetHeaderContainer() with a nil header container. Use ConstructHeader() or assign one with SetHeaderFrame(), or use SetFixedConstraints to have a headerless column.");
|
||||
self.headerContainer = headerContainer;
|
||||
self:SetTableWidth(headerContainer:GetWidth());
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ReleaseRowPools()
|
||||
local rows = self.rows;
|
||||
if rows then
|
||||
for k, row in pairs(rows) do
|
||||
local poolCollection = row.poolCollection;
|
||||
if poolCollection then
|
||||
poolCollection:ReleaseAll();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:SetRows(rows)
|
||||
-- Release any previous rows, though I can't imagine a case where the rows
|
||||
-- are being exchanged.
|
||||
self:ReleaseRowPools();
|
||||
|
||||
self.rows = rows;
|
||||
for k, row in pairs(rows) do
|
||||
if not row.poolCollection then
|
||||
row.poolCollection = CreateFramePoolCollection();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetHeaderPoolCollection()
|
||||
return self.headerPoolCollection;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetRows()
|
||||
return self.rows;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ConstructHeader(templateType, template)
|
||||
local headerContainer = self:GetHeaderContainer();
|
||||
assert(headerContainer ~= nil, "A header container must be set with TableBuilderMixin:SetHeaderContainer before adding column headers.")
|
||||
local headerPoolCollection = self:GetHeaderPoolCollection();
|
||||
local pool = headerPoolCollection:GetOrCreatePool(templateType, headerContainer, template);
|
||||
return pool:Acquire(template);
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ConstructCells(templateType, template)
|
||||
local cells = {};
|
||||
for k, row in pairs(self:GetRows()) do
|
||||
local pool = row.poolCollection:GetOrCreatePool(templateType, row, template);
|
||||
local cell = pool:Acquire(template);
|
||||
tinsert(cells, cell);
|
||||
end
|
||||
return cells;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:Arrange()
|
||||
local columns = self:GetColumns();
|
||||
if columns and #columns > 0 then
|
||||
self:CalculateColumnSpacing();
|
||||
self:ArrangeHeaders();
|
||||
self:ArrangeCells();
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:Reset()
|
||||
self.columns = {};
|
||||
self:GetHeaderPoolCollection():ReleaseAll();
|
||||
self:ReleaseRowPools();
|
||||
end
|
||||
|
||||
function TableBuilderMixin:Populate(offset, count)
|
||||
local dataProvider = self:GetDataProvider();
|
||||
local columns = self:GetColumns();
|
||||
for rowIndex = 1, count do
|
||||
local dataIndex = rowIndex + offset;
|
||||
local rowData = dataProvider(dataIndex);
|
||||
if not rowData then
|
||||
break;
|
||||
end
|
||||
|
||||
local row = self:GetRowByIndex(rowIndex);
|
||||
if row then
|
||||
-- Data is assigned to the rows and elements so they can
|
||||
-- access it later in tooltips.
|
||||
row.rowData = rowData;
|
||||
if row.Populate then
|
||||
row:Populate(rowData, dataIndex);
|
||||
end
|
||||
|
||||
for columnIndex, p in ipairs(columns) do
|
||||
local cell = self:GetCellByIndex(rowIndex, columnIndex);
|
||||
if cell.Populate then
|
||||
cell.rowData = rowData;
|
||||
cell:Populate(rowData, dataIndex);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetCellByIndex(rowIndex, index)
|
||||
local row = self:GetRowByIndex(rowIndex);
|
||||
return row.cells[index];
|
||||
end
|
||||
|
||||
function TableBuilderMixin:GetRowByIndex(rowIndex)
|
||||
return self.rows[rowIndex];
|
||||
end
|
||||
|
||||
function TableBuilderMixin:AddColumn()
|
||||
local column = CreateAndInitFromMixin(TableBuilderColumnMixin, self);
|
||||
tinsert(self.columns, column);
|
||||
return column;
|
||||
end
|
||||
|
||||
function TableBuilderMixin:CalculateColumnSpacing()
|
||||
-- The arrangement of frames is daisy-chained left to right. The margin on the left side
|
||||
-- is created by adding the margin to it's anchor offset, and the margin on the right side
|
||||
-- is created by subtracting space from the remaining fill space.
|
||||
local columns = self:GetColumns();
|
||||
local paddingTotal = 0;
|
||||
local fillCoefficientTotal = 0;
|
||||
local fixedWidthTotal = 0;
|
||||
for columnIndex, column in ipairs(columns) do
|
||||
if column:GetWidthConstraints() == ColumnWidthConstraints.Fill then
|
||||
fillCoefficientTotal = fillCoefficientTotal + column:GetFillCoefficient();
|
||||
else
|
||||
fixedWidthTotal = fixedWidthTotal + column:GetFixedWidth();
|
||||
end
|
||||
|
||||
paddingTotal = paddingTotal + column:GetPadding();
|
||||
end
|
||||
|
||||
local tableWidth = self:GetTableWidth();
|
||||
local leftMargin, rightMargin = self:GetTableMargins();
|
||||
local fillWidthTotal = tableWidth - paddingTotal - (leftMargin + rightMargin) - fixedWidthTotal;
|
||||
for k, column in pairs(columns) do
|
||||
if fillCoefficientTotal > 0 and column:GetWidthConstraints() == ColumnWidthConstraints.Fill then
|
||||
local fillRatio = column:GetFillCoefficient() / fillCoefficientTotal;
|
||||
local width = fillRatio * fillWidthTotal;
|
||||
column:SetCalculatedWidth(width);
|
||||
else
|
||||
local width = column:GetFixedWidth();
|
||||
column:SetCalculatedWidth(width);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ArrangeHorizontally(frame, relativeTo, width, pointTop, pointRelativeTop, pointBottom, pointRelativeBottom, xOffset)
|
||||
frame:SetPoint(pointTop, relativeTo, pointRelativeTop, xOffset, 0);
|
||||
frame:SetPoint(pointBottom, relativeTo, pointRelativeBottom, xOffset, 0);
|
||||
frame:SetWidth(width);
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ArrangeHeaders()
|
||||
local headerOverlap = self:GetColumnHeaderOverlap();
|
||||
local leftMargin, rightMargin = self:GetTableMargins();
|
||||
local columns = self:GetColumns();
|
||||
|
||||
-- Any trailing columns without headers should add to the width of the last column with a header.
|
||||
local numColumns = #columns;
|
||||
local lastActiveHeaderIndex = numColumns;
|
||||
local trailingWidth = 0;
|
||||
for i, column in ipairs(columns) do
|
||||
if column:GetHeaderFrame() then
|
||||
trailingWidth = 0;
|
||||
lastActiveHeaderIndex = i;
|
||||
else
|
||||
trailingWidth = trailingWidth + column:GetFullWidth();
|
||||
end
|
||||
end
|
||||
|
||||
local previousHeader = nil;
|
||||
local accumulatedWidth = 0;
|
||||
local columnIndex = 1;
|
||||
|
||||
while columnIndex <= numColumns do
|
||||
local column = columns[columnIndex];
|
||||
accumulatedWidth = accumulatedWidth + column:GetCalculatedWidth();
|
||||
|
||||
local isLastIndex = columnIndex == lastActiveHeaderIndex;
|
||||
local header = column:GetHeaderFrame();
|
||||
if header then
|
||||
if isLastIndex then
|
||||
accumulatedWidth = accumulatedWidth + trailingWidth;
|
||||
else
|
||||
for j = columnIndex + 1, #columns do
|
||||
local nextColumn = columns[j];
|
||||
if nextColumn:GetDisplayUnderPreviousHeader() then
|
||||
columnIndex = columnIndex + 1;
|
||||
accumulatedWidth = accumulatedWidth + nextColumn:GetFullWidth();
|
||||
else
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if previousHeader == nil then
|
||||
self:ArrangeHorizontally(header, header:GetParent(), accumulatedWidth, "TOPLEFT", "TOPLEFT", "BOTTOMLEFT", "BOTTOMLEFT", leftMargin);
|
||||
else
|
||||
self:ArrangeHorizontally(header, previousHeader, accumulatedWidth + headerOverlap, "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", column:GetPadding() - headerOverlap);
|
||||
end
|
||||
|
||||
accumulatedWidth = 0;
|
||||
previousHeader = header;
|
||||
end
|
||||
|
||||
if isLastIndex then
|
||||
break;
|
||||
end
|
||||
|
||||
columnIndex = columnIndex + 1;
|
||||
end
|
||||
end
|
||||
|
||||
function TableBuilderMixin:ArrangeCells()
|
||||
local columns = self:GetColumns();
|
||||
local leftMargin, rightMargin = self:GetTableMargins();
|
||||
for rowIndex, row in ipairs(self:GetRows()) do
|
||||
local cells = {};
|
||||
local height = row:GetHeight();
|
||||
|
||||
local column = columns[1];
|
||||
local cell = column:GetCellByRowIndex(rowIndex);
|
||||
tinsert(cells, cell);
|
||||
cell:SetHeight(height);
|
||||
local leftCellPadding, rightCellPadding = column:GetCellPadding();
|
||||
|
||||
self:ArrangeHorizontally(cell, row, column:GetCellWidth(), "TOPLEFT", "TOPLEFT", "BOTTOMLEFT", "BOTTOMLEFT", leftMargin + leftCellPadding);
|
||||
|
||||
local previousCell = cell;
|
||||
local previousRightCellPadding = rightCellPadding;
|
||||
for columnIndex = 2, #columns do
|
||||
column = columns[columnIndex];
|
||||
cell = column:GetCellByRowIndex(rowIndex);
|
||||
tinsert(cells, cell);
|
||||
cell:SetHeight(height);
|
||||
leftCellPadding, rightCellPadding = column:GetCellPadding();
|
||||
|
||||
self:ArrangeHorizontally(cell, previousCell, column:GetCellWidth(), "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", column:GetPadding() + leftCellPadding + previousRightCellPadding);
|
||||
previousCell = cell;
|
||||
previousRightCellPadding = rightCellPadding;
|
||||
end
|
||||
|
||||
row.cells = cells;
|
||||
end
|
||||
end
|
||||
|
||||
-- ... are additional mixins
|
||||
function CreateTableBuilder(rows, ...)
|
||||
local tableBuilder = CreateAndInitFromMixin(TableBuilderMixin, rows);
|
||||
Mixin(tableBuilder, ...);
|
||||
return tableBuilder;
|
||||
end
|
||||
-697
@@ -1,697 +0,0 @@
|
||||
local tRemove = table.remove;
|
||||
local tInsert = table.insert;
|
||||
local tWipe = table.wipe;
|
||||
|
||||
TableUtil = {};
|
||||
|
||||
TableUtil.Constants =
|
||||
{
|
||||
AssociativePriorityTable = true,
|
||||
ArraylikePriorityTable = false,
|
||||
IsIndexTable = true,
|
||||
};
|
||||
|
||||
function ipairs_reverse(table)
|
||||
local function Enumerator(table, index)
|
||||
index = index - 1;
|
||||
local value = table[index];
|
||||
if value ~= nil then
|
||||
return index, value;
|
||||
end
|
||||
end
|
||||
return Enumerator, table, #table + 1;
|
||||
end
|
||||
|
||||
function CreateTableEnumerator(tbl, minIndex, maxIndex)
|
||||
minIndex = minIndex and (minIndex - 1) or 0;
|
||||
maxIndex = maxIndex or math.huge;
|
||||
|
||||
local function Enumerator(tbl, index)
|
||||
index = index + 1;
|
||||
if index <= maxIndex then
|
||||
local value = tbl[index];
|
||||
if value ~= nil then
|
||||
return index, value;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Enumerator, tbl, minIndex;
|
||||
end
|
||||
|
||||
function CreateTableReverseEnumerator(tbl, minIndex, maxIndex)
|
||||
minIndex = minIndex or 1;
|
||||
maxIndex = (maxIndex or #tbl) + 1;
|
||||
|
||||
local function Enumerator(tbl, index)
|
||||
index = index - 1;
|
||||
if index >= minIndex then
|
||||
local value = tbl[index];
|
||||
if value ~= nil then
|
||||
return index, value;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Enumerator, tbl, maxIndex;
|
||||
end
|
||||
|
||||
function tCount(t)
|
||||
if type(t) ~= "table" then
|
||||
return 0
|
||||
end
|
||||
local size = 0
|
||||
for _ in pairs(t) do
|
||||
size = size + 1
|
||||
end
|
||||
return size
|
||||
end
|
||||
|
||||
function tDeleteItem(tbl, item)
|
||||
local size = #tbl;
|
||||
local index = size;
|
||||
while index > 0 do
|
||||
if item == tbl[index] then
|
||||
tRemove(tbl, index);
|
||||
end
|
||||
index = index - 1;
|
||||
end
|
||||
return size - #tbl;
|
||||
end
|
||||
|
||||
function tIndexOf(tbl, item)
|
||||
for i, v in ipairs(tbl) do
|
||||
if item == v then
|
||||
return i;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tContains(tbl, item)
|
||||
local index = 1;
|
||||
while tbl[index] do
|
||||
if ( item == tbl[index] ) then
|
||||
return 1;
|
||||
end
|
||||
index = index + 1;
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
function tContainsValue(tbl, item)
|
||||
for k, v in pairs(tbl) do
|
||||
if item == v then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
return false;
|
||||
end
|
||||
|
||||
function TableUtil.ContainsAllKeys(lhsTable, rhsTable)
|
||||
for key, _ in pairs(lhsTable) do
|
||||
if rhsTable[key] == nil then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
-- Check for any keys that are in rhsTable and not lhsTable.
|
||||
for key, _ in pairs(rhsTable) do
|
||||
if lhsTable[key] == nil then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
function TableUtil.CompareValuesAsKeys(lhsTable, rhsTable, valueToKeyOp)
|
||||
local lhsKeys = CopyTransformedValuesAsKeys(lhsTable, valueToKeyOp);
|
||||
local rhsKeys = CopyTransformedValuesAsKeys(rhsTable, valueToKeyOp);
|
||||
return TableUtil.ContainsAllKeys(lhsKeys, rhsKeys)
|
||||
end
|
||||
|
||||
-- This is a deep compare on the values of the table (based on depth) but not a deep comparison
|
||||
-- of the keys, as this would be an expensive check and won't be necessary in most cases.
|
||||
function tCompare(lhsTable, rhsTable, depth)
|
||||
depth = depth or 1;
|
||||
for key, value in pairs(lhsTable) do
|
||||
if type(value) == "table" then
|
||||
local rhsValue = rhsTable[key];
|
||||
if type(rhsValue) ~= "table" then
|
||||
return false;
|
||||
end
|
||||
if depth > 1 then
|
||||
if not tCompare(value, rhsValue, depth - 1) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
elseif value ~= rhsTable[key] then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for any keys that are in rhsTable and not lhsTable.
|
||||
for key, value in pairs(rhsTable) do
|
||||
if lhsTable[key] == nil then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
function tInvert(tbl)
|
||||
local inverted = {};
|
||||
for k, v in pairs(tbl) do
|
||||
inverted[v] = k;
|
||||
end
|
||||
return inverted;
|
||||
end
|
||||
|
||||
function TableUtil.TrySet(tbl, key)
|
||||
if not tbl[key] then
|
||||
tbl[key] = true;
|
||||
return true;
|
||||
end
|
||||
return false;
|
||||
end
|
||||
|
||||
function TableUtil.CopyUnique(tbl, isIndexTable)
|
||||
local found = {};
|
||||
local function FilterPredicate(value)
|
||||
return TableUtil.TrySet(found, value);
|
||||
end
|
||||
|
||||
return tFilter(tbl, FilterPredicate, isIndexTable);
|
||||
end
|
||||
|
||||
function TableUtil.CopyUniqueByPredicate(tbl, isIndexTable, unaryPredicate)
|
||||
local found = {};
|
||||
local function FilterPredicate(value)
|
||||
return TableUtil.TrySet(found, unaryPredicate(value));
|
||||
end
|
||||
|
||||
return tFilter(tbl, FilterPredicate, isIndexTable);
|
||||
end
|
||||
|
||||
function tFilter(tbl, pred, isIndexTable)
|
||||
local out = {};
|
||||
|
||||
if (isIndexTable) then
|
||||
local currentIndex = 1;
|
||||
for i, v in ipairs(tbl) do
|
||||
if (pred(v)) then
|
||||
out[currentIndex] = v;
|
||||
currentIndex = currentIndex + 1;
|
||||
end
|
||||
end
|
||||
else
|
||||
for k, v in pairs(tbl) do
|
||||
if (pred(v)) then
|
||||
out[k] = v;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return out;
|
||||
end
|
||||
|
||||
function tAppendAll(table, addedArray)
|
||||
for i, element in ipairs(addedArray) do
|
||||
tinsert(table, element);
|
||||
end
|
||||
end
|
||||
|
||||
function tInsertUnique(tbl, item)
|
||||
if not tContains(tbl, item) then
|
||||
table.insert(tbl, item);
|
||||
return #tbl;
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
function tUnorderedRemove(tbl, index)
|
||||
if index ~= #tbl then
|
||||
tbl[index] = tbl[#tbl];
|
||||
end
|
||||
|
||||
tRemove(tbl);
|
||||
end
|
||||
|
||||
function CopyTable(settings, shallow)
|
||||
local copy = {};
|
||||
for k, v in pairs(settings) do
|
||||
if type(v) == "table" and not shallow then
|
||||
copy[k] = CopyTable(v);
|
||||
else
|
||||
copy[k] = v;
|
||||
end
|
||||
end
|
||||
return copy;
|
||||
end
|
||||
|
||||
function MergeTable(destination, source)
|
||||
for k, v in pairs(source) do
|
||||
destination[k] = v;
|
||||
end
|
||||
end
|
||||
|
||||
-- Useful if there are external references to a table but we want to set
|
||||
-- that table's key-value pairs to be exactly the same as another table's key-value pairs.
|
||||
function SetTablePairsToTable(destination, source)
|
||||
tWipe(destination);
|
||||
MergeTable(destination, source);
|
||||
end
|
||||
|
||||
function Accumulate(tbl)
|
||||
local count = 0;
|
||||
for k, v in pairs(tbl) do
|
||||
count = count + v;
|
||||
end
|
||||
return count;
|
||||
end
|
||||
|
||||
function AccumulateOp(tbl, op)
|
||||
local count = 0;
|
||||
for k, v in pairs(tbl) do
|
||||
count = count + op(v);
|
||||
end
|
||||
return count;
|
||||
end
|
||||
|
||||
function TableUtil.Execute(tbl, op)
|
||||
for k, v in pairs(tbl) do
|
||||
op(v);
|
||||
end
|
||||
end
|
||||
|
||||
function TableUtil.ExecuteUntil(tbl, op)
|
||||
for k, v in pairs(tbl) do
|
||||
local operationResult = op(v);
|
||||
if operationResult then
|
||||
return operationResult;
|
||||
end
|
||||
end
|
||||
|
||||
return nil;
|
||||
end
|
||||
|
||||
function TableUtil.Transform(tbl, op)
|
||||
local result = {};
|
||||
for k, v in pairs(tbl) do
|
||||
table.insert(result, op(v));
|
||||
end
|
||||
return result;
|
||||
end
|
||||
|
||||
function ContainsIf(tbl, pred)
|
||||
for k, v in pairs(tbl) do
|
||||
if (pred(v)) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
function FindInTableIf(tbl, pred)
|
||||
for k, v in pairs(tbl) do
|
||||
if (pred(v)) then
|
||||
return k, v;
|
||||
end
|
||||
end
|
||||
|
||||
return nil;
|
||||
end
|
||||
|
||||
function FindValueInTableIf(tbl, pred)
|
||||
local _, value = FindInTableIf(tbl, pred);
|
||||
return value;
|
||||
end
|
||||
|
||||
local function FindSortedIndexImplementation(tbl, searchComparison, startIndex, rangeStart, rangeEnd)
|
||||
local comparisonResult = searchComparison(tbl[startIndex]);
|
||||
if comparisonResult == 0 then
|
||||
return startIndex;
|
||||
end
|
||||
|
||||
if comparisonResult > 0 then
|
||||
if startIndex >= rangeEnd then
|
||||
return startIndex + 1;
|
||||
end
|
||||
|
||||
rangeStart = startIndex + 1;
|
||||
return FindSortedIndexImplementation(tbl, searchComparison, startIndex + math.ceil((rangeEnd - startIndex) / 2), rangeStart, rangeEnd);
|
||||
end
|
||||
|
||||
-- comparisonResult < 0
|
||||
if startIndex <= rangeStart then
|
||||
return startIndex;
|
||||
end
|
||||
|
||||
rangeEnd = startIndex - 1;
|
||||
return FindSortedIndexImplementation(tbl, searchComparison, math.floor(startIndex / 2), rangeStart, rangeEnd);
|
||||
end
|
||||
|
||||
function FindSortedIndex(tbl, searchComparison)
|
||||
local numTable = #tbl;
|
||||
local startingIndex = math.ceil(numTable / 2);
|
||||
if startingIndex == 0 then
|
||||
return 1;
|
||||
end
|
||||
|
||||
return FindSortedIndexImplementation(tbl, searchComparison, startingIndex, 1, numTable);
|
||||
end
|
||||
|
||||
function TableIsEmpty(tbl)
|
||||
return next(tbl) == nil;
|
||||
end
|
||||
|
||||
function TableHasAnyEntries(tbl)
|
||||
return next(tbl) ~= nil;
|
||||
end
|
||||
|
||||
function CopyValuesAsKeys(tbl)
|
||||
local output = {};
|
||||
for k, v in ipairs(tbl) do
|
||||
output[v] = v;
|
||||
end
|
||||
return output;
|
||||
end
|
||||
|
||||
function CopyTransformedValuesAsKeys(tbl, transformOp)
|
||||
local output = {};
|
||||
for _, v in ipairs(tbl) do
|
||||
output[transformOp(v)] = v;
|
||||
end
|
||||
return output;
|
||||
end
|
||||
|
||||
-- Addresses the problem where nil values within a varargs list are not preserved when constructing
|
||||
-- a table, resulting a table with a smaller size than expected. Should be paired with a call to
|
||||
-- SafeUnpack when unpacking the table.
|
||||
function SafePack(...)
|
||||
local tbl = { ... };
|
||||
tbl.n = select("#", ...);
|
||||
return tbl;
|
||||
end
|
||||
|
||||
-- Upacks a table that was constructed using SafePack.
|
||||
function SafeUnpack(tbl, startIndex)
|
||||
return unpack(tbl, startIndex or 1, tbl.n);
|
||||
end
|
||||
|
||||
-- Returns the length of a table, accounting for the possibility of a table constructed using SafePack.
|
||||
function SafeLength(tbl)
|
||||
if not tbl then
|
||||
return 0;
|
||||
end
|
||||
|
||||
local operatorCount = #tbl;
|
||||
local safePackCount = tbl.n;
|
||||
|
||||
if safePackCount and operatorCount ~= safePackCount then
|
||||
return safePackCount;
|
||||
end
|
||||
|
||||
return operatorCount;
|
||||
end
|
||||
|
||||
function GetOrCreateTableEntry(table, key, defaultValue)
|
||||
local currentValue = table[key];
|
||||
local isNewValue = (currentValue == nil);
|
||||
if isNewValue then
|
||||
if defaultValue ~= nil then
|
||||
currentValue = defaultValue;
|
||||
else
|
||||
currentValue = {};
|
||||
end
|
||||
table[key] = currentValue;
|
||||
end
|
||||
|
||||
return currentValue, isNewValue;
|
||||
end
|
||||
|
||||
function GetOrCreateTableEntryByCallback(table, key, callback)
|
||||
local currentValue = table[key];
|
||||
local isNewValue = (currentValue == nil);
|
||||
if isNewValue then
|
||||
currentValue = callback(key);
|
||||
table[key] = currentValue;
|
||||
end
|
||||
|
||||
return currentValue, isNewValue;
|
||||
end
|
||||
|
||||
function GetRandomArrayEntry(array)
|
||||
return array[math.random(1, #array)];
|
||||
end
|
||||
|
||||
function GetRandomTableValue(tbl)
|
||||
local value;
|
||||
local n = 0;
|
||||
for k, v in pairs(tbl) do
|
||||
n = n + 1;
|
||||
local r = math.random();
|
||||
if r <= (1 / n) then
|
||||
value = v;
|
||||
end
|
||||
end
|
||||
return value;
|
||||
end
|
||||
|
||||
function GetKeysArray(tbl)
|
||||
local keysArray = {};
|
||||
for key in pairs(tbl) do
|
||||
tInsert(keysArray, key);
|
||||
end
|
||||
|
||||
return keysArray;
|
||||
end
|
||||
|
||||
function GetValuesArray(tbl)
|
||||
local valuesArray = {};
|
||||
for key, value in pairs(tbl) do
|
||||
tInsert(valuesArray, value);
|
||||
end
|
||||
|
||||
return valuesArray;
|
||||
end
|
||||
|
||||
function GetPairsArray(tbl)
|
||||
local pairsArray = {};
|
||||
for key, value in pairs(tbl) do
|
||||
tInsert(pairsArray, { key = key, value = value, });
|
||||
end
|
||||
|
||||
return pairsArray;
|
||||
end
|
||||
|
||||
function SwapTableEntries(lhsTable, rhsTable, key)
|
||||
local lhsValue = lhsTable[key];
|
||||
lhsTable[key] = rhsTable[key];
|
||||
rhsTable[key] = lhsValue;
|
||||
end
|
||||
|
||||
function GetKeysArraySortedByValue(tbl)
|
||||
local keysArray = GetKeysArray(tbl);
|
||||
|
||||
table.sort(keysArray, function(a, b)
|
||||
return tbl[a] < tbl[b];
|
||||
end);
|
||||
|
||||
return keysArray;
|
||||
end
|
||||
|
||||
function TableUtil.OperateOnKeys(tbl, operation)
|
||||
for key, value in pairs(tbl) do
|
||||
operation(key);
|
||||
end
|
||||
end
|
||||
|
||||
function TableUtil.GetTableValueListFromEnumeration(tableKey, ...)
|
||||
local values = {};
|
||||
for enumerationKey, tbl in ... do
|
||||
table.insert(values, tbl[tableKey]);
|
||||
end
|
||||
|
||||
return values;
|
||||
end
|
||||
|
||||
function TableUtil.GetHighestNumericalValueInTable(table)
|
||||
local highestValue = nil;
|
||||
for key, value in pairs(table) do
|
||||
if type(value) == "number" and (not highestValue or value > highestValue) then
|
||||
highestValue = value;
|
||||
end
|
||||
end
|
||||
return highestValue;
|
||||
end
|
||||
|
||||
--[[
|
||||
This utility creates and returns a table of elements that are sorted by value "priority".
|
||||
|
||||
Arguments:
|
||||
comparator - comparator(A, B) returns whether A has higher priority than B
|
||||
isAssociative - whether the table should be associative (true) or array-like (false). Only values have priorities for associative tables, not keys.
|
||||
|
||||
Return usage:
|
||||
t[k]/t:Get(k) - returns the value stored with key/index k
|
||||
t[k] = v (Associative only) - stores the value v at key k, sorting accordingly
|
||||
t:Insert(v) (Array-like only) - inserts the value v, sorting accordingly
|
||||
t:Remove(k) - removes the element at key/index k
|
||||
t:Iterate(cb) - calls function cb on each key/index value pair in sorted priority order. !!WARNING!! This must be used instead of pairs(t)/ipairs(t)
|
||||
t:GetTop() - returns the highest priority element
|
||||
t:Pop() - returns and removes the highest priority element
|
||||
t:GetBottom() - returns the lowest priority element
|
||||
t:Size() - returns the number of stored elements. !!WARNING!! This must be used instead of #t
|
||||
t:Clear() - removes all elements
|
||||
--]]
|
||||
function TableUtil.CreatePriorityTable(comparator, isAssociative)
|
||||
local sortedArray = {};
|
||||
|
||||
local ShiftPositionMap;
|
||||
local keyToPosMap;
|
||||
if isAssociative then
|
||||
keyToPosMap = {};
|
||||
|
||||
ShiftPositionMap = function(position, shiftUp)
|
||||
local mod = shiftUp and 1 or -1;
|
||||
for k, p in pairs(keyToPosMap) do
|
||||
if p >= position then
|
||||
keyToPosMap[k] = p + mod;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function SortedInsert(k, v)
|
||||
if isAssociative then
|
||||
local prevPos = keyToPosMap[k];
|
||||
if prevPos then
|
||||
tRemove(sortedArray, prevPos);
|
||||
local shiftUp = false;
|
||||
ShiftPositionMap(prevPos, shiftUp);
|
||||
end
|
||||
end
|
||||
|
||||
local top = (#sortedArray > 0) and (#sortedArray + 1) or 1;
|
||||
local bottom = 1;
|
||||
while top ~= bottom do
|
||||
local mid = math.floor((top - bottom) / 2) + bottom;
|
||||
if not comparator(v, sortedArray[mid]) then
|
||||
bottom = mid + 1;
|
||||
else
|
||||
top = mid;
|
||||
end
|
||||
end
|
||||
local idx = bottom;
|
||||
tInsert(sortedArray, idx, v);
|
||||
|
||||
if isAssociative then
|
||||
local shiftUp = true;
|
||||
ShiftPositionMap(idx, shiftUp);
|
||||
keyToPosMap[k] = idx;
|
||||
end
|
||||
end
|
||||
|
||||
local t = {};
|
||||
|
||||
function t:Get(k)
|
||||
local key = isAssociative and keyToPosMap[k] or k;
|
||||
return sortedArray[key];
|
||||
end
|
||||
|
||||
if not isAssociative then
|
||||
function t:Insert(v)
|
||||
SortedInsert(nil, v)
|
||||
end
|
||||
end
|
||||
|
||||
function t:Remove(k)
|
||||
local key = isAssociative and keyToPosMap[k] or k;
|
||||
tRemove(sortedArray, key);
|
||||
if isAssociative then
|
||||
keyToPosMap[k] = nil;
|
||||
local shiftUp = false;
|
||||
ShiftPositionMap(key, shiftUp);
|
||||
end
|
||||
end
|
||||
|
||||
function t:GetTop()
|
||||
return #sortedArray > 0 and sortedArray[1];
|
||||
end
|
||||
|
||||
function t:GetBottom()
|
||||
return #sortedArray > 0 and sortedArray[#sortedArray];
|
||||
end
|
||||
|
||||
function t:Pop()
|
||||
if t:Size() == 0 then
|
||||
return nil;
|
||||
end
|
||||
|
||||
local top = t:GetTop();
|
||||
local removalKey = isAssociative and tInvert(keyToPosMap)[1] or 1;
|
||||
t:Remove(removalKey);
|
||||
return top;
|
||||
end
|
||||
|
||||
function t:Iterate(callback)
|
||||
local posToKeyMap = isAssociative and tInvert(keyToPosMap) or nil;
|
||||
for pos, v in ipairs(sortedArray) do
|
||||
local key = isAssociative and posToKeyMap[pos] or pos;
|
||||
local done = callback(key, v);
|
||||
if done then
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function t:Size()
|
||||
return #sortedArray;
|
||||
end
|
||||
|
||||
function t:Clear()
|
||||
sortedArray = {};
|
||||
if isAssociative then
|
||||
keyToPosMap = {};
|
||||
end
|
||||
end
|
||||
|
||||
local mt =
|
||||
{
|
||||
__index = function(t, k)
|
||||
return t:Get(k);
|
||||
end,
|
||||
};
|
||||
if isAssociative then
|
||||
mt.__newindex = function(t, k, v)
|
||||
if v ~= nil then
|
||||
SortedInsert(k, v);
|
||||
else
|
||||
t:Remove(k);
|
||||
end
|
||||
end
|
||||
else
|
||||
mt.__newindex = function(t, k, v)
|
||||
error("Attempted to assign a value to an array-like priority queue index. Use Insert()/Remove() instead.")
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(t, mt);
|
||||
|
||||
return t;
|
||||
end
|
||||
|
||||
function DeepMergeTable(destination, source)
|
||||
for k, v in pairs(source) do
|
||||
if type(v) == "table" then
|
||||
if type(destination[k]) == "table" then
|
||||
DeepMergeTable(destination[k], v)
|
||||
else
|
||||
destination[k] = CopyTable(v)
|
||||
end
|
||||
else
|
||||
destination[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
-850
@@ -1,850 +0,0 @@
|
||||
local ADVENTURE_TYPE = {
|
||||
PRIMARY = 1,
|
||||
SECONDARY = 2,
|
||||
}
|
||||
|
||||
local ADVENTURE_CATEGORY = {
|
||||
DEV = 0,
|
||||
NOVICE_TIPS = 1,
|
||||
WINTERGRASP = 2,
|
||||
CATEGORY_BOSSES = 3,
|
||||
SPEC_INFO = 4,
|
||||
QUEST_DAILY_CRYSTALS = 5,
|
||||
BATTLE_PASS_QUEST_DAILY = 6,
|
||||
QUEST_RENEGADE = 7,
|
||||
QUEST_SIRUS = 8,
|
||||
SEASONAL_EVENT = 9,
|
||||
QUEST_WEEKLY_PVE = 10,
|
||||
BRAWL = 11,
|
||||
BATTLE_PASS_QUEST_WEEKLY = 12,
|
||||
RAID_NEWEST_NORMAL = 13,
|
||||
RAID_NEWEST_HEROIC = 14,
|
||||
WEEKEND_EVENT = 15,
|
||||
QUEST_DAILY_ISLAND = 16,
|
||||
ZONE_QUEST = 17,
|
||||
TUTORIAL_COINS = 100,
|
||||
MISC = 128,
|
||||
}
|
||||
|
||||
local ADVENTURE_CATEGORY_PRIORITY = {
|
||||
[ADVENTURE_CATEGORY.DEV] = 0,
|
||||
[ADVENTURE_CATEGORY.NOVICE_TIPS] = 1,
|
||||
[ADVENTURE_CATEGORY.WINTERGRASP] = 1,
|
||||
[ADVENTURE_CATEGORY.CATEGORY_BOSSES] = 1,
|
||||
[ADVENTURE_CATEGORY.SPEC_INFO] = 3,
|
||||
[ADVENTURE_CATEGORY.QUEST_DAILY_CRYSTALS] = 1,
|
||||
[ADVENTURE_CATEGORY.BATTLE_PASS_QUEST_DAILY] = 2,
|
||||
[ADVENTURE_CATEGORY.QUEST_RENEGADE] = 2,
|
||||
[ADVENTURE_CATEGORY.QUEST_SIRUS] = 2,
|
||||
[ADVENTURE_CATEGORY.SEASONAL_EVENT] = 2,
|
||||
[ADVENTURE_CATEGORY.QUEST_WEEKLY_PVE] = 2,
|
||||
[ADVENTURE_CATEGORY.BRAWL] = 2,
|
||||
[ADVENTURE_CATEGORY.BATTLE_PASS_QUEST_WEEKLY] = 5,
|
||||
[ADVENTURE_CATEGORY.RAID_NEWEST_NORMAL] = 2,
|
||||
[ADVENTURE_CATEGORY.RAID_NEWEST_HEROIC] = 2,
|
||||
[ADVENTURE_CATEGORY.WEEKEND_EVENT] = 4,
|
||||
[ADVENTURE_CATEGORY.QUEST_DAILY_ISLAND] = 5,
|
||||
[ADVENTURE_CATEGORY.ZONE_QUEST] = 5,
|
||||
[ADVENTURE_CATEGORY.TUTORIAL_COINS] = 6,
|
||||
[ADVENTURE_CATEGORY.MISC] = 5,
|
||||
}
|
||||
|
||||
local CONDITION_CHECK = {
|
||||
PLAYER_IN_GM_MODE = 0,
|
||||
PLAYER_FACTION = 1,
|
||||
PLAYER_LEVEL = 2,
|
||||
PLAYER_HAS_BUFF = 3,
|
||||
PLAYER_HAS_DEBUFF = 4,
|
||||
PLAYER_HAS_ITEM = 5,
|
||||
PLAYER_SPELL_KNOWN = 6,
|
||||
PET_SPELL_KNOWN = 7,
|
||||
REALM_STAGE = 8,
|
||||
REALM_DUNGEON_ACTUAL = 9,
|
||||
REALM_GAME_EVENT_ACTIVE = 10,
|
||||
PLAYER_QUEST_COMPLETE = 11,
|
||||
PLAYER_ACHIEVEMENT_COMPLETE = 12,
|
||||
PLAYER_BATTLEPASS_DAILY_COUNT = 13,
|
||||
PLAYER_BATTLEPASS_WEEKLY_COUNT = 14,
|
||||
REALM_WINTERGRASP_REGISTRATION_ACTIVE = 15,
|
||||
REALM_BRAWL_ACTIVE = 16,
|
||||
PLAYER_LFG_DUNGEON_JOINABLE = 17,
|
||||
PLAYER_LFG_MINIGAME_JOINABLE = 18,
|
||||
PLAYER_CUSTOM_VALUE = 19,
|
||||
PLAYER_HAS_QUEST_IN_QUESTLOG = 20,
|
||||
PLAYER_TALENT_GROUPS_COUNT = 21,
|
||||
REALM_ID = 22,
|
||||
PLAYER_IN_CHALLENGE_MODE = 23,
|
||||
}
|
||||
|
||||
local CONDITION_OPERATOR = {
|
||||
COMP_TYPE_EQ = 0,
|
||||
COMP_TYPE_HIGH = 1,
|
||||
COMP_TYPE_LOW = 2,
|
||||
COMP_TYPE_HIGH_EQ = 3,
|
||||
COMP_TYPE_LOW_EQ = 4,
|
||||
}
|
||||
|
||||
local ACTION_BUTTON_TYPE = {
|
||||
NONE = 0,
|
||||
QUEST_START = 1,
|
||||
UI_PVP_ARENA_RATING = 2,
|
||||
UI_PVP_HONOR_RANDOM = 3,
|
||||
UI_PVP_HONOR_WINTERGRASP = 4,
|
||||
UI_PVP_HONOR_BRAWL = 5,
|
||||
UI_PVE_LFG_DUNGEON_RANDOM = 6,
|
||||
UI_PVE_LFG_DUNGEON_ID = 7,
|
||||
UI_PVE_LFG_MINIGAME_ID = 8,
|
||||
UI_EJ_DUNGEON_ID = 9,
|
||||
UI_BATTLEPASS_QUESTS = 10,
|
||||
UI_HEAD_HUNTING = 11,
|
||||
}
|
||||
|
||||
local error = error
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local select = select
|
||||
local tonumber = tonumber
|
||||
local type = type
|
||||
local mathmax, mathmin, mathrandom = math.max, math.min, math.random
|
||||
local strconcat, strformat, strgsub = strconcat, string.format, string.gsub
|
||||
local tinsert, tsort, twipe, tCompare = table.insert, table.sort, table.wipe, tCompare
|
||||
|
||||
local CanQueueForWintergrasp = CanQueueForWintergrasp
|
||||
local GetAchievementInfo = GetAchievementInfo
|
||||
local GetFramerate = GetFramerate
|
||||
local GetItemCount = GetItemCount
|
||||
local GetQuestLinkByID = GetQuestLinkByID
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetTitleForQuestID = GetTitleForQuestID
|
||||
local IsLFGDungeonJoinable = IsLFGDungeonJoinable
|
||||
local IsQuestCompleted = IsQuestCompleted
|
||||
local IsQuestDataCached = IsQuestDataCached
|
||||
local IsSpellKnown = IsSpellKnown
|
||||
local QueryQuestStart = QueryQuestStart
|
||||
local UnitFactionGroup = UnitFactionGroup
|
||||
local UnitLevel = UnitLevel
|
||||
local debugprofilestop = debugprofilestop
|
||||
|
||||
local FireCustomClientEvent = FireCustomClientEvent
|
||||
local GetCurrentBrawlID = C_PvP.GetCurrentBrawlID
|
||||
local IsGameEventActive = IsGameEventActive
|
||||
local IsGMAccount = IsGMAccount
|
||||
local IsInterfaceDevClient = IsInterfaceDevClient
|
||||
--local RequestQuestCacheByID = RequestQuestCacheByID
|
||||
|
||||
local AJ_ACTION_TEXT_JOIN_BATTLE = AJ_ACTION_TEXT_JOIN_BATTLE
|
||||
local AJ_ACTION_TEXT_JOIN_GROUP = AJ_ACTION_TEXT_JOIN_GROUP
|
||||
local AJ_ACTION_TEXT_OPEN_EJ = AJ_ACTION_TEXT_OPEN_EJ
|
||||
local AJ_ACTION_TEXT_SHOW_QUEST = AJ_ACTION_TEXT_SHOW_QUEST
|
||||
local AJ_ACTION_TEXT_START_HUNT = AJ_ACTION_TEXT_START_HUNT
|
||||
local AJ_ACTION_TEXT_START_QUEST = AJ_ACTION_TEXT_START_QUEST
|
||||
local AJ_PRIMARY_REWARD_TEXT = AJ_PRIMARY_REWARD_TEXT
|
||||
local UNKNOWN = UNKNOWN
|
||||
|
||||
local COLOR_PATTERN = strformat("^|cff%s|H", string.rep("[0-9A-Fa-f]", 6))
|
||||
local QUESTION_MARK_ICON = strgsub(QUESTION_MARK_ICON, "%.BLP$", "")
|
||||
|
||||
local NUM_SECONDARY_SUGGESTIONS = 2
|
||||
local MAX_INT = 2^32/2-1
|
||||
|
||||
local PRIVATE = {
|
||||
DIRTY = true,
|
||||
|
||||
FRAMETIME_TARGET = 1 / 55,
|
||||
FRAMETIME_AVAILABLE = 8,
|
||||
FRAMETIME_RESERVE = 4,
|
||||
|
||||
REGISTRY = {},
|
||||
SUGGESTIONS = {},
|
||||
PRIMARY_OFFSET_INDEX = 1,
|
||||
}
|
||||
|
||||
PRIVATE.eventHandler = CreateFrame("Frame")
|
||||
PRIVATE.eventHandler:Hide()
|
||||
PRIVATE.eventHandler:SetScript("OnUpdate", function(self, elapsed)
|
||||
local frametimeStep = PRIVATE.FRAMETIME_TARGET - elapsed
|
||||
|
||||
if frametimeStep ~= 0 then
|
||||
frametimeStep = frametimeStep * 1000
|
||||
PRIVATE.FRAMETIME_AVAILABLE = mathmax(5, PRIVATE.FRAMETIME_AVAILABLE + frametimeStep)
|
||||
end
|
||||
|
||||
if PRIVATE.BUILD_COROUTINE then
|
||||
PRIVATE.BUILD_COROUTINE_TIMESTAMP = debugprofilestop()
|
||||
local status, result, progress = coroutine.resume(PRIVATE.BUILD_COROUTINE)
|
||||
|
||||
if not status then
|
||||
PRIVATE.BUILD_COROUTINE = nil
|
||||
self:Hide()
|
||||
error(result, 2)
|
||||
elseif not result then
|
||||
if PRIVATE.BUILD_COROUTINE_DEBUG then print("AJ_BUILD_COROUTINE", progress) end
|
||||
else
|
||||
PRIVATE.BUILD_COROUTINE = nil
|
||||
self:Hide()
|
||||
end
|
||||
else
|
||||
self:Hide()
|
||||
end
|
||||
end)
|
||||
|
||||
PRIVATE.Initialize = function()
|
||||
if PRIVATE.initialized then
|
||||
return
|
||||
end
|
||||
|
||||
PRIVATE.initialized = true
|
||||
|
||||
_G.ADVENTURE_TYPE = nil
|
||||
_G.ADVENTURE_CATEGORY = nil
|
||||
_G.ADVENTURE_CATEGORY_PRIORITY = nil
|
||||
_G.CONDITION_CHECK = nil
|
||||
_G.ACTION_BUTTON_TYPE = nil
|
||||
|
||||
local ADVENTURE_REGISTRY = _G.ADVENTURE_REGISTRY or {}
|
||||
if not IsInterfaceDevClient() then
|
||||
_G.ADVENTURE_REGISTRY = nil
|
||||
end
|
||||
|
||||
for _, adventureType in pairs(ADVENTURE_TYPE) do
|
||||
PRIVATE.REGISTRY[adventureType] = {}
|
||||
end
|
||||
|
||||
for index, entry in ipairs(ADVENTURE_REGISTRY) do
|
||||
if not entry.rngPriority then
|
||||
entry.rngPriority = mathrandom(1, MAX_INT)
|
||||
end
|
||||
|
||||
if entry.content then
|
||||
entry.content = strgsub(entry.content, "\\n", "\n")
|
||||
end
|
||||
|
||||
tinsert(PRIVATE.REGISTRY[entry.type], entry)
|
||||
end
|
||||
|
||||
for adventureType, registry in pairs(PRIVATE.REGISTRY) do
|
||||
tsort(registry, PRIVATE.SortEntries)
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.SortEntries = function(a, b)
|
||||
if ADVENTURE_CATEGORY_PRIORITY[a.category] ~= ADVENTURE_CATEGORY_PRIORITY[b.category] then
|
||||
return ADVENTURE_CATEGORY_PRIORITY[a.category] < ADVENTURE_CATEGORY_PRIORITY[b.category]
|
||||
elseif a.rngPriority ~= b.rngPriority then
|
||||
return a.rngPriority < b.rngPriority
|
||||
elseif a.id ~= b.id then
|
||||
return a.id < b.id
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
PRIVATE.IsMinigameAvailable = function(minigameID)
|
||||
for index = 1, C_MiniGames.GetNumGames() do
|
||||
if C_MiniGames.GetGameIDFromIndex(index) == minigameID then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
PRIVATE.ApplyConditionOperator = function(operator, conditionValue, value)
|
||||
if operator == CONDITION_OPERATOR.COMP_TYPE_EQ then
|
||||
return value == conditionValue
|
||||
elseif operator == CONDITION_OPERATOR.COMP_TYPE_HIGH then
|
||||
return value > conditionValue
|
||||
elseif operator == CONDITION_OPERATOR.COMP_TYPE_LOW then
|
||||
return value < conditionValue
|
||||
elseif operator == CONDITION_OPERATOR.COMP_TYPE_HIGH_EQ then
|
||||
return value >= conditionValue
|
||||
elseif operator == CONDITION_OPERATOR.COMP_TYPE_LOW_EQ then
|
||||
return value <= conditionValue
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.CheckCondition = function(entry, conditionType, conditionValue, operator, invert)
|
||||
local isComplete = false
|
||||
|
||||
if conditionType == CONDITION_CHECK.PLAYER_QUEST_COMPLETE then
|
||||
isComplete = IsQuestCompleted(conditionValue)
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_HAS_QUEST_IN_QUESTLOG then
|
||||
isComplete = GetQuestLogIndexByID(conditionValue) ~= nil
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_ACHIEVEMENT_COMPLETE then
|
||||
isComplete = select(4, GetAchievementInfo(conditionValue))
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_BATTLEPASS_DAILY_COUNT then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH_EQ, conditionValue, C_BattlePass.GetNumQuests(Enum.BattlePass.QuestType.Daily))
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_BATTLEPASS_WEEKLY_COUNT then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH_EQ, conditionValue, C_BattlePass.GetNumQuests(Enum.BattlePass.QuestType.Weekly))
|
||||
elseif conditionType == CONDITION_CHECK.REALM_STAGE then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH_EQ, conditionValue, C_Service.GetRealmStage())
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_LEVEL then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH_EQ, conditionValue, UnitLevel("player"))
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_FACTION then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_EQ, conditionValue, SERVER_PLAYER_FACTION_GROUP[UnitFactionGroup("player")])
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_CUSTOM_VALUE then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH, 0, C_Service.GetCustomValue(conditionValue) or 0)
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_TALENT_GROUPS_COUNT then
|
||||
isComplete = PRIVATE.ApplyConditionOperator(operator or CONDITION_OPERATOR.COMP_TYPE_HIGH, conditionValue, C_Talent.GetNumTalentGroups() or 1)
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_HAS_ITEM then
|
||||
isComplete = GetItemCount(conditionValue) > 0
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_HAS_BUFF then
|
||||
isComplete = C_Unit.FindAuraBySpell("player", conditionValue, "HELPFUL") ~= nil
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_HAS_DEBUFF then
|
||||
isComplete = C_Unit.FindAuraBySpell("player", conditionValue, "HARMFUL") ~= nil
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_SPELL_KNOWN then
|
||||
isComplete = IsSpellKnown(conditionValue, false)
|
||||
elseif conditionType == CONDITION_CHECK.PET_SPELL_KNOWN then
|
||||
isComplete = IsSpellKnown(conditionValue, true)
|
||||
elseif conditionType == CONDITION_CHECK.REALM_ID then
|
||||
isComplete = C_Service.GetRealmID() == conditionValue
|
||||
elseif conditionType == CONDITION_CHECK.REALM_GAME_EVENT_ACTIVE then
|
||||
isComplete = IsGameEventActive(conditionValue)
|
||||
elseif conditionType == CONDITION_CHECK.REALM_BRAWL_ACTIVE then
|
||||
isComplete = GetCurrentBrawlID() == conditionValue
|
||||
elseif conditionType == CONDITION_CHECK.REALM_WINTERGRASP_REGISTRATION_ACTIVE then
|
||||
isComplete = CanQueueForWintergrasp() ~= nil
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_LFG_DUNGEON_JOINABLE then
|
||||
isComplete = conditionValue ~= 0 and IsLFGDungeonJoinable(conditionValue)
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_LFG_MINIGAME_JOINABLE then
|
||||
isComplete = conditionValue ~= 0 and PRIVATE.IsMinigameAvailable(conditionValue)
|
||||
elseif conditionType == CONDITION_CHECK.REALM_DUNGEON_ACTUAL then
|
||||
isComplete = C_EncounterJournal.IsActualInstance(conditionValue, entry.ej_difficultyID)
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_IN_CHALLENGE_MODE then
|
||||
isComplete = (C_Hardcore.GetActiveChallengeID() or 0) == conditionValue
|
||||
elseif conditionType == CONDITION_CHECK.PLAYER_IN_GM_MODE then
|
||||
isComplete = C_Service.IsInGMMode()
|
||||
else -- unhandled condition
|
||||
return false
|
||||
end
|
||||
|
||||
if (not invert and isComplete)
|
||||
or (invert and not isComplete)
|
||||
then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
PRIVATE.CheckConditions = function(entry)
|
||||
for index, condition in ipairs(entry.conditions) do
|
||||
local isComplete = PRIVATE.CheckCondition(entry, condition.type, condition.value, condition.operator, condition.invert)
|
||||
if not isComplete then
|
||||
--[[
|
||||
if condition.altID then
|
||||
if type(condition.altID) == "table" then
|
||||
for idIndex, conditionAltID in ipairs(condition.altID) do
|
||||
isComplete = PRIVATE.CheckCondition(entry, condition.type, conditionAltID, condition.operator, condition.invert)
|
||||
if isComplete then
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
isComplete = PRIVATE.CheckCondition(entry, condition.type, condition.altID, condition.operator, condition.invert)
|
||||
end
|
||||
|
||||
if not isComplete then
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
--]]
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
PRIVATE.UpdateSuggestionsCoroutine = function(isLevelUp)
|
||||
local oldIDs = PRIVATE.GetUniqueSuggestionIDs()
|
||||
|
||||
local numEntries = 0
|
||||
local processedEntries = 0
|
||||
for adventureType, registry in ipairs(PRIVATE.REGISTRY) do
|
||||
numEntries = numEntries + #registry
|
||||
end
|
||||
|
||||
do -- Build Suggestions
|
||||
twipe(PRIVATE.SUGGESTIONS)
|
||||
|
||||
local numPrimary = 0
|
||||
local numSecondary = 0
|
||||
|
||||
for adventureType, registry in ipairs(PRIVATE.REGISTRY) do
|
||||
local isPrimary = adventureType == ADVENTURE_TYPE.PRIMARY
|
||||
|
||||
PRIVATE.SUGGESTIONS[adventureType] = {}
|
||||
|
||||
for index, entry in ipairs(registry) do
|
||||
processedEntries = processedEntries + 1
|
||||
|
||||
if PRIVATE.CheckConditions(entry) then
|
||||
if isPrimary then
|
||||
numPrimary = numPrimary + 1
|
||||
tinsert(PRIVATE.SUGGESTIONS[adventureType], entry)
|
||||
else
|
||||
if numSecondary >= NUM_SECONDARY_SUGGESTIONS or numPrimary == 0 then
|
||||
numPrimary = numPrimary + 1
|
||||
tinsert(PRIVATE.SUGGESTIONS[ADVENTURE_TYPE.PRIMARY], entry)
|
||||
else
|
||||
numSecondary = numSecondary + 1
|
||||
tinsert(PRIVATE.SUGGESTIONS[adventureType], entry)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (debugprofilestop() - PRIVATE.BUILD_COROUTINE_TIMESTAMP) > PRIVATE.FRAMETIME_BUDGET then
|
||||
coroutine.yield(false, processedEntries / numEntries)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local newIDs = PRIVATE.GetUniqueSuggestionIDs()
|
||||
local newAdventureNotice = tCompare(oldIDs, newIDs, 2)
|
||||
|
||||
local offsetFound
|
||||
|
||||
do -- try to select previously displayed primary suggestion
|
||||
if PRIVATE.PRIMARY_OFFSET_ID then
|
||||
local suggestion, offsetIndex = PRIVATE.GetSuggestionEntryByID(ADVENTURE_TYPE.PRIMARY, PRIVATE.PRIMARY_OFFSET_ID)
|
||||
if suggestion then
|
||||
PRIVATE.PRIMARY_OFFSET_INDEX = offsetIndex
|
||||
PRIVATE.PRIMARY_OFFSET_ID = suggestion.id
|
||||
offsetFound = true
|
||||
end
|
||||
end
|
||||
|
||||
if not offsetFound then
|
||||
local suggestion = PRIVATE.GetSuggestionEntry(ADVENTURE_TYPE.PRIMARY, 1)
|
||||
if suggestion then
|
||||
PRIVATE.PRIMARY_OFFSET_ID = suggestion.id
|
||||
else
|
||||
PRIVATE.PRIMARY_OFFSET_ID = nil
|
||||
end
|
||||
PRIVATE.PRIMARY_OFFSET_INDEX = 1
|
||||
end
|
||||
end
|
||||
|
||||
FireCustomClientEvent("AJ_REFRESH_DISPLAY", newAdventureNotice)
|
||||
|
||||
return true, 1
|
||||
end
|
||||
|
||||
PRIVATE.UpdateSuggestions = function(isLevelUp)
|
||||
if PRIVATE.BUILD_COROUTINE then
|
||||
return
|
||||
end
|
||||
|
||||
local framerate = GetFramerate()
|
||||
PRIVATE.FRAMETIME_TARGET = framerate > 63 and (1 / 60) or (1 / 55)
|
||||
PRIVATE.FRAMETIME_BUDGET = 1000 / framerate - PRIVATE.FRAMETIME_RESERVE
|
||||
|
||||
PRIVATE.BUILD_COROUTINE = coroutine.create(PRIVATE.UpdateSuggestionsCoroutine)
|
||||
PRIVATE.BUILD_COROUTINE_TIMESTAMP = debugprofilestop()
|
||||
|
||||
local status, result, progress = coroutine.resume(PRIVATE.BUILD_COROUTINE, isLevelUp)
|
||||
if not status then
|
||||
PRIVATE.BUILD_COROUTINE = nil
|
||||
PRIVATE.eventHandler:Hide()
|
||||
error(result, 2)
|
||||
end
|
||||
|
||||
if coroutine.status(PRIVATE.BUILD_COROUTINE) == "dead" then
|
||||
PRIVATE.BUILD_COROUTINE = nil
|
||||
else
|
||||
if PRIVATE.BUILD_COROUTINE_DEBUG then print("AJ_BUILD_COROUTINE", progress) end
|
||||
PRIVATE.eventHandler:Show()
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetNumPrimarySuggestions = function()
|
||||
if PRIVATE.SUGGESTIONS[ADVENTURE_TYPE.PRIMARY] then
|
||||
return #PRIVATE.SUGGESTIONS[ADVENTURE_TYPE.PRIMARY]
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
PRIVATE.GetNumSecondarySuggestions = function()
|
||||
if PRIVATE.SUGGESTIONS[ADVENTURE_TYPE.SECONDARY] then
|
||||
return #PRIVATE.SUGGESTIONS[ADVENTURE_TYPE.SECONDARY]
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
PRIVATE.GetButtonText = function(suggestion)
|
||||
if suggestion.actionType == ACTION_BUTTON_TYPE.NONE then
|
||||
-- skip
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.QUEST_START then
|
||||
return AJ_ACTION_TEXT_START_QUEST
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_ARENA_RATING
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_RANDOM
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_WINTERGRASP
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_BRAWL
|
||||
then
|
||||
return AJ_ACTION_TEXT_JOIN_BATTLE
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_RANDOM
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_ID
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_MINIGAME_ID
|
||||
then
|
||||
return AJ_ACTION_TEXT_JOIN_GROUP
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_EJ_DUNGEON_ID then
|
||||
return AJ_ACTION_TEXT_OPEN_EJ
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_BATTLEPASS_QUESTS then
|
||||
return AJ_ACTION_TEXT_SHOW_QUEST
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_HEAD_HUNTING then
|
||||
return AJ_ACTION_TEXT_START_HUNT
|
||||
end
|
||||
end
|
||||
|
||||
local ACTION_TARGET_VIEW = {
|
||||
[ACTION_BUTTON_TYPE.UI_PVP_ARENA_RATING] = "pvp-arena-rating",
|
||||
[ACTION_BUTTON_TYPE.UI_PVP_HONOR_RANDOM] = "pvp-honor-random",
|
||||
[ACTION_BUTTON_TYPE.UI_PVP_HONOR_WINTERGRASP] = "pvp-honor-wintergrasp",
|
||||
[ACTION_BUTTON_TYPE.UI_PVP_HONOR_BRAWL] = "pvp-honor-brawl",
|
||||
|
||||
[ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_RANDOM] = "pve-lfg-dungeon",
|
||||
[ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_ID] = "pve-lfg-dungeon",
|
||||
[ACTION_BUTTON_TYPE.UI_PVE_LFG_MINIGAME_ID] = "pve-lfg-minigame",
|
||||
}
|
||||
|
||||
PRIVATE.ActivateEntry = function(suggestion)
|
||||
if suggestion.actionType == ACTION_BUTTON_TYPE.NONE then
|
||||
-- skip
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.QUEST_START then
|
||||
local questID = suggestion.actionParam
|
||||
if questID then
|
||||
QueryQuestStart(questID, Enum.QueryQuestStartSource.Suggestion, suggestion.id)
|
||||
-- FireCustomClientEvent("AJ_QUEST_LOG_OPEN", questID or 0, uiMapID or 0)
|
||||
else
|
||||
GMError(string.format("[Suggestion::ActivateEntry] no quest id to start [suggestionID=%d]", suggestion.id))
|
||||
end
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_ARENA_RATING
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_RANDOM
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_WINTERGRASP
|
||||
or suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVP_HONOR_BRAWL
|
||||
then
|
||||
local desiredViewType = ACTION_TARGET_VIEW[suggestion.actionType]
|
||||
FireCustomClientEvent("AJ_ACTION_PVP_LFG", desiredViewType)
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_RANDOM then
|
||||
for i, lfgDungeonID in ipairs({258, 259, 261}) do
|
||||
if IsLFGDungeonJoinable(lfgDungeonID) then
|
||||
local desiredViewType = ACTION_TARGET_VIEW[suggestion.actionType]
|
||||
FireCustomClientEvent("AJ_ACTION_PVE_LFG", desiredViewType, lfgDungeonID)
|
||||
return
|
||||
end
|
||||
end
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_DUNGEON_ID then
|
||||
local desiredViewType = ACTION_TARGET_VIEW[suggestion.actionType]
|
||||
local lfgDungeonID = suggestion.actionParam or 0
|
||||
if IsLFGDungeonJoinable(lfgDungeonID) then
|
||||
FireCustomClientEvent("AJ_ACTION_PVE_LFG", desiredViewType, lfgDungeonID)
|
||||
end
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_PVE_LFG_MINIGAME_ID then
|
||||
local desiredViewType = ACTION_TARGET_VIEW[suggestion.actionType]
|
||||
local minigameID = suggestion.actionParam or 0
|
||||
FireCustomClientEvent("AJ_ACTION_PVE_LFG", desiredViewType, minigameID)
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_EJ_DUNGEON_ID then
|
||||
local dungeonID = suggestion.actionParam or 0
|
||||
local difficultyID = suggestion.actionParam2 or -1
|
||||
FireCustomClientEvent("AJ_ACTION_EJ_DUNGEON", dungeonID, difficultyID)
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_BATTLEPASS_QUESTS then
|
||||
local showQuestTab = true
|
||||
FireCustomClientEvent("AJ_ACTION_BATTLE_PASS", showQuestTab)
|
||||
elseif suggestion.actionType == ACTION_BUTTON_TYPE.UI_HEAD_HUNTING then
|
||||
FireCustomClientEvent("AJ_ACTION_HEAD_HUNTING")
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetSuggestionEntry = function(suggestionType, index)
|
||||
if PRIVATE.SUGGESTIONS[suggestionType] then
|
||||
return PRIVATE.SUGGESTIONS[suggestionType][index]
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetSuggestionEntryByID = function(suggestionType, id)
|
||||
if PRIVATE.SUGGESTIONS[suggestionType] then
|
||||
for index, suggestion in ipairs(PRIVATE.SUGGESTIONS[suggestionType]) do
|
||||
if suggestion.id == id then
|
||||
return suggestion, index
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.OnItemLoaded = function()
|
||||
FireCustomClientEvent("AJ_REWARD_DATA_RECEIVED")
|
||||
end
|
||||
|
||||
PRIVATE.OnItemLoadedContent = function()
|
||||
FireCustomClientEvent("AJ_REFRESH_DISPLAY", false)
|
||||
end
|
||||
|
||||
PRIVATE.OnQuestLoadedContent = function(questID)
|
||||
FireCustomClientEvent("AJ_REFRESH_DISPLAY", false)
|
||||
end
|
||||
|
||||
PRIVATE.GetQuestLink = function(questID)
|
||||
questID = tonumber(questID)
|
||||
|
||||
if IsQuestDataCached(questID) then
|
||||
local questLink = GetQuestLinkByID(questID)
|
||||
if questLink then
|
||||
questLink = strgsub(questLink, COLOR_PATTERN, "|cff8B0000|H")
|
||||
return questLink
|
||||
end
|
||||
else
|
||||
RequestQuestCacheByID(questID, PRIVATE.OnQuestLoadedContent)
|
||||
end
|
||||
|
||||
local name = GetTitleForQuestID(questID)
|
||||
if not name then
|
||||
name = IsGMAccount() and strformat("%s (quest:%s)", UNKNOWN, questID) or UNKNOWN
|
||||
end
|
||||
return strformat("|cff8B0000|Hquest:%d:-1|h[%s]|h|r", questID, name)
|
||||
end
|
||||
|
||||
PRIVATE.GetItemLink = function(itemID)
|
||||
itemID = tonumber(itemID)
|
||||
local name, link = C_Item.GetItemInfo(itemID, nil, PRIVATE.OnItemLoadedContent, true)
|
||||
if not link then
|
||||
name = IsGMAccount() and strformat("%s (item:%s)", UNKNOWN, itemID) or UNKNOWN
|
||||
return strformat("|cffffffff[%s]|r", name)
|
||||
end
|
||||
return link
|
||||
end
|
||||
|
||||
PRIVATE.GetSpellLink = function(spellID)
|
||||
spellID = tonumber(spellID)
|
||||
local name = GetSpellInfo(spellID)
|
||||
if not name then
|
||||
name = IsGMAccount() and strformat("%s (spell:%s)", UNKNOWN, spellID) or UNKNOWN
|
||||
return strformat("|cffffffff[%s]|r", name)
|
||||
end
|
||||
return strformat("|cff000080|Hspell:%d|h[%s]|h|r", spellID, name)
|
||||
end
|
||||
|
||||
PRIVATE.GetSuggestionInfo = function(suggestionType, index)
|
||||
local suggestion = PRIVATE.GetSuggestionEntry(suggestionType, index)
|
||||
if suggestion then
|
||||
local description = suggestion.content
|
||||
|
||||
if description then
|
||||
description = strgsub(description, "{quest:(%d+)}", PRIVATE.GetQuestLink)
|
||||
description = strgsub(description, "{item:(%d+)}", PRIVATE.GetItemLink)
|
||||
description = strgsub(description, "{spell:(%d+)}", PRIVATE.GetSpellLink)
|
||||
end
|
||||
|
||||
return {
|
||||
title = suggestion.title,
|
||||
description = description,
|
||||
buttonText = PRIVATE.GetButtonText(suggestion),
|
||||
iconPath = suggestion.icon and strconcat([[Interface\Icons\]], suggestion.icon) or QUESTION_MARK_ICON,
|
||||
ej_instanceID = suggestion.ej_instanceID,
|
||||
difficultyID = suggestion.ej_difficultyID or 1,
|
||||
expansionLevel = suggestion.ej_expansionLevel,
|
||||
isRandomDungeon = suggestion.ej_isRandomDungeon,
|
||||
hideDifficulty = suggestion.ej_showDifficulty ~= 1,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetSuggestionByIndex = function(suggestionIndex)
|
||||
if suggestionIndex <= 1 then
|
||||
return PRIVATE.GetSuggestionEntry(ADVENTURE_TYPE.PRIMARY, PRIVATE.PRIMARY_OFFSET_INDEX)
|
||||
else
|
||||
return PRIVATE.GetSuggestionEntry(ADVENTURE_TYPE.SECONDARY, suggestionIndex - 1)
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetReward = function(suggestion)
|
||||
if not suggestion then
|
||||
return
|
||||
end
|
||||
|
||||
local numRewards = #suggestion.rewards
|
||||
|
||||
if numRewards > 0 then
|
||||
if numRewards == 1 and suggestion.rewardDesc then
|
||||
local itemName, itemLink, itemRarity, iLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, vendorPrice = C_Item.GetItemInfo(suggestion.rewards[1], nil, PRIVATE.OnItemLoaded, true)
|
||||
local rewardDesc = type(suggestion.rewardDesc) == "string" and suggestion.rewardDesc or AJ_PRIMARY_REWARD_TEXT
|
||||
|
||||
return {
|
||||
isRewardTable = false,
|
||||
rewardDesc = rewardDesc,
|
||||
itemLink = itemLink,
|
||||
itemIcon = itemTexture,
|
||||
itemQuantity = 1,
|
||||
}
|
||||
else
|
||||
local rewards = {}
|
||||
|
||||
for index, itemID in ipairs(suggestion.rewards) do
|
||||
local itemName, itemLink, itemRarity, iLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, vendorPrice = C_Item.GetItemInfo(suggestion.rewards[index], nil, PRIVATE.OnItemLoaded, true)
|
||||
if itemLink then
|
||||
tinsert(rewards, {
|
||||
itemLink = itemLink,
|
||||
itemIcon = itemTexture,
|
||||
itemQuantity = 1,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if #rewards > 0 then
|
||||
rewards.isRewardList = true
|
||||
return rewards
|
||||
end
|
||||
end
|
||||
elseif false then -- currency item
|
||||
return {
|
||||
isRewardTable = false,
|
||||
rewardDesc = AJ_PRIMARY_REWARD_TEXT,
|
||||
currencyIcon = nil,
|
||||
currencyQuantity = nil,
|
||||
currencyIcon = nil,
|
||||
}
|
||||
else
|
||||
local minItemLevel = suggestion.reward_minItemLevel
|
||||
local maxItemLevel = suggestion.reward_maxItemLevel
|
||||
local itemLevel = suggestion.reward_itemLevel
|
||||
|
||||
if itemLevel or minItemLevel or maxItemLevel then
|
||||
if itemLevel then
|
||||
minItemLevel = nil
|
||||
maxItemLevel = nil
|
||||
elseif not minItemLevel or not maxItemLevel then
|
||||
minItemLevel = nil
|
||||
maxItemLevel = nil
|
||||
itemLevel = minItemLevel or maxItemLevel
|
||||
end
|
||||
|
||||
return {
|
||||
isRewardTable = true,
|
||||
itemLevel = itemLevel,
|
||||
minItemLevel = minItemLevel,
|
||||
maxItemLevel = maxItemLevel,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
PRIVATE.GetUniqueSuggestionIDs = function()
|
||||
local suggestionIDs = {}
|
||||
|
||||
for adventureType, registry in ipairs(PRIVATE.REGISTRY) do
|
||||
suggestionIDs[adventureType] = {}
|
||||
|
||||
for index, entry in ipairs(registry) do
|
||||
suggestionIDs[adventureType][entry.id] = true
|
||||
end
|
||||
end
|
||||
|
||||
return suggestionIDs
|
||||
end
|
||||
|
||||
do
|
||||
if IsInterfaceDevClient() then
|
||||
PRIVATE.BUILD_COROUTINE_DEBUG = true
|
||||
PRIVATE_AJ = PRIVATE
|
||||
end
|
||||
PRIVATE.Initialize()
|
||||
end
|
||||
|
||||
C_AdventureJournal = {}
|
||||
|
||||
function C_AdventureJournal.ReloadData()
|
||||
if IsInterfaceDevClient() then
|
||||
if _G.ADVENTURE_REGISTRY and PRIVATE.initialized then
|
||||
PRIVATE.initialized = nil
|
||||
twipe(PRIVATE.REGISTRY)
|
||||
PRIVATE.Initialize()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function C_AdventureJournal.CanBeShown()
|
||||
return true
|
||||
end
|
||||
|
||||
function C_AdventureJournal.UpdateSuggestions(isLevelUp)
|
||||
PRIVATE.UpdateSuggestions(not not isLevelUp)
|
||||
end
|
||||
|
||||
function C_AdventureJournal.SetPrimaryOffset(offset)
|
||||
if type(offset) ~= "number" then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.SetPrimaryOffset' (number expected, got %s)", offset ~= nil and type(offset) or "no value"), 2)
|
||||
end
|
||||
|
||||
offset = offset + 1
|
||||
|
||||
if offset < 1 or offset > PRIVATE.GetNumPrimarySuggestions() then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.SetPrimaryOffset' (index %s out of range [1 - %s])", offset, PRIVATE.GetNumPrimarySuggestions()), 2)
|
||||
end
|
||||
|
||||
if offset == PRIVATE.PRIMARY_OFFSET_INDEX then
|
||||
return
|
||||
end
|
||||
|
||||
local suggestion = PRIVATE.GetSuggestionEntry(ADVENTURE_TYPE.PRIMARY, offset)
|
||||
if suggestion then
|
||||
PRIVATE.PRIMARY_OFFSET_INDEX = offset
|
||||
PRIVATE.PRIMARY_OFFSET_ID = suggestion.id
|
||||
FireCustomClientEvent("AJ_REFRESH_DISPLAY", false)
|
||||
end
|
||||
end
|
||||
|
||||
function C_AdventureJournal.GetPrimaryOffset()
|
||||
return PRIVATE.PRIMARY_OFFSET_INDEX - 1
|
||||
end
|
||||
|
||||
function C_AdventureJournal.GetNumAvailableSuggestions()
|
||||
return PRIVATE.GetNumPrimarySuggestions()
|
||||
end
|
||||
|
||||
function C_AdventureJournal.GetSuggestions(suggestionTable)
|
||||
if type(suggestionTable) ~= "table" then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.GetSuggestions' (table expected, got %s)", suggestionTable ~= nil and type(suggestionTable) or "no value"), 2)
|
||||
end
|
||||
|
||||
twipe(suggestionTable)
|
||||
|
||||
if PRIVATE.GetNumPrimarySuggestions() > 0 then
|
||||
local suggestion = PRIVATE.GetSuggestionInfo(ADVENTURE_TYPE.PRIMARY, PRIVATE.PRIMARY_OFFSET_INDEX)
|
||||
if suggestion then
|
||||
tinsert(suggestionTable, suggestion)
|
||||
end
|
||||
end
|
||||
|
||||
for index = 1, mathmin(NUM_SECONDARY_SUGGESTIONS, PRIVATE.GetNumSecondarySuggestions()) do
|
||||
local suggestion = PRIVATE.GetSuggestionInfo(ADVENTURE_TYPE.SECONDARY, index)
|
||||
if suggestion then
|
||||
tinsert(suggestionTable, suggestion)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function C_AdventureJournal.GetReward(suggestionIndex)
|
||||
if type(suggestionIndex) ~= "number" then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.GetReward' (number expected, got %s)", suggestionIndex ~= nil and type(suggestionIndex) or "no value"), 2)
|
||||
elseif suggestionIndex < 1 or suggestionIndex > NUM_SECONDARY_SUGGESTIONS + 1 then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.GetReward' (index %s out of range [1 - %s])", suggestionIndex, NUM_SECONDARY_SUGGESTIONS + 1), 2)
|
||||
end
|
||||
|
||||
return PRIVATE.GetReward(PRIVATE.GetSuggestionByIndex(suggestionIndex))
|
||||
end
|
||||
|
||||
function C_AdventureJournal.ActivateEntry(suggestionIndex)
|
||||
if type(suggestionIndex) ~= "number" then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.ActivateEntry' (number expected, got %s)", suggestionIndex ~= nil and type(suggestionIndex) or "no value"), 2)
|
||||
elseif suggestionIndex < 1 or suggestionIndex > NUM_SECONDARY_SUGGESTIONS + 1 then
|
||||
error(strformat("bad argument #1 to 'C_AdventureJournal.ActivateEntry' (index %s out of range [1 - %s])", suggestionIndex, NUM_SECONDARY_SUGGESTIONS + 1), 2)
|
||||
end
|
||||
|
||||
local suggestion = PRIVATE.GetSuggestionByIndex(suggestionIndex)
|
||||
if suggestion then
|
||||
PRIVATE.ActivateEntry(suggestion)
|
||||
end
|
||||
end
|
||||
+5
@@ -1694,6 +1694,11 @@ do -- Section
|
||||
if not abilityIcon and sectionInfo[ENCOUNTER_SECTION_FIELD.ICON_SPELL_ID] > 0 then
|
||||
abilityIcon = select(3, GetSpellInfo(sectionInfo[ENCOUNTER_SECTION_FIELD.ICON_SPELL_ID]))
|
||||
end
|
||||
if not abilityIcon and
|
||||
(sectionInfo[ENCOUNTER_SECTION_FIELD.DESCRIPTION_SPELL_ID] > 0 or
|
||||
sectionInfo[ENCOUNTER_SECTION_FIELD.ICON_SPELL_ID] > 0) then
|
||||
abilityIcon = QUESTION_MARK_ICON
|
||||
end
|
||||
|
||||
if sectionInfo[ENCOUNTER_SECTION_FIELD.DIFFCULTY_MASK] ~= -1 then
|
||||
local difficultyMask = PRIVATE.GetDifficultyMask(PRIVATE.SELECTED_DIFFICULTY)
|
||||
|
||||
@@ -9,12 +9,7 @@
|
||||
## X-Hidden: 1
|
||||
|
||||
MoonWellClient.lua
|
||||
EncounterJournal\SharedXML\ClientDataGenerated\Generated_ItemsCache1.lua
|
||||
EncounterJournal\SharedXML\ClientDataGenerated\Generated_ItemsCache2.lua
|
||||
EncounterJournal\SharedXML\ClientDataGenerated\Generated_ItemsCache3.lua
|
||||
EncounterJournal\EncounterJournalCompat.lua
|
||||
EncounterJournal\SharedXML\Pools.lua
|
||||
EncounterJournal\SharedXML\TableUtil.lua
|
||||
EncounterJournal\SharedXML\SoundKitConstants.lua
|
||||
EncounterJournal\Generated_EncounterJournalData.lua
|
||||
EncounterJournal\EncounterJournalData.lua
|
||||
@@ -22,23 +17,15 @@ EncounterJournal\EncounterJournalTierFilter.lua
|
||||
EncounterJournal\EncounterJournalTierSnapshot.lua
|
||||
EncounterJournal\GlobalStrings.lua
|
||||
EncounterJournal\Utils\C_EncounterJournal.lua
|
||||
EncounterJournal\Utils\C_AdventureJournal.lua
|
||||
EncounterJournal\Utils\C_PlayerGuide.lua
|
||||
EncounterJournal\EncounterJournalInit.lua
|
||||
EncounterJournal\EncounterJournalFrameMethods.lua
|
||||
EncounterJournal\EncounterJournalFonts.xml
|
||||
EncounterJournal\SharedXML\SharedTooltipTemplates.xml
|
||||
EncounterJournal\SharedXML\TableBuilder.lua
|
||||
EncounterJournal\SharedXML\EventHandler.lua
|
||||
EncounterJournal\SharedXML\SharedUIPanelTemplates.xml
|
||||
EncounterJournal\SharedXML\SharedUIPanelPKBTTemplates.xml
|
||||
EncounterJournal\SharedXML\HybridScrollFrame.xml
|
||||
EncounterJournal\SharedXML\NavigationBar.xml
|
||||
EncounterJournal\Custom_EncounterJournal\Custom_EncounterJournal.lua
|
||||
EncounterJournal\Custom_EncounterJournal\Custom_EncounterJournal.xml
|
||||
EncounterJournal\Custom_EncounterJournal\PlayerGuide.xml
|
||||
EncounterJournal\Custom_EncounterJournal\Custom_LootJournalItems.xml
|
||||
EncounterJournal\Custom_EncounterJournal\Custom_ItemBrowser.xml
|
||||
EncounterJournal\EncounterJournalScrollFix.lua
|
||||
EncounterJournal\EncounterJournalDungeonMode.lua
|
||||
EncounterJournal\EncounterJournalOpen.lua
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user