chore: hoist plugins to root and move main into Details/
Each Details_* plugin and the main Details addon now lives in its own repo-root folder, matching the Exiles fork-layout convention.
This commit is contained in:
@@ -0,0 +1,409 @@
|
||||
local _detalhes = _G.Details
|
||||
|
||||
--code from blizzard AlertFrames
|
||||
|
||||
function _detalhes:PlayGlow (frame)
|
||||
frame:Show()
|
||||
|
||||
frame.glow:Show()
|
||||
frame.glow.animIn:Play()
|
||||
frame.shine:Show()
|
||||
frame.shine.animIn:Play()
|
||||
|
||||
--PlaySound ("LFG_Rewards", "master")
|
||||
end
|
||||
|
||||
--WatchFrame copy, got removed on WoD
|
||||
local function DetailsTutorialAlertFrame_OnFinishSlideIn (frame)
|
||||
frame.ScrollChild.Shine:Show();
|
||||
frame.ScrollChild.IconShine:Show();
|
||||
frame.ScrollChild.Shine.Flash:Play();
|
||||
frame.ScrollChild.IconShine.Flash:Play();
|
||||
end
|
||||
|
||||
local function DetailsTutorialAlertFrame_OnUpdate (frame, timestep)
|
||||
local animData = frame.animData;
|
||||
local height = animData.height;
|
||||
local scrollStart = animData.scrollStart;
|
||||
local scrollEnd = animData.scrollEnd;
|
||||
local endTime = animData.slideInTime + (animData.endDelay or 0);
|
||||
|
||||
if (frame.startDelay) then
|
||||
frame.startDelay = frame.startDelay - timestep;
|
||||
if (frame.startDelay <= 0) then
|
||||
frame.startDelay = nil;
|
||||
else
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (frame.isFirst) then
|
||||
height = height + 10;
|
||||
scrollEnd = scrollEnd - 10;
|
||||
end
|
||||
|
||||
frame.totalTime = frame.totalTime+timestep;
|
||||
if (frame.totalTime > endTime) then
|
||||
frame.totalTime = endTime;
|
||||
end
|
||||
|
||||
local scrollPos = scrollEnd;
|
||||
if (animData.slideInTime and animData.slideInTime > 0) then
|
||||
height = height*(frame.totalTime/animData.slideInTime);
|
||||
scrollPos = scrollStart + (scrollEnd-scrollStart)*(frame.totalTime/animData.slideInTime);
|
||||
end
|
||||
if ( animData.reverse ) then
|
||||
height = max(animData.height - height, 1);
|
||||
end
|
||||
frame:SetHeight(height);
|
||||
frame:UpdateScrollChildRect();
|
||||
frame:SetVerticalScroll(floor(scrollPos+0.5));
|
||||
|
||||
if (frame.totalTime >= endTime) then
|
||||
frame:SetScript("OnUpdate", nil);
|
||||
if ( animData.onFinishFunc ) then
|
||||
animData.onFinishFunc(frame);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DetailsTutorialAlertFrame_SlideInFrame (frame, animType)
|
||||
frame.totalTime = 0;
|
||||
frame.animData = { height = 72, scrollStart = 65, scrollEnd = -9, slideInTime = 0.4, onFinishFunc = DetailsTutorialAlertFrame_OnFinishSlideIn };
|
||||
frame.slideInTime = frame.animData.slideInTime;
|
||||
frame:SetHeight(1);
|
||||
if ( frame.animData.reverse ) then
|
||||
frame:SetHeight(frame.animData["height"]);
|
||||
else
|
||||
frame:SetHeight(1);
|
||||
end
|
||||
frame.startDelay = frame.animData.startDelay;
|
||||
frame:SetScript("OnUpdate", DetailsTutorialAlertFrame_OnUpdate);
|
||||
end
|
||||
|
||||
function _detalhes.PlayBestDamageOnGuild (damage)
|
||||
|
||||
damage = damage or 100000000
|
||||
|
||||
--create the main frame
|
||||
local DetailsNewDamageRecord = CreateFrame("frame", "DetailsNewDamageRecordAnimationFrame", UIParent)
|
||||
DetailsNewDamageRecord:SetPoint("CENTER", UIParent, "CENTER", 0, -200)
|
||||
DetailsNewDamageRecord:SetSize(300, 300)
|
||||
|
||||
--single animation group
|
||||
local MainAnimationGroup = {
|
||||
Play = function()
|
||||
for _, animGroup in ipairs(self) do
|
||||
if animGroup.Play then
|
||||
animGroup.Play()
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--widgets:
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
local BaseTexture = DetailsNewDamageRecord:CreateTexture("BaseTextureTexture", "ARTWORK")
|
||||
BaseTexture:SetTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Alert-Background-Mini]])
|
||||
BaseTexture:SetDrawLayer("ARTWORK", -5)
|
||||
BaseTexture:SetPoint("center", DetailsNewDamageRecord, "center", 0, 0)
|
||||
BaseTexture:SetSize(256, 64)
|
||||
BaseTexture:SetVertexColor(0.99999779462814, 0.99999779462814, 0.99999779462814, 0.99999779462814)
|
||||
|
||||
--animations for BaseTexture
|
||||
|
||||
do
|
||||
local animGroup = BaseTexture:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration(0)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.14869952201843)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetStartDelay (5)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
----------------------------------------------
|
||||
|
||||
local BigFlash = DetailsNewDamageRecord:CreateTexture("BigFlashTexture", "OVERLAY")
|
||||
BigFlash:SetTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Alert-Glow]])
|
||||
BigFlash:SetDrawLayer("OVERLAY", 0)
|
||||
BigFlash:SetPoint("center", DetailsNewDamageRecord, "center", -2, 2)
|
||||
BigFlash:SetSize(314, 100)
|
||||
BigFlash:SetDesaturated(false)
|
||||
BigFlash:SetTexCoord(0.0010000000149012, 0.77400001525879, 0.0010000000149012, 0.65800003051758)
|
||||
if (0 ~= 0) then
|
||||
BigFlash:SetRotation (0)
|
||||
end
|
||||
BigFlash:SetVertexColor(0.96470373868942, 0.98823314905167, 0.99999779462814, 0.99999779462814)
|
||||
BigFlash:SetAlpha(1)
|
||||
BigFlash:SetBlendMode("ADD")
|
||||
|
||||
--animations for BigFlash
|
||||
do
|
||||
local animGroup = BigFlash:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration(0)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.11600000411272)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(0.31600001454353)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
local FlashSwipe = DetailsNewDamageRecord:CreateTexture("FlashSwipeTexture", "OVERLAY")
|
||||
FlashSwipe:SetTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Alert-Glow]])
|
||||
FlashSwipe:SetDrawLayer("OVERLAY", 7)
|
||||
FlashSwipe:SetPoint("center", DetailsNewDamageRecord, "center", -99, 0)
|
||||
FlashSwipe:SetSize(100, 57)
|
||||
FlashSwipe:SetDesaturated(false)
|
||||
FlashSwipe:SetTexCoord(0.78199996948242, 0.91900001525879, 0.0010000000149012, 0.2760000038147)
|
||||
if (0 ~= 0) then
|
||||
FlashSwipe:SetRotation (0)
|
||||
end
|
||||
FlashSwipe:SetVertexColor(0.86666476726532, 0.54117530584335, 0, 0.99999779462814)
|
||||
FlashSwipe:SetAlpha(1)
|
||||
FlashSwipe:SetBlendMode("ADD")
|
||||
|
||||
--animations for FlashSwipe
|
||||
do
|
||||
local animGroup = FlashSwipe:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetTarget (FlashSwipe)
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration()
|
||||
alpha:SetStartDelay ()
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.31600001454353)
|
||||
alpha:SetStartDelay (0.20000000298023)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(0.501051902771)
|
||||
|
||||
local translation = animGroup:CreateAnimation("TRANSLATION")
|
||||
translation:SetOrder (2)
|
||||
translation:SetDuration(0.81599998474121)
|
||||
translation:SetStartDelay (0.20000000298023)
|
||||
translation:SetEndDelay (0)
|
||||
translation:SetOffset (200, 0)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(0.31600001454353)
|
||||
alpha:SetStartDelay (0.69999998807907)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-0.501051902771)
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
local Portrait = DetailsNewDamageRecord:CreateTexture("PortraitTexture", "OVERLAY")
|
||||
Portrait:SetTexture([[Interface\ARCHEOLOGY\ARCH-FLAREEFFECT]])
|
||||
Portrait:SetDrawLayer("OVERLAY", -5)
|
||||
Portrait:SetPoint("center", DetailsNewDamageRecord, "center", 3, 0)
|
||||
Portrait:SetSize(246, 44)
|
||||
Portrait:SetDesaturated(false)
|
||||
Portrait:SetTexCoord(0.051753740310669, 0.81701484680176, 0.086334381103516, 0.25102617263794)
|
||||
if (0 ~= 0) then
|
||||
Portrait:SetRotation (0)
|
||||
end
|
||||
Portrait:SetVertexColor(0.99999779462814, 0.99999779462814, 0.99999779462814, 0.99999779462814)
|
||||
Portrait:SetAlpha(1)
|
||||
Portrait:SetBlendMode("BLEND")
|
||||
|
||||
--animations for Portrait
|
||||
do
|
||||
local animGroup = Portrait:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration(0)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.41600000858307)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(1)
|
||||
|
||||
local scale = animGroup:CreateAnimation("SCALE")
|
||||
scale:SetOrder (1)
|
||||
scale:SetDuration(0)
|
||||
scale:SetStartDelay (0)
|
||||
scale:SetEndDelay (0)
|
||||
scale:SetScale (0.01, 0.01)
|
||||
scale:SetOrigin ("center", 0, 0)
|
||||
|
||||
scale = animGroup:CreateAnimation("SCALE")
|
||||
scale:SetOrder (2)
|
||||
scale:SetDuration(0.21600000560284)
|
||||
scale:SetStartDelay (0)
|
||||
scale:SetEndDelay (0)
|
||||
scale:SetScale(100, 100)
|
||||
scale:SetOrigin ("center", 0, 0)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetStartDelay (4.7000002861023)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
local DamageIcon = DetailsNewDamageRecord:CreateTexture("DamageIconTexture", "OVERLAY")
|
||||
DamageIcon:SetTexture([[Interface\LFGFRAME\UI-LFG-ICON-ROLES]])
|
||||
DamageIcon:SetDrawLayer("OVERLAY", 2)
|
||||
DamageIcon:SetPoint("center", DetailsNewDamageRecord, "center", -97, 1)
|
||||
DamageIcon:SetSize(32, 32)
|
||||
DamageIcon:SetDesaturated(false)
|
||||
DamageIcon:SetTexCoord(0.27200000762939, 0.51899997711182, 0.25837841033936, 0.51399997711182)
|
||||
if (0 ~= 0) then
|
||||
DamageIcon:SetRotation (0)
|
||||
end
|
||||
DamageIcon:SetVertexColor(0.99999779462814, 0.99999779462814, 0.99999779462814, 0.99999779462814)
|
||||
DamageIcon:SetAlpha(1)
|
||||
DamageIcon:SetBlendMode("BLEND")
|
||||
|
||||
--animations for DamageIcon
|
||||
do
|
||||
local animGroup = DamageIcon:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration(0)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.51599997282028)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetStartDelay (4.5999999046326)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
local NewDamageRecord = DetailsNewDamageRecord:CreateFontString("NewDamageRecordFontString", "OVERLAY")
|
||||
NewDamageRecord:SetFont([=[Fonts\FRIZQT__.TTF]=], 12, "OUTLINE")
|
||||
NewDamageRecord:SetText("Damage Record!")
|
||||
NewDamageRecord:SetDrawLayer("OVERLAY", 0)
|
||||
NewDamageRecord:SetPoint("center", DetailsNewDamageRecord, "center", 18, 7)
|
||||
NewDamageRecord:SetSize(181, 20)
|
||||
NewDamageRecord:SetTextColor(1, 1, 1)
|
||||
NewDamageRecord:SetAlpha(1)
|
||||
NewDamageRecord:SetJustifyH("CENTER")
|
||||
|
||||
--animations for NewDamageRecord
|
||||
do
|
||||
local animGroup = NewDamageRecord:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0.016000000759959)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.51599997282028)
|
||||
alpha:SetStartDelay (0.40000000596046)
|
||||
alpha:SetEndDelay (4.0999999046326)
|
||||
alpha:SetChange(1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetStartDelay (0.10000000149012)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
----------------------------------------------
|
||||
|
||||
local DamageAmount = DetailsNewDamageRecord:CreateFontString("DamageAmountFontString", "OVERLAY")
|
||||
DamageAmount:SetFont([=[Fonts\FRIZQT__.TTF]=], 12, "THICKOUTLINE")
|
||||
DamageAmount:SetText(_detalhes:comma_value (damage))
|
||||
DamageAmount:SetDrawLayer("OVERLAY", 0)
|
||||
DamageAmount:SetPoint("center", DetailsNewDamageRecord, "center", 18, -7)
|
||||
DamageAmount:SetSize(100, 20)
|
||||
DamageAmount:SetTextColor(1, 1, 1)
|
||||
DamageAmount:SetAlpha(1)
|
||||
DamageAmount:SetJustifyH("CENTER")
|
||||
|
||||
--animations for DamageAmount
|
||||
do
|
||||
local animGroup = DamageAmount:CreateAnimationGroup()
|
||||
tinsert(MainAnimationGroup, animGroup)
|
||||
local alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (1)
|
||||
alpha:SetDuration(0)
|
||||
alpha:SetStartDelay (0)
|
||||
alpha:SetEndDelay (0.016000000759959)
|
||||
alpha:SetChange(-1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (2)
|
||||
alpha:SetDuration(0.51599997282028)
|
||||
alpha:SetStartDelay (0.40000000596046)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(1)
|
||||
|
||||
alpha = animGroup:CreateAnimation("ALPHA")
|
||||
alpha:SetOrder (3)
|
||||
alpha:SetDuration(1.0160000324249)
|
||||
alpha:SetStartDelay (4.2000002861023)
|
||||
alpha:SetEndDelay (0)
|
||||
alpha:SetChange(-1)
|
||||
end
|
||||
--test the animation
|
||||
MainAnimationGroup:Play()
|
||||
end
|
||||
@@ -0,0 +1,423 @@
|
||||
<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">
|
||||
|
||||
<!-- code copied from blizzard's AlertFrames -->
|
||||
|
||||
<Frame name="DetailsAlert" virtual="true">
|
||||
<Scripts>
|
||||
<OnHide function="AlertFrame_FixAnchors"/>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<Frame name="DetailsAlertRankUpTemplate" virtual="true">
|
||||
|
||||
<Size>
|
||||
<AbsDimension x="296" y="74"/>
|
||||
</Size>
|
||||
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
|
||||
<Animations>
|
||||
<AnimationGroup name="$parentAnimIn" parentKey="animIn">
|
||||
<Alpha duration="0" order="1"/>
|
||||
<Alpha duration="0.2" order="2"/>
|
||||
</AnimationGroup>
|
||||
<AnimationGroup name="$parentWaitAndAnimOut" parentKey="waitAndAnimOut">
|
||||
<Alpha startDelay="4.05" duration="1.5" parentKey="animOut">
|
||||
<Scripts>
|
||||
<OnFinished>
|
||||
self:GetRegionParent():Hide();
|
||||
</OnFinished>
|
||||
</Scripts>
|
||||
</Alpha>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentGlow" file="Interface\AchievementFrame\UI-Achievement-Alert-Glow" alphaMode="ADD" hidden="true" parentKey="glow">
|
||||
<Size>
|
||||
<AbsDimension x="400" y="171"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER">
|
||||
<Offset x="0" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Animations>
|
||||
<AnimationGroup name="$parentAnimIn" parentKey="animIn">
|
||||
<Alpha duration="0.2" order="1"/>
|
||||
<Alpha duration="0.5" order="2"/>
|
||||
<Scripts>
|
||||
<OnFinished>
|
||||
self:GetParent():Hide();
|
||||
</OnFinished>
|
||||
</Scripts>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
<TexCoords left="0" right="0.78125" top="0" bottom="0.66796875"/>
|
||||
</Texture>
|
||||
<Texture name="$parentShine" file="Interface\AchievementFrame\UI-Achievement-Alert-Glow" alphaMode="ADD" hidden="true" parentKey="shine">
|
||||
<Size>
|
||||
<AbsDimension x="67" y="72"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset x="-20" y="1"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Animations>
|
||||
<AnimationGroup name="$parentAnimIn" parentKey="animIn">
|
||||
<Alpha duration="0.2" order="1"/>
|
||||
<Translation offsetX="200" offsetY="0" duration="0.85" order="2"/>
|
||||
<Alpha startDelay="0.35" duration="0.5" order="2"/>
|
||||
<Scripts>
|
||||
<OnFinished>
|
||||
self:GetParent():Hide();
|
||||
</OnFinished>
|
||||
</Scripts>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
<TexCoords left="0.78125" right="0.912109375" top="0" bottom="0.28125"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
|
||||
</Frame>
|
||||
|
||||
<!-- WatchFrame copy, got removed on WoD -->
|
||||
<ScrollFrame name="DetailsTutorialAlertFrameTemplate" enableMouse="true" virtual="true">
|
||||
<Size x="224" y="72"/>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:SetHorizontalScroll(-28.5);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
<ScrollChild>
|
||||
<Frame name="$parentScrollChild" parentKey="ScrollChild">
|
||||
<Size x="190" y="60"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBg" setAllPoints="true">
|
||||
<Color r="0" g="0" b="0" a="0.5"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentBorderTopLeft" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.02539063" right="0.05664063" top="0.01562500" bottom="0.26562500"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="-4" y="4" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderTopRight" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.02539063" right="0.05664063" top="0.29687500" bottom="0.54687500"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" x="4" y="4" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderBotLeft" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.02539063" right="0.05664063" top="0.57812500" bottom="0.82812500"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" x="-4" y="-4" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderBotRight" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.06054688" right="0.09179688" top="0.01562500" bottom="0.26562500"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT" x="4" y="-4"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderLeft" file="Interface\QuestFrame\AutoQuestToastBorder-LeftRight" vertTile="true">
|
||||
<Size x="8" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorderTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBorderBotLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="0.5" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderRight" file="Interface\QuestFrame\AutoQuestToastBorder-LeftRight" vertTile="true">
|
||||
<Size x="8" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentBorderTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorderBotRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.5" right="1" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderTop" file="Interface\QuestFrame\AutoQuestToastBorder-TopBot" horizTile="true">
|
||||
<Size x="16" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentBorderTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentBorderTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="1" top="0" bottom="0.5"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentBorderBottom" file="Interface\QuestFrame\AutoQuestToastBorder-TopBot" horizTile="true">
|
||||
<Size x="16" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBorderBotLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBorderBotRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="1" top="0.5" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentQuestIconBg" inherits="QuestIcon-Large">
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativePoint="LEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK" textureSubLevel="1">
|
||||
<Texture name="$parentExclamation" parentKey="Exclamation" hidden="true" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="19" y="33"/>
|
||||
<TexCoords left="0.13476563" right="0.17187500" top="0.01562500" bottom="0.53125000"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativeTo="$parentQuestIconBg" x="0.5" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
|
||||
<Texture name="$parentQuestionMark" parentKey="QuestionMark" hidden="true" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="19" y="33"/>
|
||||
<TexCoords left="0.17578125" right="0.21289063" top="0.01562500" bottom="0.53125000"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativeTo="$parentQuestIconBg" x="0.5" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<FontString name="$parentQuestName" inherits="QuestFont_Large" parentKey="QuestName">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentQuestIconBg" relativePoint="RIGHT" x="-6"/>
|
||||
<Anchor point="RIGHT" x="-8"/>
|
||||
<Anchor point="TOP" x="0" y="-24"/>
|
||||
</Anchors>
|
||||
<Color r="1" g="1" b="1"/>
|
||||
</FontString>
|
||||
<FontString name="$parentTopText" inherits="GameFontNormalSmall" parentKey="TopText">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" x="0" y="-4"/>
|
||||
<Anchor point="LEFT" relativeTo="$parentQuestIconBg" relativePoint="RIGHT" x="-6"/>
|
||||
<Anchor point="RIGHT" x="-8"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentBottomText" inherits="GameFontDisableSmall" parentKey="BottomText">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM" x="0" y="4"/>
|
||||
<Anchor point="LEFT" relativeTo="$parentQuestIconBg" relativePoint="RIGHT" x="-6"/>
|
||||
<Anchor point="RIGHT" x="-8"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
<Layer level="BORDER" textureSubLevel="1">
|
||||
<Texture name="$parentShine" alphaMode="ADD" alpha="0" hidden="true" parentKey="Shine">
|
||||
<Animations>
|
||||
<AnimationGroup name="$parentFlash" parentKey="Flash">
|
||||
<Alpha startDelay="0" duration="0.25" order="1"/>
|
||||
<Alpha startDelay="0.05" duration="0.25" order="2"/>
|
||||
<Scripts>
|
||||
<OnStop>
|
||||
self:GetParent():Hide();
|
||||
</OnStop>
|
||||
<OnFinished>
|
||||
self:GetParent():Hide();
|
||||
</OnFinished>
|
||||
</Scripts>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="-1" y="1"/>
|
||||
<Anchor point="BOTTOMRIGHT" x="1" y="-1"/>
|
||||
</Anchors>
|
||||
<Color r="1" g="1" b="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentIconShine" alphaMode="ADD" alpha="0" hidden="true" parentKey="IconShine" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="42" y="42"/>
|
||||
<TexCoords left="0.21679688" right="0.29882813" top="0.01562500" bottom="0.67187500"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativeTo="$parentQuestIconBg"/>
|
||||
</Anchors>
|
||||
<Animations>
|
||||
<AnimationGroup name="$parentFlash" parentKey="Flash">
|
||||
<Alpha duration="0.25" order="1"/>
|
||||
<Alpha startDelay="0.05" duration="0.25" order="2"/>
|
||||
<Scripts>
|
||||
<OnStop>
|
||||
self:GetParent():Hide();
|
||||
</OnStop>
|
||||
<OnFinished>
|
||||
self:GetParent():Hide();
|
||||
--if (self:GetParent():GetParent():GetParent().type=="COMPLETED") then
|
||||
--self:GetParent():GetParent().Flash:Show();
|
||||
--end
|
||||
</OnFinished>
|
||||
</Scripts>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="$parentFlash" useParentLevel="true" setAllPoints="true" hidden="true" parentKey="Flash">
|
||||
<Layers>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="QuestLogFrameCompleteButtonFlash" inherits="UIPanelButtonHighlightTexture" parentKey="Flash">
|
||||
<Size x="180" y="28"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="14" y="-2"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentIconFlash" alphaMode="ADD" alpha="0.5" parentKey="IconFlash" file="Interface\QuestFrame\AutoQuest-Parts">
|
||||
<Size x="42" y="42"/>
|
||||
<TexCoords left="0.21679688" right="0.29882813" top="0.01562500" bottom="0.67187500"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativePoint="LEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self.IconFlash:SetVertexColor(1, 0, 0);
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
UIFrameFlash(self, 0.75, 0.75, -1, nil);
|
||||
</OnShow>
|
||||
<OnHide>
|
||||
UIFrameFlashStop(self);
|
||||
</OnHide>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Frames>
|
||||
</Frame>
|
||||
</ScrollChild>
|
||||
</ScrollFrame>
|
||||
|
||||
<Frame name="DetailsBoxAlertTemplateUp" inherits="GlowBoxTemplate" hidden="false" frameStrata="FULLSCREEN" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parentText" parentKey="text" inherits="GameFontHighlightLeft" justifyV="TOP" text="">
|
||||
<Size x="280" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="16" y="-15"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Size x="300" y="150"/>
|
||||
<Frames>
|
||||
<Frame name="$parentArrow" parentKey="arrow" inherits="GlowBoxArrowTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativePoint="BOTTOM" x="40" y="1"/>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</Frames>
|
||||
</Frame>
|
||||
|
||||
<!-- raw copy of blizzard ui -->
|
||||
<Frame name="DetailsHelpBoxTemplate" inherits="GlowBoxTemplate" parent="UIParent" hidden="true" frameStrata="FULLSCREEN_DIALOG" frameLevel="2" virtual="true">
|
||||
<Size x="220" y="100"/>
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString parentKey="Text" inherits="GameFontHighlightLeft">
|
||||
<Size x="200" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="15" y="-15"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture parentKey="ArrowUP" inherits="HelpPlateArrowDOWN" hidden="true">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativePoint="BOTTOM" x="0" y="3"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowDOWN" inherits="HelpPlateArrowUP" hidden="true">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM" relativePoint="TOP" x="0" y="-3"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowRIGHT" inherits="HelpPlateArrowDOWN" hidden="true">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativePoint="LEFT" x="3" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowLEFT" inherits="HelpPlateArrowDOWN" hidden="true">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" x="-3" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture parentKey="ArrowGlowUP" inherits="HelpPlateArrow-GlowDOWN" hidden="true" alphaMode="ADD" alpha="0.5">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativePoint="BOTTOM" x="0" y="3"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowGlowDOWN" inherits="HelpPlateArrow-GlowUP" hidden="true" alphaMode="ADD" alpha="0.5">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM" relativePoint="TOP" x="0" y="-3"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowGlowRIGHT" inherits="HelpPlateArrow-GlowDOWN" hidden="true" alphaMode="ADD" alpha="0.5">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativePoint="LEFT" x="3" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="ArrowGlowLEFT" inherits="HelpPlateArrow-GlowDOWN" hidden="true" alphaMode="ADD" alpha="0.5">
|
||||
<Size x="53" y="21"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" x="-3" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentCloseButton" inherits="UIPanelCloseButton">
|
||||
<Size x="20" y="20"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="3" y="3"/>
|
||||
</Anchors>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self.Text:SetSpacing(4);
|
||||
SetClampedTextureRotation(self.ArrowLEFT, 270);
|
||||
SetClampedTextureRotation(self.ArrowRIGHT, 90);
|
||||
SetClampedTextureRotation(self.ArrowGlowLEFT, 270);
|
||||
SetClampedTextureRotation(self.ArrowGlowRIGHT, 90);
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
self:SetHeight(self.Text:GetHeight()+30);
|
||||
</OnShow>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,716 @@
|
||||
|
||||
local cstr = tostring
|
||||
local _string_len = string.len
|
||||
local ceil = math.ceil
|
||||
local math_floor = math.floor
|
||||
local CreateFrame = CreateFrame
|
||||
local GetTime = GetTime
|
||||
local GetCursorPosition = GetCursorPosition
|
||||
local GameTooltip = GameTooltip
|
||||
local select = select
|
||||
|
||||
local _detalhes = _G.Details
|
||||
local gump = _detalhes.gump
|
||||
|
||||
|
||||
function gump:NewLabel2 (parent, container, member, text, font, size, color)
|
||||
|
||||
font = font or "GameFontHighlightSmall"
|
||||
|
||||
local newFontString = parent:CreateFontString(nil, "OVERLAY", font)
|
||||
if (member) then
|
||||
container [member] = newFontString
|
||||
end
|
||||
newFontString:SetText(text)
|
||||
|
||||
if (size) then
|
||||
_detalhes:SetFontSize(newFontString, size)
|
||||
end
|
||||
|
||||
if (color) then
|
||||
newFontString:SetTextColor(unpack(color))
|
||||
end
|
||||
|
||||
newFontString:SetJustifyH("LEFT")
|
||||
|
||||
return newFontString
|
||||
end
|
||||
|
||||
function gump:NewDetailsButton (parent, container, instancia, func, param1, param2, w, h, pic_up, pic_down, pic_disabled, pic_highlight, options, FrameName, inherits, ischeck)
|
||||
|
||||
if (not parent) then
|
||||
return nil
|
||||
end
|
||||
|
||||
w = w or 16
|
||||
h = h or 16
|
||||
options = options or {}
|
||||
|
||||
local new_button
|
||||
if (ischeck) then
|
||||
new_button = CreateFrame("CheckButton", FrameName, parent, inherits)
|
||||
else
|
||||
new_button = CreateFrame("Button", FrameName, parent)
|
||||
end
|
||||
|
||||
new_button:SetWidth(w)
|
||||
new_button:SetHeight(h)
|
||||
|
||||
if (not pic_down and pic_up) then
|
||||
pic_down = pic_up
|
||||
end
|
||||
if (not pic_disabled and pic_up) then
|
||||
pic_disabled = pic_up
|
||||
end
|
||||
if (not pic_highlight and pic_up) then
|
||||
pic_highlight = pic_up
|
||||
end
|
||||
|
||||
new_button:SetNormalTexture(pic_up)
|
||||
new_button:SetPushedTexture(pic_down)
|
||||
new_button:SetDisabledTexture(pic_disabled)
|
||||
new_button:SetHighlightTexture(pic_highlight, "ADD")
|
||||
|
||||
local new_text = new_button:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
new_text:SetPoint("center", new_button, "center")
|
||||
new_button.text = new_text
|
||||
|
||||
new_button.supportFrame = CreateFrame("frame", nil, new_button)
|
||||
new_button.supportFrame:SetPoint("topleft", new_button, "topleft")
|
||||
new_button.supportFrame:SetPoint("bottomright", new_button, "bottomright")
|
||||
new_button.supportFrame:SetFrameLevel(new_button:GetFrameLevel()+1)
|
||||
|
||||
new_button.supportFrame.disable_overlay = new_button.supportFrame:CreateTexture(nil, "overlay")
|
||||
new_button.supportFrame.disable_overlay:SetTexture("Interface\\AddOns\\Details\\images\\button_disable_overlay")
|
||||
new_button.supportFrame.disable_overlay:SetPoint("topleft", new_button.supportFrame, "topleft")
|
||||
new_button.supportFrame.disable_overlay:SetPoint("bottomright", new_button.supportFrame, "bottomright")
|
||||
new_button.supportFrame.disable_overlay:Hide()
|
||||
|
||||
local rightFunction = options.rightFunc
|
||||
|
||||
new_button:SetScript("OnDisable", function()
|
||||
new_button.supportFrame.disable_overlay:Show()
|
||||
end)
|
||||
new_button:SetScript("OnEnable", function()
|
||||
new_button.supportFrame.disable_overlay:Hide()
|
||||
end)
|
||||
|
||||
new_button.funcParam1 = param1
|
||||
new_button.funcParam2 = param2
|
||||
new_button.options = options
|
||||
|
||||
function new_button:ChangeOptions (_table)
|
||||
options = _table
|
||||
rightFunction = options.rightFunc
|
||||
end
|
||||
|
||||
new_button.enter = false
|
||||
|
||||
new_button:SetScript("OnMouseDown", function(self, button)
|
||||
if (not self:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
self.mouse_down = GetTime()
|
||||
local x, y = GetCursorPosition()
|
||||
self.x = math_floor (x)
|
||||
self.y = math_floor (y)
|
||||
|
||||
if (container) then
|
||||
if (container:IsMovable() and not container.isLocked) then
|
||||
container:StartMoving()
|
||||
container.isMoving = true
|
||||
end
|
||||
end
|
||||
|
||||
if (new_button.texture) then
|
||||
new_button.texture:SetTexCoord(0, 1, 0.5, 0.74609375)
|
||||
end
|
||||
|
||||
if (options.OnGrab and options.OnGrab == "PassClick") then
|
||||
if (rightFunction) then
|
||||
if (button == "LeftButton") then
|
||||
func (new_button.funcParam1, new_button.funcParam2)
|
||||
else
|
||||
rightFunction.func (rightFunction.param1, rightFunction.param2)
|
||||
end
|
||||
else
|
||||
func (new_button.funcParam1, new_button.funcParam2)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
new_button:SetScript("OnMouseUp", function(self, button)
|
||||
if (not self:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
if (container) then
|
||||
if (container.isMoving) then
|
||||
container:StopMovingOrSizing()
|
||||
container.isMoving = false
|
||||
if (instancia) then
|
||||
instancia:SaveMainWindowPosition()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (new_button.texture) then
|
||||
if (new_button.enter) then
|
||||
new_button.texture:SetTexCoord(0, 1, 0.25, 0.49609375)
|
||||
else
|
||||
new_button.texture:SetTexCoord(0, 1, 0, 0.24609375)
|
||||
end
|
||||
end
|
||||
|
||||
local x, y = GetCursorPosition()
|
||||
x = math_floor (x)
|
||||
y = math_floor (y)
|
||||
if ((self.mouse_down+0.4 > GetTime() and (x == self.x and y == self.y)) or (x == self.x and y == self.y)) then
|
||||
if (rightFunction) then
|
||||
if (button == "LeftButton") then
|
||||
func (new_button.funcParam1, new_button.funcParam2)
|
||||
else
|
||||
rightFunction.func (rightFunction.param1, rightFunction.param2)
|
||||
end
|
||||
else
|
||||
func (new_button.funcParam1, new_button.funcParam2)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
new_button.tooltip = nil
|
||||
|
||||
new_button:SetScript("OnEnter", function()
|
||||
|
||||
new_button.enter = true
|
||||
|
||||
if (new_button.tooltip) then
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:SetType ("tooltip")
|
||||
GameCooltip:SetColor ("main", "transparent")
|
||||
GameCooltip:AddLine(new_button.tooltip)
|
||||
GameCooltip:SetOwner(new_button)
|
||||
GameCooltip:ShowCooltip()
|
||||
end
|
||||
|
||||
if (new_button.texture) then
|
||||
new_button.texture:SetTexCoord(0, 1, 0.25+(0.0078125/2), 0.5+(0.0078125/2))
|
||||
end
|
||||
|
||||
if (new_button.MouseOnEnterHook) then
|
||||
new_button.MouseOnEnterHook (new_button)
|
||||
end
|
||||
end)
|
||||
|
||||
new_button:SetScript("OnLeave", function()
|
||||
|
||||
new_button.enter = false
|
||||
|
||||
if (new_button.tooltip) then
|
||||
_detalhes.popup:ShowMe(false)
|
||||
end
|
||||
|
||||
if (new_button.texture) then
|
||||
new_button.texture:SetTexCoord(0, 1, 0, 0.24609375)
|
||||
end
|
||||
|
||||
if (new_button.MouseOnLeaveHook) then
|
||||
new_button.MouseOnLeaveHook (new_button)
|
||||
end
|
||||
end)
|
||||
|
||||
function new_button:ChangeIcon (icon1, icon2, icon3, icon4)
|
||||
new_button:SetNormalTexture(icon1)
|
||||
new_button:SetPushedTexture(icon2)
|
||||
new_button:SetDisabledTexture(icon3)
|
||||
new_button:SetHighlightTexture(icon4, "ADD")
|
||||
end
|
||||
|
||||
function new_button:InstallCustomTexture (texture, rect)
|
||||
new_button:SetNormalTexture("")
|
||||
new_button:SetPushedTexture("")
|
||||
new_button:SetDisabledTexture("")
|
||||
new_button:SetHighlightTexture("")
|
||||
texture = texture or "Interface\\AddOns\\Details\\images\\default_button"
|
||||
new_button.texture = new_button:CreateTexture(nil, "background")
|
||||
|
||||
if (not rect) then
|
||||
new_button.texture:SetAllPoints(new_button)
|
||||
else
|
||||
new_button.texture:SetPoint("topleft", new_button, "topleft", rect.x1, rect.y1)
|
||||
new_button.texture:SetPoint("bottomright", new_button, "bottomright", rect.x2, rect.y2)
|
||||
end
|
||||
|
||||
new_button.texture:SetTexCoord(0, 1, 0, 0.24609375)
|
||||
new_button.texture:SetTexture(texture)
|
||||
end
|
||||
|
||||
new_button.textColor = {}
|
||||
new_button.textColor.r, new_button.textColor.g, new_button.textColor.b = new_button.text:GetTextColor()
|
||||
|
||||
return new_button
|
||||
end
|
||||
|
||||
local EditBoxBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
tile = true, edgeSize = 1, tileSize = 5,
|
||||
}
|
||||
|
||||
function gump:NewTextBox (parent, container, member, func, param1, param2, w, h, options)
|
||||
|
||||
local editbox = CreateFrame("EditBox", "DetailsEditBox1", parent)
|
||||
container [member] = editbox
|
||||
options = options or {}
|
||||
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetFontObject(GameFontHighlightSmall)
|
||||
|
||||
editbox:SetWidth(w)
|
||||
editbox:SetHeight(h)
|
||||
editbox:SetJustifyH("CENTER")
|
||||
editbox:EnableMouse(true)
|
||||
editbox:SetBackdrop(EditBoxBackdrop)
|
||||
editbox:SetBackdropColor(0, 0, 0, 0.5)
|
||||
editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
|
||||
editbox:SetText("") --localize-me
|
||||
|
||||
editbox.perdeu_foco = nil
|
||||
|
||||
editbox.text = ""
|
||||
editbox.next = options.next
|
||||
editbox.tooltip = options.tooltip
|
||||
editbox.tab_on_enter = options.TabOnEnterPress
|
||||
editbox.space = options.MySpace
|
||||
|
||||
gump:NewLabel(editbox, editbox, nil, "label", "", "GameFontHighlightSmall")
|
||||
editbox ["label"]: SetPoint ("right", editbox, "left", -2, 0)
|
||||
editbox.label:SetTextColor(.8, .8, .8, 1)
|
||||
|
||||
function editbox:SetPointAndSpace (MyAnchor, SnapTo, HisAnchor, x, y, Width)
|
||||
|
||||
if (type(MyAnchor) == "boolean" and MyAnchor and editbox.space) then
|
||||
local textWidth = editbox ["label"]:GetStringWidth()+2
|
||||
editbox:SetWidth(editbox.space - textWidth - 15)
|
||||
return
|
||||
|
||||
elseif (not editbox.space and not Width) then
|
||||
return
|
||||
elseif (Width) then
|
||||
editbox.space = Width
|
||||
end
|
||||
|
||||
if (editbox.space) then
|
||||
editbox ["label"]:ClearAllPoints()
|
||||
editbox:ClearAllPoints()
|
||||
editbox ["label"]:SetPoint(MyAnchor, SnapTo, HisAnchor, x, y)
|
||||
editbox:SetPoint("left", editbox["label"].widget, "right", 2, 0)
|
||||
|
||||
local textWidth = editbox ["label"]:GetStringWidth()+2
|
||||
editbox:SetWidth(editbox.space - textWidth - 15)
|
||||
end
|
||||
end
|
||||
|
||||
function editbox:SetLabelText (text)
|
||||
if (text) then
|
||||
editbox ["label"]:SetText(text)
|
||||
else
|
||||
editbox ["label"]:SetText("")
|
||||
end
|
||||
|
||||
if (editbox.space) then
|
||||
editbox:SetPointAndSpace (true) --refresh
|
||||
end
|
||||
end
|
||||
|
||||
local EnterPress = function(byScript)
|
||||
|
||||
if (editbox.EnterHook) then
|
||||
editbox.EnterHook()
|
||||
end
|
||||
|
||||
local texto = _detalhes:trim (editbox:GetText())
|
||||
if (_string_len (texto) > 0) then
|
||||
editbox.text = texto
|
||||
if (func) then
|
||||
func (param1, param2, texto, editbox, byScript)
|
||||
end
|
||||
else
|
||||
editbox:SetText("")
|
||||
editbox.text = ""
|
||||
end
|
||||
editbox.perdeu_foco = true --isso aqui pra quando estiver editando e clicar em outra caixa
|
||||
editbox:ClearFocus()
|
||||
|
||||
if (editbox.tab_on_enter and editbox.next) then
|
||||
editbox.next:SetFocus()
|
||||
end
|
||||
end
|
||||
|
||||
function editbox:PressEnter(byScript)
|
||||
EnterPress (byScript)
|
||||
end
|
||||
|
||||
editbox:SetScript("OnEnterPressed", EnterPress)
|
||||
|
||||
editbox:SetScript("OnEscapePressed", function()
|
||||
editbox:SetText("")
|
||||
editbox.text = ""
|
||||
editbox.perdeu_foco = true
|
||||
editbox:ClearFocus()
|
||||
|
||||
if (editbox.OnEscapeHook) then
|
||||
editbox.OnEscapeHook()
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEnter", function()
|
||||
editbox.mouse_over = true
|
||||
if (editbox:IsEnabled()) then
|
||||
editbox:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
|
||||
end
|
||||
if (editbox.tooltip) then
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:SetType ("tooltip")
|
||||
GameCooltip:SetColor ("main", "transparent")
|
||||
GameCooltip:AddLine(editbox.tooltip)
|
||||
GameCooltip:SetOwner(editbox)
|
||||
GameCooltip:ShowCooltip()
|
||||
end
|
||||
|
||||
if (editbox.OnEnterHook) then
|
||||
editbox:OnEnterHook()
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnLeave", function()
|
||||
editbox.mouse_over = false
|
||||
if (editbox:IsEnabled()) then
|
||||
editbox:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
|
||||
end
|
||||
|
||||
if (not editbox:HasFocus()) then
|
||||
--if (editbox:GetText() == "") then
|
||||
-- editbox:SetText("insira o nome do buff")
|
||||
--end
|
||||
end
|
||||
|
||||
if (editbox.tooltip) then
|
||||
if (not editbox.HaveMenu) then
|
||||
_detalhes.popup:ShowMe(false)
|
||||
end
|
||||
end
|
||||
|
||||
if (editbox.OnLeaveHook) then
|
||||
editbox:OnLeaveHook()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEditFocusGained", function()
|
||||
if (editbox.label) then
|
||||
editbox.label:SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
if (editbox.OnFocusGainedHook) then
|
||||
editbox.OnFocusGainedHook()
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEditFocusLost", function()
|
||||
|
||||
if (editbox:IsShown()) then
|
||||
if (editbox.perdeu_foco == nil) then
|
||||
local texto = _detalhes:trim (editbox:GetText())
|
||||
if (_string_len (texto) > 0) then
|
||||
editbox.text = texto
|
||||
if (func) then
|
||||
func (param1, param2, texto, editbox, nil)
|
||||
end
|
||||
else
|
||||
editbox:SetText("")
|
||||
end
|
||||
else
|
||||
editbox.perdeu_foco = nil
|
||||
end
|
||||
|
||||
if (editbox.label) then
|
||||
editbox.label:SetTextColor(.8, .8, .8, 1)
|
||||
end
|
||||
|
||||
if (editbox.OnFocusLostHook) then
|
||||
editbox.OnFocusLostHook()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnChar", function(self, text)
|
||||
if (editbox.InputHook) then
|
||||
editbox:InputHook (text)
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnTextChanged", function(self, userChanged)
|
||||
if (editbox.TextChangeedHook and userChanged) then
|
||||
editbox:TextChangeedHook (userChanged)
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnTabPressed", function()
|
||||
if (editbox.next) then
|
||||
EnterPress()
|
||||
editbox.next:SetFocus()
|
||||
end
|
||||
end)
|
||||
|
||||
editbox.SetNext = function(_, NextBox)
|
||||
if (NextBox) then
|
||||
editbox.next = NextBox
|
||||
end
|
||||
end
|
||||
|
||||
editbox.SetLabel = function(_, Label)
|
||||
if (Label) then
|
||||
editbox.label = Label
|
||||
editbox.label:SetTextColor(.8, .8, .8, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function editbox:Blink()
|
||||
editbox.label:SetTextColor(1, .2, .2, 1)
|
||||
end
|
||||
|
||||
if (options.Label) then
|
||||
editbox:SetLabel (options.Label)
|
||||
end
|
||||
|
||||
options = nil
|
||||
|
||||
return editbox
|
||||
end
|
||||
|
||||
function gump:NewScrollBar2 (master, slave, x, y)
|
||||
|
||||
local slider_gump = CreateFrame("Slider", master:GetName() and master:GetName() .. "SliderGump" or "DetailsSliderGump" .. math.random(1, 10000000), master)
|
||||
slider_gump.scrollMax = 560 --default - tamanho da janela de fundo
|
||||
|
||||
-- ///// SLIDER /////
|
||||
slider_gump:SetPoint("TOPLEFT", master, "TOPRIGHT", x, y)
|
||||
slider_gump.ativo = true
|
||||
|
||||
slider_gump.bg = slider_gump:CreateTexture(nil, "BACKGROUND")
|
||||
slider_gump.bg:SetAllPoints(true)
|
||||
slider_gump.bg:SetTexture(0, 0, 0, 0)
|
||||
--coisinha do meio
|
||||
slider_gump.thumb = slider_gump:CreateTexture(nil, "OVERLAY")
|
||||
slider_gump.thumb:SetTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
|
||||
slider_gump.thumb:SetSize(29, 30)
|
||||
slider_gump:SetThumbTexture (slider_gump.thumb)
|
||||
|
||||
slider_gump:SetOrientation("VERTICAL")
|
||||
slider_gump:SetSize(16, 100)
|
||||
slider_gump:SetMinMaxValues(0, slider_gump.scrollMax)
|
||||
slider_gump:SetValue(0)
|
||||
slider_gump.ultimo = 0
|
||||
|
||||
local botao_cima = CreateFrame("Button", slider_gump:GetName() .. "UpButton", master)
|
||||
|
||||
botao_cima:SetWidth(29)
|
||||
botao_cima:SetHeight(32)
|
||||
botao_cima:SetNormalTexture([[Interface\Buttons\Arrow-Up-Up]])
|
||||
botao_cima:SetPushedTexture([[Interface\Buttons\Arrow-Up-Down]])
|
||||
botao_cima:SetDisabledTexture([[Interface\Buttons\Arrow-Up-Disabled]])
|
||||
botao_cima:Show()
|
||||
botao_cima:Disable()
|
||||
|
||||
botao_cima:SetPoint("BOTTOM", slider_gump, "TOP", 0, -12)
|
||||
botao_cima.x = 0
|
||||
botao_cima.y = -12
|
||||
|
||||
local botao_baixo = CreateFrame("Button", slider_gump:GetName() .. "DownButton", master)
|
||||
botao_baixo:SetPoint("TOP", slider_gump, "BOTTOM", 0, 12)
|
||||
botao_baixo.x = 0
|
||||
botao_baixo.y = 12
|
||||
|
||||
botao_baixo:SetWidth(29)
|
||||
botao_baixo:SetHeight(32)
|
||||
botao_baixo:SetNormalTexture([[Interface\Buttons\Arrow-Down-Up]])
|
||||
botao_baixo:SetPushedTexture([[Interface\Buttons\Arrow-Down-Down]])
|
||||
botao_baixo:SetDisabledTexture([[Interface\Buttons\Arrow-Down-Disabled]])
|
||||
botao_baixo:Show()
|
||||
botao_baixo:Disable()
|
||||
|
||||
master.baixo = botao_baixo
|
||||
master.cima = botao_cima
|
||||
master.slider = slider_gump
|
||||
|
||||
botao_baixo:SetScript("OnMouseDown", function(self)
|
||||
if (not slider_gump:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = slider_gump:GetValue()
|
||||
local minValue, maxValue = slider_gump:GetMinMaxValues()
|
||||
if (current+5 < maxValue) then
|
||||
slider_gump:SetValue(current+5)
|
||||
else
|
||||
slider_gump:SetValue(maxValue)
|
||||
end
|
||||
self.precionado = true
|
||||
self.last_up = -0.3
|
||||
self:SetScript("OnUpdate", function(self, elapsed)
|
||||
self.last_up = self.last_up + elapsed
|
||||
if (self.last_up > 0.03) then
|
||||
self.last_up = 0
|
||||
local current = slider_gump:GetValue()
|
||||
local minValue, maxValue = slider_gump:GetMinMaxValues()
|
||||
if (current+2 < maxValue) then
|
||||
slider_gump:SetValue(current+2)
|
||||
else
|
||||
slider_gump:SetValue(maxValue)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
botao_baixo:SetScript("OnMouseUp", function(self)
|
||||
self.precionado = false
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
|
||||
botao_cima:SetScript("OnMouseDown", function(self)
|
||||
if (not slider_gump:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = slider_gump:GetValue()
|
||||
if (current-5 > 0) then
|
||||
slider_gump:SetValue(current-5)
|
||||
else
|
||||
slider_gump:SetValue(0)
|
||||
end
|
||||
self.precionado = true
|
||||
self.last_up = -0.3
|
||||
self:SetScript("OnUpdate", function(self, elapsed)
|
||||
self.last_up = self.last_up + elapsed
|
||||
if (self.last_up > 0.03) then
|
||||
self.last_up = 0
|
||||
local current = slider_gump:GetValue()
|
||||
if (current-2 > 0) then
|
||||
slider_gump:SetValue(current-2)
|
||||
else
|
||||
slider_gump:SetValue(0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
botao_cima:SetScript("OnMouseUp", function(self)
|
||||
self.precionado = false
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
--isso aqui pra quando o slider ativar, o scroll fica na posi��o zero
|
||||
botao_cima:SetScript("OnEnable", function(self)
|
||||
local current = slider_gump:GetValue()
|
||||
if (current == 0) then
|
||||
botao_cima:Disable()
|
||||
end
|
||||
end)
|
||||
|
||||
slider_gump:SetScript("OnValueChanged", function(self)
|
||||
local current = self:GetValue()
|
||||
master:SetVerticalScroll (current)
|
||||
|
||||
local minValue, maxValue = slider_gump:GetMinMaxValues()
|
||||
|
||||
if (current == minValue) then
|
||||
botao_cima:Disable()
|
||||
elseif (not botao_cima:IsEnabled()) then
|
||||
botao_cima:Enable()
|
||||
end
|
||||
|
||||
if (current == maxValue) then
|
||||
botao_baixo:Disable()
|
||||
elseif (not botao_baixo:IsEnabled()) then
|
||||
botao_baixo:Enable()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
slider_gump:SetScript("OnShow", function(self)
|
||||
botao_cima:Show()
|
||||
botao_baixo:Show()
|
||||
end)
|
||||
|
||||
slider_gump:SetScript("OnDisable", function(self)
|
||||
botao_cima:Disable()
|
||||
botao_baixo:Disable()
|
||||
end)
|
||||
|
||||
slider_gump:SetScript("OnEnable", function(self)
|
||||
botao_cima:Enable()
|
||||
botao_baixo:Enable()
|
||||
end)
|
||||
|
||||
master:SetScript("OnMouseWheel", function(self, delta)
|
||||
if (not slider_gump:IsEnabled()) then
|
||||
return
|
||||
end
|
||||
|
||||
local current = slider_gump:GetValue()
|
||||
if (delta < 0) then
|
||||
--baixo
|
||||
local minValue, maxValue = slider_gump:GetMinMaxValues()
|
||||
if (current + (master.wheel_jump or 20) < maxValue) then
|
||||
slider_gump:SetValue(current + (master.wheel_jump or 20))
|
||||
else
|
||||
slider_gump:SetValue(maxValue)
|
||||
end
|
||||
elseif (delta > 0) then
|
||||
--cima
|
||||
if (current + (master.wheel_jump or 20) > 0) then
|
||||
slider_gump:SetValue(current - (master.wheel_jump or 20))
|
||||
else
|
||||
slider_gump:SetValue(0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function slider_gump:Altura (h)
|
||||
self:SetHeight(h)
|
||||
end
|
||||
|
||||
function slider_gump:Update (desativar)
|
||||
|
||||
if (desativar) then
|
||||
slider_gump:Disable()
|
||||
slider_gump:SetValue(0)
|
||||
slider_gump.ativo = false
|
||||
master:EnableMouseWheel(false)
|
||||
return
|
||||
end
|
||||
|
||||
self.scrollMax = slave:GetHeight()-master:GetHeight()
|
||||
if (self.scrollMax > 0) then
|
||||
slider_gump:SetMinMaxValues(0, self.scrollMax)
|
||||
if (not slider_gump.ativo) then
|
||||
slider_gump:Enable()
|
||||
slider_gump.ativo = true
|
||||
master:EnableMouseWheel(true)
|
||||
end
|
||||
else
|
||||
slider_gump:Disable()
|
||||
slider_gump:SetValue(0)
|
||||
slider_gump.ativo = false
|
||||
master:EnableMouseWheel(false)
|
||||
end
|
||||
end
|
||||
|
||||
function slider_gump:cimaPoint (x, y)
|
||||
botao_cima:SetPoint("BOTTOM", slider_gump, "TOP", x, (y)-12)
|
||||
end
|
||||
|
||||
function slider_gump:baixoPoint (x, y)
|
||||
botao_baixo:SetPoint("TOP", slider_gump, "BOTTOM", x, (y)+12)
|
||||
end
|
||||
|
||||
return slider_gump
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
<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">
|
||||
|
||||
<Frame name="DetailsToolbarButton" virtual="true" hidden="true">
|
||||
|
||||
<Size>
|
||||
<AbsDimension x="14" y="14"/>
|
||||
</Size>
|
||||
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
DetailsToolbarButtonOnEnter (self);
|
||||
</OnEnter>
|
||||
|
||||
<OnLeave>
|
||||
DetailsToolbarButtonOnLeave (self);
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
|
||||
<Layers>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentStar" parentKey="Star" file="interface\cooldown\star4" alphaMode="ADD" alpha="0">
|
||||
<Size x="40" y="40"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Color r="0.985" g="0.111" b="0.125"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
|
||||
<Animations>
|
||||
<AnimationGroup parentKey="StarAnim">
|
||||
<Rotation targetKey="$parent.$parent.Star" degrees="-90" duration="0.9" order="1"/>
|
||||
<Alpha targetKey="$parent.$parent.Star" duration="0.3667" order="1"/>
|
||||
<Alpha targetKey="$parent.$parent.Star" duration="0.5333" order="2"/>
|
||||
</AnimationGroup>
|
||||
</Animations>
|
||||
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,668 @@
|
||||
--parei (20/11) declarando o header, precisa agora modificar a config do header quando atualizar
|
||||
--fazer uma função para alterar a config header.columns para add ou remover attributos
|
||||
|
||||
--próximo: ao criar uma janela AllInOne, precisa criar uma nova instancia no Details!
|
||||
--na tabela de configuração precisa dizer que é uma all in one e o details vai chamar esse arquivo pra atualizar
|
||||
|
||||
--(ainda aqui) parei atualizando o height da titlebar
|
||||
--proximo passo: atualizar o resto das propriedade da title bar
|
||||
--fazer as funcções para setar os valores na titleBar
|
||||
--verificar se precisa add funcções no mixin dos bottões como SetTexture, SetVertexColor
|
||||
|
||||
--tem que fazer a função de ShowWindow() e ToggleWindows()
|
||||
--fazer a criação do header e fazer o header ser redirecionado (aumentar ou diminuir o tamanho by dragging)
|
||||
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
local df = DetailsFramework
|
||||
local detailsFramework = DetailsFramework
|
||||
local Details = Details
|
||||
local addonName, DetailsPrivite = ...
|
||||
|
||||
local defaultWindowSettings = {
|
||||
isOpened = true,
|
||||
|
||||
libwindow = {},
|
||||
width = 350,
|
||||
height = 150,
|
||||
|
||||
titlebar = {
|
||||
--done here: all options can be retrived from details! settings
|
||||
},
|
||||
|
||||
header = {
|
||||
show_name = true, --false | on for debug
|
||||
show_icon = true,
|
||||
auto_size = true, --false | on for debug
|
||||
columns = { --damage, dps, percent
|
||||
{1, 1},
|
||||
{1, 2},
|
||||
{1, 1, "%"}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
--namespace
|
||||
DetailsPrivite.AllInOneWindow = {}
|
||||
local attributeCodes = {
|
||||
|
||||
}
|
||||
|
||||
DetailsPrivite.WindowTooltip = {}
|
||||
|
||||
|
||||
local textureCoords = {
|
||||
show_mainmenu = {0/256, 32/256, 0, 1},
|
||||
show_segments = {32/256, 64/256, 0, 1},
|
||||
show_report = {96/256, 128/256, 0, 1},
|
||||
show_reset = {128/256, 160/256, 0, 1},
|
||||
show_displays = {66/256, 93/256, 0, 1},
|
||||
show_close = {160/256, 192/256, 0, 1},
|
||||
}
|
||||
|
||||
--namespace
|
||||
Details.AllInOneWindow = {
|
||||
--store the frame of all AllInOne windows, this table does not same with the addon
|
||||
FramesCreated = {},
|
||||
WindowsOpened = 0,
|
||||
|
||||
--return a table: {{settings}, {settings}, {settings}, {settings}, ...}
|
||||
GetAllSettings = function()
|
||||
--setting within profile
|
||||
return Details.all_in_one_windows
|
||||
end,
|
||||
|
||||
--return the amount of settings by calling the above function and returning the amount of indexes
|
||||
GetNumSettings = function()
|
||||
return #Details.AllInOneWindow.GetAllSettings()
|
||||
end,
|
||||
|
||||
--return which will be the next settingID if a new setting is added
|
||||
GetNextSettingID = function()
|
||||
return #Details.all_in_one_windows + 1
|
||||
end,
|
||||
|
||||
--return the settingTable of a settingID
|
||||
GetSettingsByID = function(ID)
|
||||
return Details.AllInOneWindow.GetAllSettings()[ID]
|
||||
end,
|
||||
|
||||
--add a setting and return the settingID
|
||||
AddSetting = function(newSettingTable)
|
||||
local allSettings = Details.AllInOneWindow.GetAllSettings()
|
||||
allSettings[#allSettings+1] = newSettingTable
|
||||
return #allSettings
|
||||
end,
|
||||
|
||||
--frames already created on this session
|
||||
GetAllFrames = function()
|
||||
return Details.AllInOneWindow.FramesCreated
|
||||
end,
|
||||
|
||||
GetNumFrames = function()
|
||||
return #Details.AllInOneWindow.GetAllFrames()
|
||||
end,
|
||||
|
||||
GetFrameBySettingID = function(settingId)
|
||||
local numFramesCreated = Details.AllInOneWindow.GetNumFrames()
|
||||
for id = 1, numFramesCreated do
|
||||
local window = Details.AllInOneWindow.GetFrameByID(id)
|
||||
if (window:GetSettingsID() == settingId) then
|
||||
return window:GetSettings()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
AddFrame = function(frame)
|
||||
Details.AllInOneWindow.FramesCreated[#Details.AllInOneWindow.FramesCreated+1] = frame
|
||||
return #Details.AllInOneWindow.FramesCreated+1
|
||||
end,
|
||||
|
||||
GetFrameByID = function(ID)
|
||||
return Details.AllInOneWindow.FramesCreated[ID]
|
||||
end,
|
||||
|
||||
RestoreAllWindows = function()
|
||||
|
||||
end,
|
||||
|
||||
ShowWindow = function(settingId)
|
||||
|
||||
end,
|
||||
|
||||
HideWindow = function(settingId)
|
||||
assert(type(settingId) ~= "number", "Details.AllInOneWindow.HideWindow require a number on 'settingId'")
|
||||
local settings = Details.AllInOneWindow.GetAllSettings()
|
||||
local windowSetting = settings[settingId]
|
||||
assert(type(windowSetting) ~= "table", "Details.AllInOneWindow.HideWindow settings not found for settingId: " .. settingId)
|
||||
|
||||
if (windowSetting) then
|
||||
if (windowSetting.isOpened) then
|
||||
windowSetting.isOpened = false
|
||||
--get the window being used by this setting
|
||||
local window = Details.AllInOneWindow.GetFrameBySettingID(settingId)
|
||||
if (window) then
|
||||
window:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
HideAllWindows = function()
|
||||
local numSettings = Details.AllInOneWindow.GetNumSettings()
|
||||
--table with all the settings for all AllInOne windows in the current profile
|
||||
local settings = Details.AllInOneWindow.GetAllSettings()
|
||||
for settingId = 1, numSettings do
|
||||
local windowSetting = Details.AllInOneWindow.GetSettingsByID(settingId)
|
||||
if (windowSetting.isOpened) then
|
||||
Details.AllInOneWindow.HideWindow(settingId)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
ToggleWindows = function()
|
||||
|
||||
end,
|
||||
}
|
||||
|
||||
local menuButtonMixin = {
|
||||
GetSettingName = function(button)
|
||||
return button.settingName
|
||||
end,
|
||||
}
|
||||
|
||||
local menuSupportFrameMixin = {
|
||||
Constructor = function(menuSupportFrame)
|
||||
menuSupportFrame:SetSize(1, 1)
|
||||
menuSupportFrame.allButtons = {}
|
||||
|
||||
menuSupportFrame:CreateMenuButton("CloseMenu", "show_close")
|
||||
menuSupportFrame:CreateMenuButton("MainMenu", "show_mainmenu")
|
||||
menuSupportFrame:CreateMenuButton("SegmentsMenu", "show_segments")
|
||||
menuSupportFrame:CreateMenuButton("DisplaysMenu", "show_report")
|
||||
menuSupportFrame:CreateMenuButton("ReportMenu", "show_reset")
|
||||
menuSupportFrame:CreateMenuButton("ResetMenu", "show_displays")
|
||||
end,
|
||||
|
||||
GetNumButtons = function(supportFrame)
|
||||
return #supportFrame.allButtons
|
||||
end,
|
||||
|
||||
GetButtonByIndex = function(supportFrame, buttonIndex)
|
||||
return supportFrame.allButtons[buttonIndex]
|
||||
end,
|
||||
|
||||
CreateMenuButton = function(supportFrame, name, settingName)
|
||||
local newButton = CreateFrame("button", "$parent" .. name, supportFrame)
|
||||
newButton:SetSize(20, 20)
|
||||
newButton:SetScale(1)
|
||||
supportFrame.allButtons[#supportFrame.allButtons+1] = newButton
|
||||
df:Mixin(newButton, menuButtonMixin)
|
||||
newButton.settingName = settingName
|
||||
return newButton
|
||||
end,
|
||||
|
||||
Refresh = function(supportFrame)
|
||||
local window = supportFrame:GetParent():GetParent()
|
||||
--problem: it is getting the settings from the AllInOneWindow settings, it should get from Details! default window settings
|
||||
--this settings should return the regular window setting from Details! on _detalhes.tabela_instancias[windowId]
|
||||
local settings = window:GetSettings().titlebar.menu_buttons
|
||||
|
||||
supportFrame:ClearAllPoints()
|
||||
supportFrame:SetSize(1, 1)
|
||||
supportFrame:SetScale(settings.scale)
|
||||
supportFrame:SetAlpha(settings.alpha)
|
||||
|
||||
--buttons currently allowed to show by the user settings
|
||||
local allShownButtons = {}
|
||||
for i = 1, supportFrame:GetNumButtons() do
|
||||
local button = supportFrame:GetButtonByIndex(i)
|
||||
if (settings[button:GetSettingName()]) then
|
||||
allShownButtons[#allShownButtons+1] = button
|
||||
button:Show()
|
||||
df:SetRegularButtonTexture(button, settings.texture_file, textureCoords[button:GetSettingName()])
|
||||
df:SetRegularButtonVertexColor(button, settings.color)
|
||||
else
|
||||
button:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
--hardcoded to place the menu buttons in the left side of the window
|
||||
--if needed this can be "right" with the header leave space for it
|
||||
local attachPoint = "left"
|
||||
|
||||
if (settings.alignment == "horizontal") then
|
||||
--make it attach to the left side of the title bar or the right side of the title bar
|
||||
supportFrame:SetPoint(attachPoint, window.TitleBar, attachPoint, settings.x_offset, settings.y_offset)
|
||||
|
||||
local paddingAmount = attachPoint == "left" and settings.padding or (settings.padding * -1)
|
||||
for i = 1, #allShownButtons do
|
||||
local button = allShownButtons[i]
|
||||
if (i ==1) then
|
||||
button:SetPoint(attachPoint, supportFrame, attachPoint, 0, 0)
|
||||
else
|
||||
local previousButton = allShownButtons[i - 1]
|
||||
local sideToAttach = attachPoint == "left" and "right" or "left"
|
||||
button:SetPoint(attachPoint, previousButton, sideToAttach, paddingAmount, 0)
|
||||
end
|
||||
end
|
||||
|
||||
elseif (settings.alignment == "vertical") then
|
||||
if (attachPoint == "left") then
|
||||
supportFrame:SetPoint("topright", window.TitleBar, "topleft", settings.x_offset, settings.y_offset)
|
||||
else
|
||||
supportFrame:SetPoint("topleft", window.TitleBar, "topright", settings.x_offset, settings.y_offset)
|
||||
end
|
||||
|
||||
--here left == top to bottom | right = bottom to top
|
||||
local paddingAmount = attachPoint == "left" and settings.padding or (settings.padding * -1)
|
||||
local attachTo = attachPoint == "left" and "top" or "bottom"
|
||||
for i = 1, #allShownButtons do
|
||||
local button = allShownButtons[i]
|
||||
if (i ==1) then
|
||||
button:SetPoint(attachTo, supportFrame, attachTo, 0, 0)
|
||||
else
|
||||
local previousButton = allShownButtons[i - 1]
|
||||
local sideToAttach = attachTo == "left" and "bottom" or "top"
|
||||
button:SetPoint(attachTo, previousButton, sideToAttach, paddingAmount, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local headerMixin = {
|
||||
Constructor = function(header)
|
||||
|
||||
end,
|
||||
}
|
||||
|
||||
local titleBarMixin = { --~titlebar
|
||||
--run when the title bar is created
|
||||
Constructor = function(titleBar)
|
||||
titleBar:EnableMouse(false)
|
||||
|
||||
--create support frame for control buttons, it also will create the control buttons as children
|
||||
titleBar:CreateMenuSupportFrame()
|
||||
|
||||
--create the elapsed time string
|
||||
titleBar:CreateCombatTimeString()
|
||||
titleBar:SetCombatTimeText("02:36") --debug
|
||||
|
||||
--create titlebar texture
|
||||
titleBar:CreateTexture()
|
||||
|
||||
--create header
|
||||
titleBar:CreateHeader()
|
||||
end,
|
||||
|
||||
GetSettings = function(titleBar)
|
||||
--get the settings from the main window
|
||||
return titleBar:GetParent():GetSettings()
|
||||
end,
|
||||
|
||||
SetSetting = function()
|
||||
--this function exists and get overriden by the SetSetting of the window mixin
|
||||
end,
|
||||
|
||||
SetTitleBarHeight = function(titleBar, height)
|
||||
assert(type(height) == "number", "Invalid height, usage: TitleBar:SetTitleBarHeight(height)")
|
||||
titleBar:SetHeight(height)
|
||||
titleBar:SetSetting(height, "titlebar", "height")
|
||||
titleBar:Refresh()
|
||||
end,
|
||||
|
||||
SetTitleBarTextSize = function(window, size)
|
||||
if (not size or type(size) ~= "number") then
|
||||
return
|
||||
end
|
||||
df:SetFontSize(window.TitleBar.CombatTime, size)
|
||||
|
||||
end,
|
||||
|
||||
SetTitleBarTextColor = function(window, color)
|
||||
local r, g, b, a = df:ParseColor(color)
|
||||
df:SetFontColor(window.TitleBar.CombatTime, r, g, b, a)
|
||||
end,
|
||||
|
||||
SetTitleBarTextFont = function(window, font)
|
||||
|
||||
end,
|
||||
|
||||
SetTitleBarTextOutline = function(window, outline)
|
||||
|
||||
end,
|
||||
|
||||
SetTitleBarTextShadow = function(window, shadow, xOffset, yOffset)
|
||||
|
||||
end,
|
||||
|
||||
SetTexture = function(titleBar, texturePath, textureCoord, vertexColor)
|
||||
if (texturePath) then
|
||||
titleBar.BackgroundTexture:SetTexture(texturePath)
|
||||
|
||||
if (vertexColor) then
|
||||
local r, g, b, a = detailsFramework:ParseColors(vertexColor)
|
||||
titleBar.BackgroundTexture:SetVertexColor(r, g, b, a)
|
||||
else
|
||||
titleBar.BackgroundTexture:SetVertexColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
if (textureCoord) then
|
||||
titleBar.BackgroundTexture:SetTexCoord(unpack(textureCoord))
|
||||
else
|
||||
titleBar.BackgroundTexture:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
else
|
||||
titleBar.BackgroundTexture:SetTexture("")
|
||||
end
|
||||
end,
|
||||
|
||||
CreateTexture = function(titleBar)
|
||||
local texture = titleBar:CreateTexture("$parentBackgroundTexture", "border")
|
||||
titleBar.BackgroundTexture = texture
|
||||
return texture
|
||||
end,
|
||||
|
||||
GetTexture = function(titleBar)
|
||||
return titleBar.BackgroundTexture
|
||||
end,
|
||||
|
||||
CreateCombatTimeString = function(titleBar)
|
||||
local combatTimeString = titleBar:CreateFontString("$parentCombatTime", "overlay", "GameFontNormal")
|
||||
titleBar.CombatTime = combatTimeString
|
||||
return titleBar.CombatTime
|
||||
end,
|
||||
|
||||
GetCombatTimeString = function(titleBar)
|
||||
return titleBar.CombatTime
|
||||
end,
|
||||
|
||||
SetCombatTimeText = function(titleBar, combatTime)
|
||||
local combatTimeString = titleBar:GetCombatTimeString()
|
||||
if (type(combatTime) == "string") then
|
||||
combatTimeString:SetText(combatTime)
|
||||
|
||||
elseif (type(combatTime) == "number") then
|
||||
local timeAsString = DetailsFramework:IntegerToTimer(combatTime)
|
||||
combatTimeString:SetText(timeAsString)
|
||||
else
|
||||
--if no valid time passed, clear the timer
|
||||
combatTimeString:SetText("")
|
||||
end
|
||||
end,
|
||||
|
||||
Refresh = function(titleBar)
|
||||
local settings = titleBar:GetSettings()
|
||||
|
||||
--title bar is always shown
|
||||
settings.titlebar_shown = true
|
||||
|
||||
--titlebar_shown = false,
|
||||
--titlebar_height = 16,
|
||||
--titlebar_texture = "Details Serenity",
|
||||
--titlebar_texture_color = {.2, .2, .2, 0.8},
|
||||
|
||||
if (settings.titlebar_shown) then
|
||||
titleBar:Show()
|
||||
--height
|
||||
local height = settings.titlebar_height
|
||||
titleBar:SetHeight(height)
|
||||
|
||||
titleBar:SetTexture(settings.titlebar_texture, nil, settings.titlebar_texture_color)
|
||||
|
||||
local header = titleBar:GetHeader()
|
||||
|
||||
else
|
||||
titleBar:Hide()
|
||||
end
|
||||
|
||||
|
||||
|
||||
local timerShown = settings.timer_show
|
||||
|
||||
|
||||
local menuSupportFrame = titleBar:GetMenuSupportFrame()
|
||||
menuSupportFrame:Update()
|
||||
end,
|
||||
|
||||
GetMenuSupportFrame = function(titleBar)
|
||||
return titleBar.MenuSupportFrame
|
||||
end,
|
||||
|
||||
--menu support frame is the frame which will parent the menu buttons (cogwheel, segments, report button, etc)
|
||||
CreateMenuSupportFrame = function(titleBar)
|
||||
local menuSupportFrame = CreateFrame("frame", "$parentMenuSupportFrame", titleBar, "BackdropTemplate")
|
||||
titleBar.MenuSupportFrame = menuSupportFrame
|
||||
detailsFramework:Mixin(menuSupportFrame, menuSupportFrameMixin)
|
||||
menuSupportFrame:Constructor()
|
||||
return menuSupportFrame
|
||||
end,
|
||||
|
||||
CreateHeader = function(titleBar)
|
||||
local defaultHeaderTable = {
|
||||
{text = "", width = 20}, --spec icon
|
||||
{text = "Actor Name", width = 60, attribute = {name = true}},
|
||||
|
||||
{text = "Damage Done", width = 60, attribute = {1, 1}},
|
||||
{text = "DPS", width = 50, attribute = {1, 2}},
|
||||
{text = "Damage %", width = 50, attribute = {percent = true}},
|
||||
|
||||
{text = "Healing Done", width = 60, attribute = {1, 1}},
|
||||
{text = "HPS", width = 50, attribute = {1, 2}},
|
||||
{text = "Healing %", width = 50, attribute = {percent = true}},
|
||||
}
|
||||
|
||||
local defaultHeaderOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
local headerFrame = DetailsFramework:CreateHeader(titleBar, defaultHeaderTable, defaultHeaderOptions)
|
||||
titleBar.Header = headerFrame
|
||||
detailsFramework:Mixin(headerFrame, headerMixin)
|
||||
headerFrame:Constructor()
|
||||
return headerFrame
|
||||
end,
|
||||
|
||||
GetHeader = function(titleBar)
|
||||
return titleBar.Header
|
||||
end,
|
||||
}
|
||||
|
||||
local AllInOneWindowMixin = {
|
||||
SetSetting = function(window, value, ...)
|
||||
local config = window:GetSettings()
|
||||
local currentTable = config
|
||||
local lastKey = ""
|
||||
for index, key in ipairs({...}) do
|
||||
if (type(currentTable[key]) == "table") then
|
||||
currentTable = currentTable[value]
|
||||
else
|
||||
lastKey = key
|
||||
end
|
||||
end
|
||||
currentTable[lastKey] = value
|
||||
end,
|
||||
|
||||
IsOpened = function(window)
|
||||
return Details.AllInOneWindow.GetSettingsByID(window:GetSettingsID()).isOpened
|
||||
end,
|
||||
|
||||
SetWindowSize = function(self, width, height)
|
||||
|
||||
end,
|
||||
|
||||
GetSettings = function(window)
|
||||
return window.settings
|
||||
end,
|
||||
|
||||
SetSettingID = function(window, newSettingId)
|
||||
assert(type(newSettingId) ~= "number", "window.SetSettingID require a number on 'newSettingId'")
|
||||
local settings = Details.AllInOneWindow.GetSettingsByID(newSettingId)
|
||||
if (settings) then
|
||||
window.id = newSettingId
|
||||
window.settings = settings
|
||||
else
|
||||
error("window.SetSettingID could not find a settings for ID " .. newSettingId)
|
||||
end
|
||||
end,
|
||||
|
||||
GetSettingsID = function(window)
|
||||
return window.id
|
||||
end,
|
||||
|
||||
CreateTitleBar = function(window)
|
||||
local titleBar = CreateFrame("frame", "$parentTitleBar", window, "BackdropTemplate")
|
||||
window.TitleBar = titleBar
|
||||
df:Mixin(titleBar, titleBarMixin)
|
||||
titleBar:Constructor()
|
||||
return titleBar
|
||||
end,
|
||||
|
||||
GetTitleBar = function(window)
|
||||
return window.TitleBar
|
||||
end,
|
||||
|
||||
Refresh = function(window)
|
||||
local settingsId = window:GetSettingsID()
|
||||
local settings = window:GetSettings()
|
||||
|
||||
if (not settings.isOpened) then
|
||||
window:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local titleBar = window:GetTitleBar()
|
||||
titleBar:Refresh()
|
||||
end,
|
||||
}
|
||||
|
||||
--override
|
||||
titleBarMixin.SetSetting = AllInOneWindowMixin.SetSetting
|
||||
|
||||
--[=[
|
||||
lib window need to be on the AllInOneWindow:Update() so it can register the new libwindow table on profile change
|
||||
--register on libwindow
|
||||
LibWindow.RegisterConfig(newWindow, windowSettings.libwindow)
|
||||
LibWindow.RestorePosition(newWindow)
|
||||
LibWindow.MakeDraggable(newWindow)
|
||||
|
||||
--set the size using the settings
|
||||
newWindow:SetSize(windowSettings.width, windowSettings.height)
|
||||
|
||||
--rnable mouse for click through
|
||||
newWindow:EnableMouse(true)
|
||||
--setmovable for locked
|
||||
newWindow:SetMovable(true)
|
||||
|
||||
--title bar position (default on top)
|
||||
titleBar:SetPoint("topleft", newWindow, "topleft", 0, 0)
|
||||
titleBar:SetPoint("topright", newWindow, "topright", 0, 0)
|
||||
--title bar height
|
||||
titleBar:SetHeight(20)
|
||||
|
||||
--combat time position
|
||||
combatTimeString:SetPoint("left", titleBar, "left", 2, 0)
|
||||
--]=]
|
||||
|
||||
--create only the frame for a new window ~newwindow ñewwindow
|
||||
function Details.AllInOneWindow.CreateFrame(settingId)
|
||||
--create the new window
|
||||
local newFrame = CreateFrame("frame", "DetailsNewWindow" .. settingId, UIParent, "BackdropTemplate")
|
||||
newFrame.id = settingId
|
||||
df:Mixin(newFrame, AllInOneWindowMixin)
|
||||
|
||||
newFrame:SetPoint("center", UIParent, "center", -400, 0)
|
||||
|
||||
--create the title bar
|
||||
newFrame:CreateTitleBar()
|
||||
|
||||
|
||||
|
||||
--create scroll bar
|
||||
|
||||
|
||||
|
||||
--create resizers
|
||||
|
||||
|
||||
|
||||
--add the frame to the frame pool
|
||||
local frameId = Details.AllInOneWindow.AddFrame(newFrame)
|
||||
return newFrame
|
||||
end
|
||||
|
||||
--Entry Point to create a new window, must pass here at least once
|
||||
--create the settings for a new window plus the frames
|
||||
function Details.AllInOneWindow.CreateNew()
|
||||
local newSettings = {}
|
||||
--copy the settings prototype
|
||||
df.table.deploy(newSettings, defaultWindowSettings)
|
||||
--copy the settings from a skin
|
||||
local skinTable = Details:GetSkin("Minimalistic")
|
||||
df.table.deploy(newSettings, skinTable.instance_cprops)
|
||||
|
||||
--add the new settings table into the profile where the new window settings are stored
|
||||
local settingId = Details.AllInOneWindow.AddSetting(newSettings)
|
||||
|
||||
--reload all windows
|
||||
Details.AllInOneWindow.ReloadAll()
|
||||
|
||||
return settingId
|
||||
end
|
||||
|
||||
--assuming this will run when the profile is loaded
|
||||
--assuming there will be only one All In One Window
|
||||
|
||||
--used when a profile finished loading
|
||||
--entry point for loading a window on profile change, on Initialization or when a new window is created
|
||||
--at the moment of details! creation, there's zero settings available
|
||||
function Details.AllInOneWindow.ReloadAll()
|
||||
--get the amount of settings
|
||||
local numSettings = Details.AllInOneWindow.GetNumSettings()
|
||||
|
||||
--table with all window frames already created on this session
|
||||
local framesCreated = Details.AllInOneWindow.GetAllFrames()
|
||||
--next frame to be used
|
||||
local frameIndex = 1
|
||||
|
||||
for settingId = 1, numSettings do
|
||||
local windowSetting = Details.AllInOneWindow.GetSettingsByID(settingId)
|
||||
if (windowSetting.isOpened) then
|
||||
local windowFrame = framesCreated[frameIndex]
|
||||
if (not windowFrame) then
|
||||
windowFrame = Details.AllInOneWindow.CreateFrame(settingId)
|
||||
end
|
||||
frameIndex = frameIndex + 1
|
||||
windowFrame:SetSettingID(settingId)
|
||||
|
||||
--libwindow
|
||||
LibWindow.RegisterConfig(windowFrame, windowSetting.libwindow)
|
||||
LibWindow.RestorePosition(windowFrame)
|
||||
LibWindow.MakeDraggable(windowFrame)
|
||||
|
||||
--setup the frame using the settings
|
||||
windowFrame:Refresh()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function DetailsPrivite.WindowTooltip.CreateTooltipFrame()
|
||||
local damageDoneTooltipFrame = CreateFrame("frame", "DetailsWindowTooltipFrame", UIParent, "BackdropTemplate")
|
||||
DetailsFramework:ApplyStandardBackdrop(damageDoneTooltipFrame)
|
||||
|
||||
--create header
|
||||
|
||||
--create 4 scroll frames
|
||||
|
||||
--create 4 separators
|
||||
|
||||
--import data from the regular tooltip functions on each attribute file
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
|
||||
local Details = Details
|
||||
local DetailsFramework = _G.DetailsFramework
|
||||
local GameCooltip2 = GameCooltip2
|
||||
|
||||
function Details:CreateAPI2Frame()
|
||||
if (not _G.DetailsAPI2Frame or not _G.DetailsAPI2Frame.Initialized) then
|
||||
|
||||
--menu settings
|
||||
|
||||
_G.DetailsAPI2Frame.Initialized = true
|
||||
|
||||
local panelWidth = 800
|
||||
local panelHeight = 610
|
||||
local scrollWidth = 200
|
||||
local scrollHeight = 570
|
||||
local lineHeight = 20
|
||||
local lineAmount = 27
|
||||
local backdropColor = {.2, .2, .2, 0.2}
|
||||
local backdropColorOnEnter = {.8, .8, .8, 0.4}
|
||||
local backdropColorSelected = {1, 1, .8, 0.4}
|
||||
local yStart = -30
|
||||
local xAnchorPoint = 250
|
||||
local parametersAmount = 10
|
||||
local returnAmount = 10
|
||||
|
||||
--local Api2Frame = DetailsFramework:CreateSimplePanel(UIParent, panelWidth, panelHeight, "Details! API 2.0", "DetailsAPI2Frame")
|
||||
local Api2Frame = _G.DetailsAPI2Frame
|
||||
|
||||
Api2Frame:SetFrameStrata("FULLSCREEN")
|
||||
Api2Frame:SetPoint("center")
|
||||
DetailsFramework:ApplyStandardBackdrop(Api2Frame, false, 1.2)
|
||||
|
||||
--store
|
||||
local apiFunctionNames = {}
|
||||
local parametersLines = {}
|
||||
local returnLines = {}
|
||||
local currentSelected = 1
|
||||
|
||||
local api = Details.API_Description.namespaces[1].api
|
||||
|
||||
--on select api on the menu
|
||||
local onSelectAPI = function(self)
|
||||
local apiName = apiFunctionNames [self.index]
|
||||
if (not apiName) then
|
||||
Details:Msg("API name not found:", apiName)
|
||||
return
|
||||
end
|
||||
|
||||
--fill the box in the right with information about the API
|
||||
local apiInfo = api [self.index]
|
||||
if (not apiInfo) then
|
||||
Details:Msg("API information for api not found", apiName)
|
||||
return
|
||||
end
|
||||
|
||||
currentSelected = self.index
|
||||
|
||||
--update name and desc
|
||||
Api2Frame.ApiFunctionName.text = apiName
|
||||
Api2Frame.ApiFunctionDesc.text = apiInfo.desc
|
||||
|
||||
--update the copy line text box
|
||||
local parameters = ""
|
||||
for parameterIndex, parameterInfo in ipairs(apiInfo.parameters) do
|
||||
if (parameterInfo.required) then
|
||||
parameters = parameters .. parameterInfo.name .. ", "
|
||||
end
|
||||
end
|
||||
parameters = parameters:gsub(", $", "")
|
||||
|
||||
local returnValues = "local "
|
||||
for returnIndex, returnInfo in ipairs(apiInfo.returnValues) do
|
||||
returnValues = returnValues .. returnInfo.name .. ", "
|
||||
end
|
||||
returnValues = returnValues:gsub(", $", "")
|
||||
returnValues = returnValues .. " = "
|
||||
|
||||
if (parameters ~= "") then
|
||||
Api2Frame.ApiCopy.text = returnValues .. "Details." .. apiName .. "( " .. parameters .. " )"
|
||||
else
|
||||
Api2Frame.ApiCopy.text = returnValues .. "Details." .. apiName .. "()"
|
||||
end
|
||||
|
||||
Api2Frame.ApiCopy:SetFocus(true)
|
||||
Api2Frame.ApiCopy:HighlightText()
|
||||
|
||||
--parameters
|
||||
for i = 1, #parametersLines do
|
||||
local parameterLine = parametersLines [i]
|
||||
local parameterInfo = apiInfo.parameters [i]
|
||||
|
||||
if (parameterInfo) then
|
||||
parameterLine:Show()
|
||||
parameterLine.index = i
|
||||
parameterLine.name.text = parameterInfo.name
|
||||
parameterLine.typeData.text = parameterInfo.type
|
||||
parameterLine.required.text = parameterInfo.required and "yes" or "no"
|
||||
parameterLine.default.text = parameterInfo.default or ""
|
||||
else
|
||||
parameterLine:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
--return values
|
||||
for i = 1, #returnLines do
|
||||
local returnLine = returnLines [i]
|
||||
local returnInfo = apiInfo.returnValues [i]
|
||||
|
||||
if (returnInfo) then
|
||||
returnLine:Show()
|
||||
returnLine.index = i
|
||||
returnLine.name.text = returnInfo.name
|
||||
returnLine.typeData.text = returnInfo.type
|
||||
returnLine.desc.text = returnInfo.desc
|
||||
|
||||
else
|
||||
returnLine:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
--refresh the scroll box
|
||||
Api2Frame.scrollMenu:Refresh()
|
||||
end
|
||||
|
||||
--menu scroll
|
||||
local apiMenuScrollRefresh = function(self, data, offset, total_lines)
|
||||
for i = 1, total_lines do
|
||||
local index = i + offset
|
||||
local apiName = data [index]
|
||||
if (apiName) then
|
||||
local line = self:GetLine (i)
|
||||
line.text:SetText(apiName)
|
||||
line.index = index
|
||||
|
||||
if (currentSelected == index) then
|
||||
line:SetBackdropColor(unpack(backdropColorSelected))
|
||||
else
|
||||
line:SetBackdropColor(unpack(backdropColor))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for apiIndex, apiDesc in ipairs(api) do
|
||||
table.insert(apiFunctionNames, apiDesc.name)
|
||||
end
|
||||
|
||||
local api2ScrollMenu = DetailsFramework:CreateScrollBox (Api2Frame, "$parentApi2MenuScroll", apiMenuScrollRefresh, apiFunctionNames, scrollWidth, scrollHeight, lineAmount, lineHeight)
|
||||
DetailsFramework:ReskinSlider(api2ScrollMenu)
|
||||
api2ScrollMenu:SetPoint("topleft", Api2Frame, "topleft", 10, yStart)
|
||||
Api2Frame.scrollMenu = api2ScrollMenu
|
||||
|
||||
local lineOnEnter = function(self)
|
||||
self:SetBackdropColor(unpack(backdropColorOnEnter))
|
||||
|
||||
local apiName = apiFunctionNames [self.index]
|
||||
if (not apiName) then
|
||||
return
|
||||
end
|
||||
|
||||
--fill the box in the right with information about the API
|
||||
local apiInfo = api [self.index]
|
||||
if (not apiInfo) then
|
||||
return
|
||||
end
|
||||
|
||||
GameCooltip2:Preset(2)
|
||||
GameCooltip2:SetOwner(self, "left", "right", 2, 0)
|
||||
GameCooltip2:AddLine(apiInfo.desc)
|
||||
GameCooltip2:ShowCooltip()
|
||||
end
|
||||
|
||||
local lineOnLeave = function(self)
|
||||
if (currentSelected == self.index) then
|
||||
self:SetBackdropColor(unpack(backdropColorSelected))
|
||||
else
|
||||
self:SetBackdropColor(unpack(backdropColor))
|
||||
end
|
||||
|
||||
GameCooltip2:Hide()
|
||||
end
|
||||
|
||||
--create lines
|
||||
for i = 1, lineAmount do
|
||||
api2ScrollMenu:CreateLine (function(self, index)
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(lineHeight+1)) - 1)
|
||||
line:SetSize(scrollWidth - 2, lineHeight)
|
||||
line.index = index
|
||||
|
||||
line:SetScript("OnEnter", lineOnEnter)
|
||||
line:SetScript("OnLeave", lineOnLeave)
|
||||
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(unpack(backdropColor))
|
||||
|
||||
line.text = DetailsFramework:CreateLabel(line)
|
||||
line.text:SetPoint("left", line, "left", 2, 0)
|
||||
|
||||
line:SetScript("OnMouseDown", onSelectAPI)
|
||||
|
||||
return line
|
||||
end)
|
||||
end
|
||||
|
||||
--info box
|
||||
local infoWidth = panelWidth - xAnchorPoint - 10
|
||||
--api name
|
||||
Api2Frame.ApiFunctionName = DetailsFramework:CreateLabel(Api2Frame, "", 14, "orange")
|
||||
Api2Frame.ApiFunctionName:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, yStart)
|
||||
--api desc
|
||||
Api2Frame.ApiFunctionDesc = DetailsFramework:CreateLabel(Api2Frame)
|
||||
Api2Frame.ApiFunctionDesc:SetPoint("topleft", Api2Frame.ApiFunctionName, "bottomleft", 0, -2)
|
||||
Api2Frame.ApiFunctionDesc.width = infoWidth
|
||||
Api2Frame.ApiFunctionDesc.height = 22
|
||||
Api2Frame.ApiFunctionDesc.valign = "top"
|
||||
|
||||
--api func to copy
|
||||
local apiCopyString = DetailsFramework:CreateLabel(Api2Frame, "Copy String", 12, "orange")
|
||||
apiCopyString:SetPoint("topleft", Api2Frame.ApiFunctionDesc, "bottomleft", 0, -20)
|
||||
Api2Frame.ApiCopy = DetailsFramework:CreateTextEntry(Api2Frame, function() end, infoWidth, 20)
|
||||
Api2Frame.ApiCopy:SetPoint("topleft", apiCopyString, "bottomleft", 0, -2)
|
||||
Api2Frame.ApiCopy:SetTemplate(DetailsFramework:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX"))
|
||||
|
||||
--parameters
|
||||
local parametersYStart = yStart - 110
|
||||
local parametersString = DetailsFramework:CreateLabel(Api2Frame, "Parameters", 12, "orange")
|
||||
parametersString:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, parametersYStart)
|
||||
|
||||
parametersYStart = parametersYStart - 20
|
||||
|
||||
local space1, space2, space3 = 150, 300, 450
|
||||
local parametersHeader = CreateFrame("frame", nil, Api2Frame, "BackdropTemplate")
|
||||
parametersHeader:SetSize(infoWidth, 20)
|
||||
parametersHeader:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, parametersYStart)
|
||||
parametersHeader:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
parametersHeader:SetBackdropColor(unpack(backdropColor))
|
||||
parametersHeader.name = DetailsFramework:CreateLabel(parametersHeader, "Name", 12, "yellow")
|
||||
parametersHeader.typeData = DetailsFramework:CreateLabel(parametersHeader, "Type", 12, "yellow")
|
||||
parametersHeader.required = DetailsFramework:CreateLabel(parametersHeader, "Is Required", 12, "yellow")
|
||||
parametersHeader.default = DetailsFramework:CreateLabel(parametersHeader, "Default Value", 12, "yellow")
|
||||
parametersHeader.name:SetPoint("left", parametersHeader, "left", 2, 0)
|
||||
parametersHeader.typeData:SetPoint("left", parametersHeader, "left", space1, 0)
|
||||
parametersHeader.required:SetPoint("left", parametersHeader, "left", space2, 0)
|
||||
parametersHeader.default:SetPoint("left", parametersHeader, "left", space3, 0)
|
||||
|
||||
local parameterOnEnter = function(self)
|
||||
GameCooltip2:Preset(2)
|
||||
GameCooltip2:SetOwner(self)
|
||||
|
||||
--fill the box in the right with information about the API
|
||||
local apiInfo = api [currentSelected]
|
||||
if (not apiInfo) then
|
||||
return
|
||||
end
|
||||
GameCooltip2:AddLine(apiInfo.parameters [self.index].desc)
|
||||
GameCooltip2:ShowCooltip()
|
||||
|
||||
self:SetBackdropColor(unpack(backdropColorOnEnter))
|
||||
end
|
||||
local parameterOnLeave = function(self)
|
||||
GameCooltip2:Hide()
|
||||
self:SetBackdropColor(unpack(backdropColor))
|
||||
end
|
||||
|
||||
for i = 1, parametersAmount do
|
||||
local parameterLine = {}
|
||||
local f = CreateFrame("frame", nil, Api2Frame, "BackdropTemplate")
|
||||
f:SetSize(infoWidth, 20)
|
||||
f:SetScript("OnEnter", parameterOnEnter)
|
||||
f:SetScript("OnLeave", parameterOnLeave)
|
||||
f:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
f:SetBackdropColor(unpack(backdropColor))
|
||||
f:Hide()
|
||||
|
||||
f.name = DetailsFramework:CreateLabel(f)
|
||||
f.typeData = DetailsFramework:CreateLabel(f)
|
||||
f.required = DetailsFramework:CreateLabel(f)
|
||||
f.default = DetailsFramework:CreateLabel(f)
|
||||
|
||||
f:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, parametersYStart + (-i * 20))
|
||||
|
||||
f.name:SetPoint("left", f, "left", 2, 0)
|
||||
f.typeData:SetPoint("left", f, "left", space1, 0)
|
||||
f.required:SetPoint("left", f, "left", space2, 0)
|
||||
f.default:SetPoint("left", f, "left", space3, 0)
|
||||
|
||||
table.insert(parametersLines, f)
|
||||
end
|
||||
|
||||
--return value box
|
||||
local returnYStart = yStart - 260
|
||||
local returnString = DetailsFramework:CreateLabel(Api2Frame, "Return Values", 12, "orange")
|
||||
returnString:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, returnYStart)
|
||||
|
||||
returnYStart = returnYStart - 20
|
||||
|
||||
local space1 = 200
|
||||
local returnHeader = CreateFrame("frame", nil, Api2Frame, "BackdropTemplate")
|
||||
returnHeader:SetSize(infoWidth, 20)
|
||||
returnHeader:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, returnYStart)
|
||||
returnHeader:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
returnHeader:SetBackdropColor(unpack(backdropColor))
|
||||
returnHeader.name = DetailsFramework:CreateLabel(returnHeader, "Name", 12, "yellow")
|
||||
returnHeader.typeData = DetailsFramework:CreateLabel(returnHeader, "Type", 12, "yellow")
|
||||
returnHeader.name:SetPoint("left", returnHeader, "left", 2, 0)
|
||||
returnHeader.typeData:SetPoint("left", returnHeader, "left", space1, 0)
|
||||
|
||||
local returnOnEnter = function(self)
|
||||
self:SetBackdropColor(unpack(backdropColorOnEnter))
|
||||
end
|
||||
local returnOnLeave = function(self)
|
||||
self:SetBackdropColor(unpack(backdropColor))
|
||||
end
|
||||
|
||||
for i = 1, returnAmount do
|
||||
local parameterLine = {}
|
||||
local f = CreateFrame("frame", nil, Api2Frame, "BackdropTemplate")
|
||||
f:SetSize(infoWidth, 20)
|
||||
f:SetScript("OnEnter", returnOnEnter)
|
||||
f:SetScript("OnLeave", returnOnLeave)
|
||||
f:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
f:SetBackdropColor(unpack(backdropColor))
|
||||
f:Hide()
|
||||
|
||||
f.name = DetailsFramework:CreateLabel(f)
|
||||
f.typeData = DetailsFramework:CreateLabel(f)
|
||||
|
||||
f.desc = DetailsFramework:CreateLabel(f, "", 10, "gray")
|
||||
f.desc.width = infoWidth
|
||||
f.desc.height = 60
|
||||
f.desc.valign = "top"
|
||||
|
||||
f:SetPoint("topleft", Api2Frame, "topleft", xAnchorPoint, returnYStart + (-i * 20))
|
||||
|
||||
f.name:SetPoint("left", f, "left", 2, 0)
|
||||
f.typeData:SetPoint("left", f, "left", space1, 0)
|
||||
|
||||
f.desc:SetPoint("topleft", f.name, "bottomleft", 0, -5)
|
||||
|
||||
table.insert(returnLines, f)
|
||||
end
|
||||
|
||||
function Api2Frame.Refresh()
|
||||
onSelectAPI (api2ScrollMenu.Frames [1])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,253 @@
|
||||
|
||||
local Details = Details
|
||||
local DF = DetailsFramework
|
||||
local _
|
||||
|
||||
--namespace
|
||||
Details.AuraTracker = {
|
||||
buff = {},
|
||||
debuff = {},
|
||||
}
|
||||
|
||||
--frame options
|
||||
local windowWidth = 800
|
||||
local windowHeight = 670
|
||||
local scrollWidth = 790
|
||||
local scrollHeightBuff = 400
|
||||
local scrollHeightDebuff = 200
|
||||
local scrollLineAmountBuff = 20
|
||||
local scrollLineAmountDebuff = 10
|
||||
local scrollLineHeight = 20
|
||||
|
||||
--templates
|
||||
local dropdownTemplate = DetailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWNDARK_TEMPLATE")
|
||||
|
||||
function Details.AuraTracker.AddAura(auraType, spellid)
|
||||
Details.AuraTracker[auraType][spellid] = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function HandleAuraBuff(...)
|
||||
local auraInfo = AuraUtil.PackAuraData(...)
|
||||
Details.AuraTracker.buff[auraInfo.spellId] = auraInfo
|
||||
end
|
||||
|
||||
local function HandleAuraDebuff(...)
|
||||
local auraInfo = AuraUtil.PackAuraData(...)
|
||||
Details.AuraTracker.debuff[auraInfo.spellId] = auraInfo
|
||||
end
|
||||
|
||||
local doFullAuraUpdate = function()
|
||||
Details:Destroy(Details.AuraTracker.buff)
|
||||
Details:Destroy(Details.AuraTracker.debuff)
|
||||
|
||||
local unitId = "player"
|
||||
|
||||
local batchCount = nil
|
||||
local usePackedAura = true
|
||||
AuraUtil.ForEachAura(unitId, "HELPFUL", batchCount, HandleAuraBuff, usePackedAura)
|
||||
AuraUtil.ForEachAura(unitId, "HARMFUL", batchCount, HandleAuraDebuff, usePackedAura)
|
||||
|
||||
unitId = "pet"
|
||||
AuraUtil.ForEachAura(unitId, "HELPFUL", batchCount, HandleAuraBuff, usePackedAura)
|
||||
AuraUtil.ForEachAura(unitId, "HARMFUL", batchCount, HandleAuraDebuff, usePackedAura)
|
||||
|
||||
Details.AuraTracker.RefreshScrollData()
|
||||
end
|
||||
|
||||
function Details.AuraTracker.OnShowAuraTrackerFrame(auraTrackerFrame)
|
||||
doFullAuraUpdate()
|
||||
auraTrackerFrame.EventFrame:RegisterUnitEvent("UNIT_AURA", "player")
|
||||
end
|
||||
|
||||
function Details.AuraTracker.OnHideAuraTrackerFrame(auraTrackerFrame)
|
||||
auraTrackerFrame.EventFrame:UnregisterEvent("UNIT_AURA")
|
||||
end
|
||||
|
||||
function Details.AuraTracker.CreatePanel()
|
||||
--create a panel
|
||||
local auraTrackerFrame = DetailsFramework:CreateSimplePanel(UIParent)
|
||||
auraTrackerFrame:SetSize(windowWidth, windowHeight)
|
||||
auraTrackerFrame:SetTitle("Details! Aura Tracker")
|
||||
|
||||
--disable the buil-in mouse integration of the simple panel, doing this to use LibWindow-1.1 as the window management
|
||||
auraTrackerFrame:SetScript("OnMouseDown", nil)
|
||||
auraTrackerFrame:SetScript("OnMouseUp", nil)
|
||||
|
||||
Details.AuraTracker.AuraTrackerFrame = auraTrackerFrame
|
||||
auraTrackerFrame.data = {
|
||||
buffs = {},
|
||||
debuffs = {},
|
||||
}
|
||||
|
||||
auraTrackerFrame.EventFrame = CreateFrame("frame")
|
||||
auraTrackerFrame.EventFrame:SetScript("OnEvent", Details.AuraTracker.OnUnitAuraEvent)
|
||||
|
||||
--register in the libWindow
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(auraTrackerFrame, Details.aura_tracker_frame.position)
|
||||
LibWindow.MakeDraggable(auraTrackerFrame)
|
||||
LibWindow.RestorePosition(auraTrackerFrame)
|
||||
|
||||
--scale bar
|
||||
local scaleBar = DetailsFramework:CreateScaleBar(auraTrackerFrame, Details.aura_tracker_frame.scaletable)
|
||||
auraTrackerFrame:SetScale(Details.aura_tracker_frame.scaletable.scale)
|
||||
|
||||
--status bar
|
||||
local statusBar = DetailsFramework:CreateStatusBar(auraTrackerFrame)
|
||||
statusBar.text = statusBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
statusBar.text:SetPoint("left", statusBar, "left", 5, 0)
|
||||
statusBar.text:SetText("By Terciob | Part of Details! Damage Meter")
|
||||
DetailsFramework:SetFontSize(statusBar.text, 11)
|
||||
DetailsFramework:SetFontColor(statusBar.text, "gray")
|
||||
|
||||
--header
|
||||
local headerTable = {
|
||||
{text = "", width = 20},
|
||||
{text = "Aura Name", width = 162},
|
||||
{text = "Spell Id", width = 100},
|
||||
{text = "Lua Table", width = 200},
|
||||
}
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
auraTrackerFrame.Header = DetailsFramework:CreateHeader(auraTrackerFrame, headerTable, headerOptions)
|
||||
auraTrackerFrame.Header:SetPoint("topleft", auraTrackerFrame, "topleft", 5, -22)
|
||||
|
||||
--create a scroll to show all buffs
|
||||
local buffScroll = DetailsFramework:CreateScrollBox(auraTrackerFrame, "$parentBuffScrollBox", Details.AuraTracker.RefreshScroll, auraTrackerFrame.data.buffs, scrollWidth, scrollHeightBuff, scrollLineAmountBuff, scrollLineHeight)
|
||||
DetailsFramework:ReskinSlider(buffScroll)
|
||||
buffScroll:CreateLines(Details.AuraTracker.CreateScrollLine, scrollLineAmountBuff)
|
||||
buffScroll:SetPoint("topleft", auraTrackerFrame, "topleft", 5, -42)
|
||||
auraTrackerFrame.BuffScroll = buffScroll
|
||||
|
||||
--create a scroll to show all debuffs
|
||||
local debuffScroll = DetailsFramework:CreateScrollBox(auraTrackerFrame, "$parentDebuffScrollBox", Details.AuraTracker.RefreshScroll, auraTrackerFrame.data.debuffs, scrollWidth, scrollHeightDebuff, scrollLineAmountDebuff, scrollLineHeight)
|
||||
debuffScroll:CreateLines(Details.AuraTracker.CreateScrollLine, scrollLineAmountDebuff)
|
||||
DetailsFramework:ReskinSlider(debuffScroll)
|
||||
debuffScroll:SetPoint("topleft", buffScroll, "bottomleft", 0, -2)
|
||||
auraTrackerFrame.DebuffScroll = debuffScroll
|
||||
|
||||
Details.AuraTracker.framesCreated = true
|
||||
end
|
||||
|
||||
local formatToLuaTable = {
|
||||
--[232698] = 1, --Shadowform
|
||||
doFormat1 = function(auraInfo)
|
||||
return "[" .. auraInfo.spellId .. "] = 1, --" .. auraInfo.name
|
||||
end,
|
||||
}
|
||||
|
||||
--if you need your own table format, override the function below as: function(auraInfo) return "" end
|
||||
--[[GLOBAL]] DETAILS_AURATRACKER_LUATABLE_FUNC = nil
|
||||
|
||||
--[371354] = {[131] = 1, [151] = 2, [174] = 3, [1] = 131, [2] = 151, [3] = 174}, --Phial of the Eye in the Storm
|
||||
|
||||
function Details.AuraTracker.RefreshScroll(self, data, offset, totalLines)
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local auraInfo = data[index]
|
||||
|
||||
if (auraInfo) then
|
||||
local line = self:GetLine(i)
|
||||
line.Icon.texture = auraInfo.icon
|
||||
line.Name.text = auraInfo.name
|
||||
line.SpellId.text = auraInfo.spellId
|
||||
local globalfunc = DETAILS_AURATRACKER_LUATABLE_FUNC
|
||||
line.LuaTableEntry.text = globalfunc and globalfunc(auraInfo) or formatToLuaTable.doFormat1(auraInfo) --doFormat2NoIndex
|
||||
|
||||
line.Name:SetCursorPosition(0)
|
||||
line.LuaTableEntry:SetCursorPosition(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Details.AuraTracker.RefreshScrollData()
|
||||
local buffData = {}
|
||||
for spellId, auraInfo in pairs(Details.AuraTracker.buff) do
|
||||
buffData[#buffData+1] = auraInfo
|
||||
end
|
||||
|
||||
local debuffData = {}
|
||||
for spellId, auraInfo in pairs(Details.AuraTracker.debuff) do
|
||||
debuffData[#debuffData+1] = auraInfo
|
||||
end
|
||||
|
||||
Details.AuraTracker.AuraTrackerFrame.BuffScroll:SetData(buffData)
|
||||
Details.AuraTracker.AuraTrackerFrame.BuffScroll:Refresh()
|
||||
Details.AuraTracker.AuraTrackerFrame.DebuffScroll:SetData(debuffData)
|
||||
Details.AuraTracker.AuraTrackerFrame.DebuffScroll:Refresh()
|
||||
end
|
||||
|
||||
function Details.AuraTracker.OnUnitAuraEvent(self, event, unit)
|
||||
if unit ~= "player" and unit ~= "pet" then
|
||||
return
|
||||
end
|
||||
doFullAuraUpdate(unit)
|
||||
end
|
||||
|
||||
function Details.AuraTracker.CreateScrollLine(self, lineId)
|
||||
local line = CreateFrame("frame", "$parentLine" .. lineId, self, "BackdropTemplate")
|
||||
line.lineId = lineId
|
||||
|
||||
line:SetPoint("topleft", self, "topleft", 2, (scrollLineHeight * (lineId - 1) * -1) - 2)
|
||||
line:SetPoint("topright", self, "topright", -2, (scrollLineHeight * (lineId - 1) * -1) - 2)
|
||||
line:SetHeight(scrollLineHeight)
|
||||
|
||||
DetailsFramework:Mixin(line, DetailsFramework.HeaderFunctions)
|
||||
DetailsFramework.BackdropUtil:SetColorStripe(line, lineId)
|
||||
|
||||
local header = self:GetParent().Header
|
||||
|
||||
--aura icon
|
||||
local auraIconTexture = DetailsFramework:CreateTexture(line, "", scrollLineHeight - 2, scrollLineHeight - 2, "overlay", {.1, .9, .1, .9})
|
||||
|
||||
--aura name
|
||||
local auraNameTextField = DetailsFramework:CreateTextEntry(line, function()end, header:GetColumnWidth(2), scrollLineHeight, _, _, _, dropdownTemplate)
|
||||
auraNameTextField:SetJustifyH("left")
|
||||
auraNameTextField:SetTextInsets(3, 3, 0, 0)
|
||||
auraNameTextField:SetAutoSelectTextOnFocus(true)
|
||||
|
||||
--spellId text field
|
||||
local spellIdTextField = DetailsFramework:CreateTextEntry(line, function()end, header:GetColumnWidth(3), scrollLineHeight, _, _, _, dropdownTemplate)
|
||||
spellIdTextField:SetJustifyH("left")
|
||||
spellIdTextField:SetTextInsets(3, 3, 0, 0)
|
||||
spellIdTextField:SetAutoSelectTextOnFocus(true)
|
||||
|
||||
--formatted lua table
|
||||
local luaTableEntryTextField = DetailsFramework:CreateTextEntry(line, function()end, header:GetColumnWidth(4), scrollLineHeight, _, _, _, dropdownTemplate)
|
||||
luaTableEntryTextField:SetJustifyH("left")
|
||||
luaTableEntryTextField:SetTextInsets(3, 3, 0, 0)
|
||||
luaTableEntryTextField:SetAutoSelectTextOnFocus(true)
|
||||
|
||||
line:AddFrameToHeaderAlignment(auraIconTexture)
|
||||
line:AddFrameToHeaderAlignment(auraNameTextField)
|
||||
line:AddFrameToHeaderAlignment(spellIdTextField)
|
||||
line:AddFrameToHeaderAlignment(luaTableEntryTextField)
|
||||
|
||||
line:AlignWithHeader(header, "left")
|
||||
|
||||
line.Icon = auraIconTexture
|
||||
line.Name = auraNameTextField
|
||||
line.SpellId = spellIdTextField
|
||||
line.LuaTableEntry = luaTableEntryTextField
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
function Details.AuraTracker.Open()
|
||||
if (not Details.AuraTracker.framesCreated) then
|
||||
Details.AuraTracker.CreatePanel()
|
||||
end
|
||||
Details.AuraTracker.AuraTrackerFrame:Show()
|
||||
Details.AuraTracker.OnShowAuraTrackerFrame(Details.AuraTracker.AuraTrackerFrame)
|
||||
end
|
||||
|
||||
function Details.AuraTracker.Close()
|
||||
if (Details.AuraTracker.framesCreated) then
|
||||
Details.AuraTracker.AuraTrackerFrame:Hide()
|
||||
Details.AuraTracker.OnHideAuraTrackerFrame(Details.AuraTracker.AuraTrackerFrame)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,289 @@
|
||||
|
||||
if (true) then
|
||||
return
|
||||
end
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local libwindow = LibStub("LibWindow-1.1")
|
||||
|
||||
--this function isn't in use
|
||||
function Details.OpenDpsBenchmark()
|
||||
|
||||
--main frame
|
||||
|
||||
local DF = Details.gump
|
||||
local _ = nil
|
||||
|
||||
--declaration
|
||||
local f = CreateFrame("frame", "DetailsBenchmark", UIParent,"BackdropTemplate")
|
||||
f:SetSize(800, 600)
|
||||
f:SetPoint("left", UIParent, "left")
|
||||
f:SetFrameStrata("LOW")
|
||||
f:EnableMouse(true)
|
||||
f:SetMovable(true)
|
||||
f:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
f:SetBackdropColor(0, 0, 0, 0.9)
|
||||
f:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--register to libwindow
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(f, Details.benchmark_db.frame)
|
||||
LibWindow.RestorePosition(f)
|
||||
LibWindow.MakeDraggable(f)
|
||||
LibWindow.SavePosition(f)
|
||||
|
||||
--titlebar
|
||||
f.TitleBar = CreateFrame("frame", "$parentTitleBar", f,"BackdropTemplate")
|
||||
f.TitleBar:SetPoint("topleft", f, "topleft", 2, -3)
|
||||
f.TitleBar:SetPoint("topright", f, "topright", -2, -3)
|
||||
f.TitleBar:SetHeight(20)
|
||||
f.TitleBar:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
f.TitleBar:SetBackdropColor(.2, .2, .2, 1)
|
||||
f.TitleBar:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--close button
|
||||
f.Close = CreateFrame("button", "$parentCloseButton", f,"BackdropTemplate")
|
||||
f.Close:SetPoint("right", f.TitleBar, "right", -2, 0)
|
||||
f.Close:SetSize(16, 16)
|
||||
f.Close:SetNormalTexture(Details.gump.folder .. "icons")
|
||||
f.Close:SetHighlightTexture(Details.gump.folder .. "icons")
|
||||
f.Close:SetPushedTexture(Details.gump.folder .. "icons")
|
||||
f.Close:GetNormalTexture():SetTexCoord(0, 16/128, 0, 1)
|
||||
f.Close:GetHighlightTexture():SetTexCoord(0, 16/128, 0, 1)
|
||||
f.Close:GetPushedTexture():SetTexCoord(0, 16/128, 0, 1)
|
||||
f.Close:SetAlpha(0.7)
|
||||
f.Close:SetScript("OnClick", function() f:Hide() end)
|
||||
|
||||
--title
|
||||
f.Title = f.TitleBar:CreateFontString("$parentTitle", "overlay", "GameFontNormal")
|
||||
f.Title:SetPoint("center", f.TitleBar, "center")
|
||||
f.Title:SetTextColor(.8, .8, .8, 1)
|
||||
f.Title:SetText("Details! Benchmark")
|
||||
|
||||
DF:InstallTemplate("font", "DETAILS_BENCHMARK_NORMAL", {color = "white", size = 10, font = "Friz Quadrata TT"})
|
||||
|
||||
function f.CreateCombatObject()
|
||||
local t = {}
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
function f.StartNewBenchmark()
|
||||
|
||||
end
|
||||
|
||||
function f.StopCurrentBenchmark()
|
||||
|
||||
end
|
||||
|
||||
|
||||
f.OnTickInterval = 0
|
||||
function f.UpdateOnTick (self, deltaTime)
|
||||
f.OnTickInterval = f.OnTickInterval + deltaTime
|
||||
if (f.OnTickInterval >= 0.024) then
|
||||
--do the update
|
||||
|
||||
--reset the interval
|
||||
f.OnTickInterval = 0
|
||||
end
|
||||
end
|
||||
function f.StartUpdateOnTick()
|
||||
f:SetScript("OnUpdate", f.UpdateOnTick)
|
||||
end
|
||||
|
||||
--events
|
||||
f:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
f:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
|
||||
f:SetScript("OnEvent", function(self, event, ...)
|
||||
if (event == "PLAYER_REGEN_DISABLED") then
|
||||
f.StartNewBenchmark()
|
||||
|
||||
elseif (event == "PLAYER_REGEN_ENABLED") then
|
||||
f.StopCurrentBenchmark()
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
local normal_text_template = DF:GetTemplate("font", "DETAILS_BENCHMARK_NORMAL")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
--locations
|
||||
f.FrameLocations = {
|
||||
summary = {10, -30},
|
||||
auras = {10, -120},
|
||||
spells = {10, -180},
|
||||
history = {10, -280},
|
||||
}
|
||||
f.FrameSizes = {
|
||||
default = {300, 200},
|
||||
}
|
||||
|
||||
--summary block
|
||||
|
||||
--declaration
|
||||
local summaryFrame = CreateFrame("frame", "$parentSummaryFrame", f,"BackdropTemplate")
|
||||
summaryFrame:SetPoint("topleft", f, "topleft", unpack(f.FrameLocations.summary))
|
||||
summaryFrame:SetSize(unpack(f.FrameSizes.default))
|
||||
summaryFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
summaryFrame:SetBackdropColor(0, 0, 0, 0.9)
|
||||
summaryFrame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--time to test string and dropdown
|
||||
local build_time_list = function()
|
||||
local t = {
|
||||
{value = 40, label = "40 seconds"},
|
||||
{value = 60, label = "60 seconds"},
|
||||
{value = 90, label = "90 seconds"},
|
||||
{value = 120, label = "2 minutes"},
|
||||
{value = 180, label = "3 minutes"},
|
||||
{value = 300, label = "5 minutes"},
|
||||
}
|
||||
return t
|
||||
end
|
||||
|
||||
summaryFrame.TimeToTestLabel = DF:CreateLabel(summaryFrame, "Amount of Time", normal_text_template)
|
||||
summaryFrame.TimeToTestDropdown = DF:CreateDropDown (summaryFrame, build_time_list, default, 150, 20, _, _, options_dropdown_template)
|
||||
|
||||
--description string and text entry
|
||||
summaryFrame.DescriptionLabel = DF:CreateLabel(summaryFrame, "Description", normal_text_template)
|
||||
summaryFrame.DescriptionEntry = DF:CreateTextEntry(summaryFrame, function()end, 120, 20, nil, _, nil, options_dropdown_template)
|
||||
|
||||
--DPS Amount string
|
||||
summaryFrame.DPSLabel = DF:CreateLabel(summaryFrame, "100K", normal_text_template)
|
||||
|
||||
--TIME ELAPSED string
|
||||
summaryFrame.TimeElapsedLabel = DF:CreateLabel(summaryFrame, "01:00", normal_text_template)
|
||||
|
||||
--boss simulation string and dropdown
|
||||
local build_bosssimulation_list, default = function()
|
||||
local t = {
|
||||
{value = "patchwerk", label = "Patchwerk"},
|
||||
}
|
||||
return t
|
||||
end
|
||||
summaryFrame.BossSimulationLabel = DF:CreateLabel(summaryFrame, "Boss Simulation", normal_text_template)
|
||||
summaryFrame.BossSimulationDropdown = DF:CreateDropDown (summaryFrame, build_bosssimulation_list, default, 150, 20, _, _, options_dropdown_template)
|
||||
|
||||
--boss records line with a tooltip importing data from the storage
|
||||
summaryFrame.BossRecordsFrame = CreateFrame("frame", nil, summaryFrame,"BackdropTemplate")
|
||||
summaryFrame.BossRecordsFrame:SetSize(f.FrameSizes.default[1]-20, 20)
|
||||
summaryFrame.BossRecordsFrame:SetBackdropColor(0, 0, 0, 0.3)
|
||||
summaryFrame.BossRecordsFrame:SetScript("OnEnter", function()
|
||||
|
||||
end)
|
||||
summaryFrame.BossRecordsFrame:SetScript("OnLeave", function()
|
||||
|
||||
end)
|
||||
|
||||
--set the points
|
||||
do
|
||||
local x, y = 10, -10
|
||||
summaryFrame.TimeToTestLabel:SetPoint("topleft", summaryFrame, "topleft", x, y)
|
||||
summaryFrame.TimeToTestDropdown:SetPoint("topleft", summaryFrame.TimeToTestLabel, "bottomleft", 0, -2)
|
||||
|
||||
--y = y - 40
|
||||
summaryFrame.DescriptionLabel:SetPoint("topleft", summaryFrame, "topleft", x+160, y)
|
||||
summaryFrame.DescriptionEntry:SetPoint("topleft", summaryFrame.DescriptionLabel, "bottomleft", 0, -2)
|
||||
|
||||
y = y - 40
|
||||
summaryFrame.DPSLabel:SetPoint("topleft", summaryFrame, "topleft", x, y)
|
||||
summaryFrame.TimeElapsedLabel:SetPoint("topleft", summaryFrame, "topleft", x + 100, y)
|
||||
|
||||
y = y - 40
|
||||
summaryFrame.BossSimulationLabel:SetPoint("topleft", summaryFrame, "topleft", x, y)
|
||||
summaryFrame.BossSimulationDropdown:SetPoint("topleft", summaryFrame.BossSimulationLabel, "bottomleft", 0, -2)
|
||||
|
||||
y = y - 40
|
||||
summaryFrame.BossRecordsFrame:SetPoint("topleft", summaryFrame, "topleft", 0, 0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--spells block
|
||||
|
||||
--declaration
|
||||
local spellsFrame = CreateFrame("frame", "$parentSpellsFrame", f,"BackdropTemplate")
|
||||
spellsFrame:SetPoint("topleft", f, "topleft", unpack(f.FrameLocations.spells))
|
||||
spellsFrame:SetSize(unpack(f.FrameSizes.default))
|
||||
spellsFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
spellsFrame:SetBackdropColor(0, 0, 0, 0.9)
|
||||
spellsFrame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--header with the string titles:
|
||||
--Spell Icon | DPS | Damage | Casts | Criticals | Highest Damage
|
||||
|
||||
--scrollpanel
|
||||
--each line with:
|
||||
--Texture for the icon
|
||||
--5 strings for the data
|
||||
--hover over scripts
|
||||
|
||||
--auras block
|
||||
|
||||
--declaration
|
||||
local aurasFrame = CreateFrame("frame", "$parentAurasFrame", f,"BackdropTemplate")
|
||||
aurasFrame:SetPoint("topleft", f, "topleft", unpack(f.FrameLocations.auras))
|
||||
aurasFrame:SetSize(unpack(f.FrameSizes.default))
|
||||
aurasFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
aurasFrame:SetBackdropColor(0, 0, 0, 0.9)
|
||||
aurasFrame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--will be 9 blocks?
|
||||
|
||||
--each block with:
|
||||
--Texture for the icon
|
||||
--3 strings for Total Update, Applications and Refreshes
|
||||
|
||||
|
||||
--history block
|
||||
|
||||
--declaration
|
||||
local historyFrame = CreateFrame("frame", "$parentHistoryFrame", f,"BackdropTemplate")
|
||||
historyFrame:SetPoint("topleft", f, "topleft", unpack(f.FrameLocations.history))
|
||||
historyFrame:SetSize(unpack(f.FrameSizes.default))
|
||||
historyFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
historyFrame:SetBackdropColor(0, 0, 0, 0.9)
|
||||
historyFrame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--header with the string titles:
|
||||
--Spec | ILevel | DPS | Time | Talents | Crit | Haste | Versatility | Mastery | Int | Description
|
||||
|
||||
--scrollpanel
|
||||
--each line with:
|
||||
--7 Textures for talent icons
|
||||
--10 strings for the data
|
||||
--hover over scripts
|
||||
|
||||
|
||||
|
||||
--mechanics
|
||||
|
||||
--to open the window
|
||||
--on target a training dummy
|
||||
--need to be on a specific map / sanctuary
|
||||
|
||||
--on start a new combat:
|
||||
--start the timer
|
||||
--start the boss script if not patchwerk
|
||||
--create the graphic tables for *player total damage and *spell damage
|
||||
--create aura tables / grab auras already applied to the player / auras with no duration wont be added
|
||||
|
||||
--on tick:
|
||||
--*check if the time is gone *update the time string *update the graphic *update the spells *upate the auras
|
||||
|
||||
|
||||
--on finishes:
|
||||
--stop the timer and check if the elapsed time is done
|
||||
--create a new benchmark object to store the test
|
||||
--export the data to this new object
|
||||
--add this new object to the benchmark storage table
|
||||
--update the history scrollbar
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local Loc = _G.LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
--config bookmarks
|
||||
function Details:OpenBookmarkConfig()
|
||||
|
||||
if (not _G.DetailsBookmarkManager) then
|
||||
DF:CreateSimplePanel(UIParent, 465, 460, Loc ["STRING_OPTIONS_MANAGE_BOOKMARKS"], "DetailsBookmarkManager")
|
||||
local panel = _G.DetailsBookmarkManager
|
||||
DF:ApplyStandardBackdrop(panel)
|
||||
panel:SetBackdropColor(.1, .1, .1, .9)
|
||||
panel.blocks = {}
|
||||
|
||||
local clear_func = function(self, button, id)
|
||||
if (Details.switch.table [id]) then
|
||||
Details.switch.table [id].atributo = nil
|
||||
Details.switch.table [id].sub_atributo = nil
|
||||
panel:Refresh()
|
||||
Details.switch:Update()
|
||||
end
|
||||
end
|
||||
|
||||
local select_attribute = function(_, _, _, attribute, sub_atribute)
|
||||
if (not sub_atribute) then
|
||||
return
|
||||
end
|
||||
Details.switch.table [panel.selecting_slot].atributo = attribute
|
||||
Details.switch.table [panel.selecting_slot].sub_atributo = sub_atribute
|
||||
panel:Refresh()
|
||||
Details.switch:Update()
|
||||
end
|
||||
|
||||
local cooltip_color = {.1, .1, .1, .3}
|
||||
local set_att = function(self, button, id)
|
||||
panel.selecting_slot = id
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:SetType (3)
|
||||
GameCooltip:SetOwner(self)
|
||||
Details:MontaAtributosOption (Details:GetInstance(1), select_attribute)
|
||||
GameCooltip:SetColor (1, cooltip_color)
|
||||
GameCooltip:SetColor (2, cooltip_color)
|
||||
GameCooltip:SetOption("HeightAnchorMod", -7)
|
||||
GameCooltip:SetOption("TextSize", Details.font_sizes.menus)
|
||||
GameCooltip:SetBackdrop(1, Details.tooltip_backdrop, nil, Details.tooltip_border_color)
|
||||
GameCooltip:SetBackdrop(2, Details.tooltip_backdrop, nil, Details.tooltip_border_color)
|
||||
|
||||
GameCooltip:ShowCooltip()
|
||||
end
|
||||
|
||||
local button_backdrop = {bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 64, insets = {left=0, right=0, top=0, bottom=0}}
|
||||
|
||||
local set_onenter = function(self, capsule)
|
||||
self:SetBackdropColor(1, 1, 1, 0.9)
|
||||
capsule.icon:SetBlendMode("ADD")
|
||||
end
|
||||
local set_onleave = function(self, capsule)
|
||||
self:SetBackdropColor(0, 0, 0, 0.5)
|
||||
capsule.icon:SetBlendMode("BLEND")
|
||||
end
|
||||
|
||||
for i = 1, 40 do
|
||||
local clear = DF:CreateButton(panel, clear_func, 16, 16, nil, i, nil, [[Interface\Glues\LOGIN\Glues-CheckBox-Check]])
|
||||
if (i%2 ~= 0) then
|
||||
--impar
|
||||
clear:SetPoint(15, (( i*10 ) * -1) - 35) --left
|
||||
else
|
||||
--par
|
||||
local o = i-1
|
||||
clear:SetPoint(250, (( o*10 ) * -1) - 35) --right
|
||||
end
|
||||
|
||||
local set = DF:CreateButton(panel, set_att, 16, 16, nil, i)
|
||||
set:SetPoint("left", clear, "right")
|
||||
set:SetPoint("right", clear, "right", 180, 0)
|
||||
set:SetBackdrop(button_backdrop)
|
||||
set:SetBackdropColor(0, 0, 0, 0.5)
|
||||
set:SetHook("OnEnter", set_onenter)
|
||||
set:SetHook("OnLeave", set_onleave)
|
||||
|
||||
--set:InstallCustomTexture (nil, nil, nil, nil, true)
|
||||
set:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
local bg_texture = DF:CreateImage(set, [[Interface\AddOns\Details\images\bar_skyline]], 135, 30, "background")
|
||||
bg_texture:SetAllPoints()
|
||||
set.bg = bg_texture
|
||||
|
||||
local icon = DF:CreateImage(set, nil, 16, 16, nil, nil, "icon")
|
||||
icon:SetPoint("left", clear, "right", 4, 0)
|
||||
|
||||
local label = DF:CreateLabel(set, "")
|
||||
label:SetPoint("left", icon, "right", 2, 0)
|
||||
|
||||
table.insert(panel.blocks, {icon = icon, label = label, bg = set.bg, button = set})
|
||||
end
|
||||
|
||||
local normal_coords = {0, 1, 0, 1}
|
||||
local unknown_coords = {157/512, 206/512, 39/512, 89/512}
|
||||
|
||||
function panel:Refresh()
|
||||
local bookmarks = Details.switch.table
|
||||
|
||||
for i = 1, 40 do
|
||||
local bookmark = bookmarks [i]
|
||||
local this_block = panel.blocks [i]
|
||||
if (bookmark and bookmark.atributo and bookmark.sub_atributo) then
|
||||
if (bookmark.atributo == 5) then --custom
|
||||
local CustomObject = Details.custom [bookmark.sub_atributo]
|
||||
if (not CustomObject) then --ele j� foi deletado
|
||||
this_block.label.text = "-- x -- x --"
|
||||
this_block.icon.texture = "Interface\\ICONS\\Ability_DualWield"
|
||||
this_block.icon.texcoord = normal_coords
|
||||
this_block.bg:SetVertexColor(.4, .1, .1, .12)
|
||||
else
|
||||
this_block.label.text = CustomObject.name
|
||||
this_block.icon.texture = CustomObject.icon
|
||||
this_block.icon.texcoord = normal_coords
|
||||
this_block.bg:SetVertexColor(.4, .4, .4, .6)
|
||||
end
|
||||
else
|
||||
bookmark.atributo = bookmark.atributo or 1
|
||||
bookmark.sub_atributo = bookmark.sub_atributo or 1
|
||||
this_block.label.text = Details.sub_atributos [bookmark.atributo] and Details.sub_atributos [bookmark.atributo].lista [bookmark.sub_atributo]
|
||||
this_block.icon.texture = Details.sub_atributos [bookmark.atributo] and Details.sub_atributos [bookmark.atributo].icones [bookmark.sub_atributo] [1]
|
||||
this_block.icon.texcoord = Details.sub_atributos [bookmark.atributo] and Details.sub_atributos [bookmark.atributo].icones [bookmark.sub_atributo] [2]
|
||||
this_block.bg:SetVertexColor(.4, .4, .4, .6)
|
||||
end
|
||||
|
||||
this_block.button:SetAlpha(1)
|
||||
else
|
||||
this_block.label.text = "-- x -- x --"
|
||||
this_block.icon.texture = [[Interface\AddOns\Details\images\icons]]
|
||||
this_block.icon.texcoord = unknown_coords
|
||||
this_block.bg:SetVertexColor(.1, .1, .1, .12)
|
||||
this_block.button:SetAlpha(0.3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local bookmarkFrame = _G.DetailsBookmarkManager
|
||||
bookmarkFrame:Show()
|
||||
bookmarkFrame:Refresh()
|
||||
|
||||
local optionsFrame = _G.DetailsOptionsWindow
|
||||
if (optionsFrame) then
|
||||
--parent is the plugin container
|
||||
local currentOptionsScale = optionsFrame:GetParent():GetScale()
|
||||
bookmarkFrame:SetScale(currentOptionsScale)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,598 @@
|
||||
|
||||
local addonName, Details222 = ...
|
||||
local breakdownWindow = Details.BreakdownWindow
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local unpack = unpack
|
||||
local GetTime = GetTime
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local _GetSpellInfo = Details.GetSpellInfo
|
||||
local GameTooltip = GameTooltip
|
||||
local DF = DetailsFramework
|
||||
local tinsert = table.insert
|
||||
|
||||
local damageClass = Details.atributo_damage
|
||||
|
||||
local spellsTab = DetailsSpellBreakdownTab
|
||||
local headerContainerType = spellsTab.headerContainerType
|
||||
|
||||
local CONST_BAR_HEIGHT = 20
|
||||
local CONST_SPELLSCROLL_LINEHEIGHT = 20
|
||||
local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]]
|
||||
local CONST_SPELLBLOCK_DEFAULT_COLOR = {.4, .4, .4, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_COLOR = {.9, .8, 0, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_SIZE = 11
|
||||
|
||||
---onEnter function for the generic bars, set the alpha of the bar to one
|
||||
---@param self breakdowngenericbar
|
||||
local onEnterGenericBar = function(self) --~onenter ~genericbaronenter
|
||||
self:SetAlpha(1)
|
||||
|
||||
if (self.bIsFromLeftScroll) then
|
||||
---@type instance
|
||||
local instanceObject = spellsTab.GetInstance()
|
||||
local mainAttribute, subAttribute = instanceObject:GetDisplay()
|
||||
|
||||
---@type actordamage
|
||||
local currentActor = spellsTab.GetActor()
|
||||
|
||||
---@type combat
|
||||
local currentCombat = instanceObject:GetCombat()
|
||||
|
||||
---@type actorcontainer
|
||||
local actorContainer = currentCombat:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
|
||||
|
||||
if (mainAttribute == DETAILS_ATTRIBUTE_DAMAGE) then
|
||||
if (subAttribute == DETAILS_SUBATTRIBUTE_DAMAGETAKEN) then
|
||||
local aggressorActor = actorContainer:GetActor(self.actorName)
|
||||
---@type {topValue: number, data: {key1: spellid, key2: number, key3: actorname}[]}
|
||||
local spellList = damageClass.BuildDamageTakenSpellListFromAgressor(currentActor, aggressorActor)
|
||||
spellsTab.GenericScrollFrameRight:RefreshMe(spellList)
|
||||
|
||||
elseif (subAttribute == DETAILS_SUBATTRIBUTE_FRIENDLYFIRE) then
|
||||
--currentActor is the player which inflicted the damage to other players
|
||||
--self.actorName is the name of the actor in the hovered bar
|
||||
local spellList = damageClass.BuildFriendlySpellListFromAgressor(currentActor, self.actorName)
|
||||
spellsTab.GenericScrollFrameRight:RefreshMe(spellList)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--when hovered over, it need to detect which data is shown and call a function within a class to generate the data to show in the right scroll
|
||||
end
|
||||
|
||||
--onLeave function for the generic bars, set the alpha of the bar to 0.9
|
||||
---@param self breakdowngenericbar
|
||||
local onLeaveGenericBar = function(self) --~onleave ~genericbaronleave
|
||||
self:SetAlpha(0.9)
|
||||
end
|
||||
|
||||
---get a generic bar from the scroll box, if it doesn't exist, return nil
|
||||
---@param scrollFrame table
|
||||
---@param lineIndex number
|
||||
---@return breakdownphasebar
|
||||
local getGenericBar = function(scrollFrame, lineIndex)
|
||||
---@type breakdowngenericbar
|
||||
local genericBar = scrollFrame:GetLine(lineIndex)
|
||||
|
||||
--reset header alignment
|
||||
genericBar:ResetFramesToHeaderAlignment()
|
||||
|
||||
--reset columns, hiding them
|
||||
genericBar.Icon:Hide()
|
||||
for inLineIndex = 1, #genericBar.InLineTexts do
|
||||
genericBar.InLineTexts[inLineIndex]:SetText("")
|
||||
end
|
||||
|
||||
return genericBar
|
||||
end
|
||||
|
||||
---@param scrollFrame table
|
||||
---@param scrollData table
|
||||
---@param offset number
|
||||
---@param totalLines number
|
||||
local refreshGenericRightScrollFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshgeneric ~refreshfunc ~refresh ~refreshg ~updategenericbar
|
||||
local lineIndex = 1
|
||||
local combatTime = scrollData.combatTime
|
||||
local totalValue = scrollData.totalValue
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local spellData = scrollData[index]
|
||||
|
||||
if (spellData) then
|
||||
local spellId = spellData.spellId
|
||||
local spellTotal = spellData.total
|
||||
local petName = spellData.petName
|
||||
local spellSchool = spellData.spellScholl
|
||||
|
||||
local spellName, _, spellIcon = _GetSpellInfo(spellId)
|
||||
|
||||
--get a bar from the second generic scroll frame
|
||||
local genericBar = getGenericBar(scrollFrame, i)
|
||||
genericBar.statusBar:SetValue(spellTotal / scrollFrame.topValue * 100)
|
||||
|
||||
local r, g, b = Details:GetSpellSchoolColor(spellSchool)
|
||||
genericBar.statusBar:SetStatusBarColor(r, g, b, 1)
|
||||
|
||||
---@type number
|
||||
local textIndex = 1
|
||||
|
||||
if (scrollData.headersAllowed.icon) then
|
||||
---@type texturetable
|
||||
genericBar.Icon:Show()
|
||||
genericBar.Icon:SetTexture(spellIcon)
|
||||
genericBar.Icon:SetTexCoord(.1, .9, .1, .9)
|
||||
genericBar.Icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
genericBar:AddFrameToHeaderAlignment(genericBar.Icon)
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.rank) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(index)
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.name) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
if (petName ~= "") then
|
||||
--remove the owner name from the pet name
|
||||
petName = petName:gsub((" <.*"), "")
|
||||
spellName = spellName .. " (" .. petName .. ")"
|
||||
end
|
||||
fontString:SetText(spellName)
|
||||
textIndex = textIndex + 1
|
||||
genericBar.actorName = spellName
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.amount) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(Details:Format(spellTotal))
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.persecond) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(Details:Format(spellTotal / combatTime))
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.percent) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(string.format("%.1f", spellTotal / totalValue * 100) .. "%")
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
genericBar:Show()
|
||||
|
||||
genericBar:AlignWithHeader(scrollFrame.Header, "left")
|
||||
|
||||
lineIndex = lineIndex + 1
|
||||
if (lineIndex > totalLines) then
|
||||
break
|
||||
end
|
||||
|
||||
--set the amount
|
||||
--genericBar.InLineTexts[2]:SetText(Details:ToK(spellTotal))
|
||||
|
||||
--set the amount percent
|
||||
--genericBar.InLineTexts[3]:SetText(Details:ToK(spellTotal / totalValue * 100))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param scrollFrame table
|
||||
---@param scrollData table
|
||||
---@param offset number
|
||||
---@param totalLines number
|
||||
local refreshGenericLeftScrollFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshgeneric ~refreshfunc ~refresh ~refreshg ~updategenericbar
|
||||
local lineIndex = 1
|
||||
local combatTime = scrollData.combatTime
|
||||
local totalValue = scrollData.totalValue
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local dataTable = scrollData[index]
|
||||
|
||||
if (dataTable) then
|
||||
local genericBar = getGenericBar(scrollFrame, lineIndex)
|
||||
genericBar.statusBar:SetValue(dataTable.total / scrollFrame.topValue * 100)
|
||||
|
||||
local spellSchool = dataTable.spellScholl
|
||||
local className = dataTable.class
|
||||
|
||||
if (spellSchool) then
|
||||
local r, g, b = Details:GetSpellSchoolColor(spellSchool)
|
||||
genericBar.statusBar:SetStatusBarColor(r, g, b, 1)
|
||||
|
||||
else
|
||||
local red, green, blue = Details:GetClassColor(className)
|
||||
genericBar.statusBar:SetStatusBarColor(red, green, blue, 1)
|
||||
end
|
||||
|
||||
---@type number
|
||||
local textIndex = 1
|
||||
|
||||
if (scrollData.headersAllowed.icon) then
|
||||
---@type texturetable
|
||||
local dataIcon = dataTable.icon
|
||||
genericBar.Icon:Show()
|
||||
genericBar.Icon:SetTexture(dataIcon.texture)
|
||||
genericBar.Icon:SetTexCoord(dataIcon.coords.left, dataIcon.coords.right, dataIcon.coords.top, dataIcon.coords.bottom)
|
||||
genericBar.Icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
genericBar:AddFrameToHeaderAlignment(genericBar.Icon)
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.rank) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(index)
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.name) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
local nameWithoutRealm = DF:RemoveRealmName(dataTable.name)
|
||||
fontString:SetText(nameWithoutRealm or dataTable.name)
|
||||
textIndex = textIndex + 1
|
||||
genericBar.actorName = dataTable.name
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.amount) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(Details:Format(dataTable.total))
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.persecond) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(Details:Format(dataTable.total / combatTime))
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
if (scrollData.headersAllowed.percent) then
|
||||
---@type fontstring
|
||||
local fontString = genericBar.InLineTexts[textIndex]
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
fontString:SetText(string.format("%.1f", dataTable.total / totalValue * 100) .. "%")
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
|
||||
genericBar:AlignWithHeader(scrollFrame.Header, "left")
|
||||
|
||||
lineIndex = lineIndex + 1
|
||||
if (lineIndex > totalLines) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---create a genericbar within the generic scroll
|
||||
---@param self breakdowngenericscrollframe
|
||||
---@param index number
|
||||
---@return breakdowngenericbar
|
||||
local createGenericBar = function(self, index) --~create ~generic ~creategeneric ~genericbar
|
||||
---@type breakdowngenericbar
|
||||
local genericBar = CreateFrame("button", self:GetName() .. "GenericBarButton" .. index, self)
|
||||
genericBar.index = index
|
||||
|
||||
--size and positioning
|
||||
genericBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15
|
||||
genericBar:SetPoint("topleft", self, "topleft", 0, y)
|
||||
genericBar:SetPoint("topright", self, "topright", 0, y)
|
||||
|
||||
genericBar:EnableMouse(true)
|
||||
|
||||
genericBar:SetAlpha(0.9)
|
||||
genericBar:SetFrameStrata("HIGH")
|
||||
genericBar:SetScript("OnEnter", onEnterGenericBar)
|
||||
genericBar:SetScript("OnLeave", onLeaveGenericBar)
|
||||
|
||||
DF:Mixin(genericBar, DF.HeaderFunctions)
|
||||
|
||||
---@type breakdownspellbarstatusbar
|
||||
local statusBar = CreateFrame("StatusBar", "$parentStatusBar", genericBar)
|
||||
statusBar:SetAllPoints()
|
||||
statusBar:SetAlpha(0.8)
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetValue(50)
|
||||
statusBar:EnableMouse(false)
|
||||
statusBar:SetFrameLevel(genericBar:GetFrameLevel() - 1)
|
||||
genericBar.statusBar = statusBar
|
||||
|
||||
---@type texture this is the statusbar texture
|
||||
local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork")
|
||||
statusBarTexture:SetTexture(SharedMedia:Fetch("statusbar", Details.breakdown_general.bar_texture))
|
||||
statusBar:SetStatusBarTexture(statusBarTexture)
|
||||
statusBar:SetStatusBarColor(1, 1, 1, 1)
|
||||
|
||||
---@type texture shown when the mouse hoverover this bar
|
||||
local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight")
|
||||
hightlightTexture:SetTexture(1, 1, 1, 0.2)
|
||||
hightlightTexture:SetAllPoints()
|
||||
statusBar.highlightTexture = hightlightTexture
|
||||
|
||||
---@type texture background texture
|
||||
local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border")
|
||||
backgroundTexture:SetAllPoints()
|
||||
backgroundTexture:SetTexture(.05, .05, .05)
|
||||
backgroundTexture:SetAlpha(1)
|
||||
statusBar.backgroundTexture = backgroundTexture
|
||||
|
||||
--create an icon
|
||||
---@type texture
|
||||
local icon = statusBar:CreateTexture("$parentTexture", "overlay")
|
||||
icon:SetPoint("left", statusBar, "left", 0, 0)
|
||||
icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
icon:SetTexCoord(.1, .9, .1, .9)
|
||||
genericBar.Icon = icon
|
||||
|
||||
genericBar:AddFrameToHeaderAlignment(icon)
|
||||
|
||||
genericBar.InLineTexts = {}
|
||||
|
||||
for i = 1, 5 do
|
||||
---@type fontstring
|
||||
local fontString = genericBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall")
|
||||
fontString:SetJustifyH("left")
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
fontString:SetNonSpaceWrap(true)
|
||||
fontString:SetWordWrap(false)
|
||||
genericBar["lineText" .. i] = fontString
|
||||
genericBar.InLineTexts[i] = fontString
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
genericBar:AddFrameToHeaderAlignment(fontString)
|
||||
end
|
||||
|
||||
genericBar:AlignWithHeader(self.Header, "left")
|
||||
|
||||
return genericBar
|
||||
end
|
||||
|
||||
---create two generic containers, these containers hold bars that can show any type of data
|
||||
---an example is damage taken in the left container and the spells which caused the damage in the right container
|
||||
---@param tabFrame tabframe
|
||||
---@return breakdowngenericscrollframe, breakdowngenericscrollframe
|
||||
function spellsTab.CreateGenericContainers(tabFrame) --~create ~generic ~creategenericcontainer ~creategenericscroll ~creategeneric
|
||||
local defaultAmountOfLines = 50
|
||||
|
||||
--create a container for the scrollframe
|
||||
local optionsLeftScroll = {
|
||||
width = Details.breakdown_spell_tab.genericcontainer_width,
|
||||
height = Details.breakdown_spell_tab.genericcontainer_height,
|
||||
is_locked = Details.breakdown_spell_tab.genericcontainer_islocked,
|
||||
can_move = false,
|
||||
can_move_children = false,
|
||||
use_top_resizer = true,
|
||||
use_right_resizer = true,
|
||||
use_bottom_resizer = true,
|
||||
use_left_resizer = true,
|
||||
}
|
||||
|
||||
--create a container for the scrollframe
|
||||
local optionsRightScroll = {
|
||||
width = Details.breakdown_spell_tab.genericcontainer_right_width,
|
||||
height = Details.breakdown_spell_tab.genericcontainer_right_height,
|
||||
is_locked = Details.breakdown_spell_tab.genericcontainer_islocked,
|
||||
can_move = false,
|
||||
can_move_children = false,
|
||||
use_top_resizer = true,
|
||||
use_right_resizer = true,
|
||||
use_bottom_resizer = true,
|
||||
use_left_resizer = true,
|
||||
}
|
||||
|
||||
---@type df_framecontainer
|
||||
local leftContainer = DF:CreateFrameContainer(tabFrame, optionsLeftScroll, tabFrame:GetName() .. "GenericScrollContainerLeft")
|
||||
leftContainer:SetPoint("topleft", tabFrame, "topleft", 0, 0)
|
||||
leftContainer:SetFrameLevel(tabFrame:GetFrameLevel()+1)
|
||||
spellsTab.GenericContainerFrameLeft = leftContainer
|
||||
|
||||
---@type df_framecontainer
|
||||
local rightContainer = DF:CreateFrameContainer(tabFrame, optionsRightScroll, tabFrame:GetName() .. "GenericScrollContainerRight")
|
||||
rightContainer:SetPoint("topleft", leftContainer, "topright", 30, 0)
|
||||
rightContainer:SetFrameLevel(tabFrame:GetFrameLevel()+1)
|
||||
spellsTab.GenericContainerFrameRight = rightContainer
|
||||
|
||||
--when a setting is changed in the container, it will call this function, it is registered below with SetSettingChangedCallback()
|
||||
local settingChangedCallbackFunction_Left = function(frameContainer, settingName, settingValue)
|
||||
if (frameContainer:IsShown()) then
|
||||
if (settingName == "height") then
|
||||
---@type number
|
||||
local currentHeight = frameContainer.ScrollFrame:GetHeight()
|
||||
Details.breakdown_spell_tab.genericcontainer_height = settingValue
|
||||
frameContainer.ScrollFrame:SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 2)
|
||||
|
||||
elseif (settingName == "width") then
|
||||
Details.breakdown_spell_tab.genericcontainer_width = settingValue
|
||||
|
||||
elseif (settingName == "is_locked") then
|
||||
Details.breakdown_spell_tab.genericcontainer_islocked = settingValue
|
||||
end
|
||||
end
|
||||
end
|
||||
leftContainer:SetSettingChangedCallback(settingChangedCallbackFunction_Left)
|
||||
|
||||
--when a setting is changed in the container, it will call this function, it is registered below with SetSettingChangedCallback()
|
||||
local settingChangedCallbackFunction_Right = function(frameContainer, settingName, settingValue)
|
||||
if (frameContainer:IsShown()) then
|
||||
if (settingName == "height") then
|
||||
---@type number
|
||||
local currentHeight = frameContainer.ScrollFrame:GetHeight()
|
||||
Details.breakdown_spell_tab.genericcontainer_right_height = settingValue
|
||||
frameContainer.ScrollFrame:SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 2)
|
||||
|
||||
elseif (settingName == "width") then
|
||||
Details.breakdown_spell_tab.genericcontainer_right_width = settingValue
|
||||
|
||||
elseif (settingName == "is_locked") then
|
||||
Details.breakdown_spell_tab.genericcontainer_islocked = settingValue
|
||||
end
|
||||
end
|
||||
end
|
||||
rightContainer:SetSettingChangedCallback(settingChangedCallbackFunction_Right)
|
||||
|
||||
--create the left scrollframe
|
||||
local genericScrollFrameLeft = DF:CreateScrollBox(leftContainer, "$parentGenericScrollLeft", refreshGenericLeftScrollFunc, {}, Details.breakdown_spell_tab.genericcontainer_width, Details.breakdown_spell_tab.genericcontainer_height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
DF:ReskinSlider(genericScrollFrameLeft)
|
||||
genericScrollFrameLeft:SetBackdrop({})
|
||||
genericScrollFrameLeft:SetAllPoints()
|
||||
leftContainer:RegisterChildForDrag(genericScrollFrameLeft)
|
||||
leftContainer.ScrollFrame = genericScrollFrameLeft
|
||||
genericScrollFrameLeft.DontHideChildrenOnPreRefresh = false
|
||||
tabFrame.GenericScrollFrameLeft = genericScrollFrameLeft
|
||||
spellsTab.GenericScrollFrameLeft = genericScrollFrameLeft
|
||||
|
||||
--create the right scrollframe
|
||||
local genericScrollFrameRight = DF:CreateScrollBox(rightContainer, "$parentGenericScrollRight", refreshGenericRightScrollFunc, {}, Details.breakdown_spell_tab.genericcontainer_right_width, Details.breakdown_spell_tab.genericcontainer_right_height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
DF:ReskinSlider(genericScrollFrameRight)
|
||||
genericScrollFrameRight:SetBackdrop({})
|
||||
genericScrollFrameRight:SetAllPoints()
|
||||
rightContainer:RegisterChildForDrag(genericScrollFrameRight)
|
||||
rightContainer.ScrollFrame = genericScrollFrameRight
|
||||
genericScrollFrameRight.DontHideChildrenOnPreRefresh = false
|
||||
tabFrame.GenericScrollFrameRight = genericScrollFrameRight
|
||||
spellsTab.GenericScrollFrameRight = genericScrollFrameRight
|
||||
|
||||
function genericScrollFrameLeft:RefreshMe(data) --~refreshme (generic) ~refreshg
|
||||
--get which column is currently selected and the sort order
|
||||
local columnIndex, order, key = genericScrollFrameLeft.Header:GetSelectedColumn()
|
||||
genericScrollFrameLeft.SortKey = key
|
||||
|
||||
---@type string
|
||||
local keyToSort = key
|
||||
|
||||
if (order == "DESC") then
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] > t2[keyToSort]
|
||||
end)
|
||||
genericScrollFrameLeft.topValue = data[1] and data[1][keyToSort] or 0.00001
|
||||
else
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] < t2[keyToSort]
|
||||
end)
|
||||
genericScrollFrameLeft.topValue = data[#data] and data[#data][keyToSort] or 0.00001
|
||||
end
|
||||
|
||||
genericScrollFrameLeft:SetData(data)
|
||||
genericScrollFrameLeft:Refresh()
|
||||
|
||||
--clear the right scrollframe
|
||||
genericScrollFrameRight:SetData({})
|
||||
genericScrollFrameRight:Refresh()
|
||||
end
|
||||
|
||||
function genericScrollFrameRight:RefreshMe(data) --~refreshme (generic) ~refreshg
|
||||
--get which column is currently selected and the sort order
|
||||
local columnIndex, order, key = genericScrollFrameRight.Header:GetSelectedColumn()
|
||||
genericScrollFrameRight.SortKey = key
|
||||
|
||||
---@type string
|
||||
local keyToSort = key
|
||||
|
||||
if (order == "DESC") then
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] > t2[keyToSort]
|
||||
end)
|
||||
genericScrollFrameRight.topValue = data[1] and data[1][keyToSort] or 0.00001
|
||||
else
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] < t2[keyToSort]
|
||||
end)
|
||||
genericScrollFrameRight.topValue = data[#data] and data[#data][keyToSort] or 0.00001
|
||||
end
|
||||
|
||||
genericScrollFrameRight:SetData(data)
|
||||
genericScrollFrameRight:Refresh()
|
||||
end
|
||||
|
||||
--~header
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
header_height = 14,
|
||||
|
||||
reziser_shown = true,
|
||||
reziser_width = 2,
|
||||
reziser_color = {.5, .5, .5, 0.7},
|
||||
reziser_max_width = 246,
|
||||
|
||||
header_click_callback = spellsTab.OnAnyColumnHeaderClickCallback,
|
||||
|
||||
header_backdrop_color = {0.1, 0.1, 0.1, 0.4},
|
||||
text_color = {1, 1, 1, 0.823},
|
||||
}
|
||||
|
||||
local headerOptionsRight = {
|
||||
padding = 2,
|
||||
header_height = 14,
|
||||
|
||||
reziser_shown = true,
|
||||
reziser_width = 2,
|
||||
reziser_color = {.5, .5, .5, 0.7},
|
||||
reziser_max_width = 210,
|
||||
|
||||
header_click_callback = spellsTab.OnAnyColumnHeaderClickCallback,
|
||||
|
||||
header_backdrop_color = {0.1, 0.1, 0.1, 0.4},
|
||||
text_color = {1, 1, 1, 0.823},
|
||||
}
|
||||
|
||||
---@type df_headerframe
|
||||
local headerLeft = DetailsFramework:CreateHeader(leftContainer, spellsTab.genericContainerLeftColumnData, headerOptions)
|
||||
headerLeft:SetPoint("topleft", genericScrollFrameLeft, "topleft", 0, 1)
|
||||
headerLeft:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged)
|
||||
genericScrollFrameLeft.Header = headerLeft
|
||||
|
||||
---@type df_headerframe
|
||||
local headerRight = DetailsFramework:CreateHeader(rightContainer, spellsTab.genericContainerRightColumnData, headerOptionsRight)
|
||||
headerRight:SetPoint("topleft", genericScrollFrameRight, "topleft", 0, 1)
|
||||
headerRight:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged)
|
||||
genericScrollFrameRight.Header = headerRight
|
||||
|
||||
--cache the type of these headers
|
||||
headerContainerType[headerLeft] = "generic_left"
|
||||
headerContainerType[headerRight] = "generic_right"
|
||||
|
||||
--create the scroll lines
|
||||
for i = 1, defaultAmountOfLines do
|
||||
local lineFrame = genericScrollFrameLeft:CreateLine(createGenericBar)
|
||||
lineFrame.bIsFromLeftScroll = true
|
||||
end
|
||||
|
||||
--create the scroll lines
|
||||
for i = 1, defaultAmountOfLines do
|
||||
local lineFrame = genericScrollFrameRight:CreateLine(createGenericBar)
|
||||
lineFrame:Hide()
|
||||
lineFrame.bIsFromRightScroll = true
|
||||
end
|
||||
|
||||
--need to create the second scroll frame to show the details about the spelltable/actor hovered over
|
||||
|
||||
return genericScrollFrameLeft, genericScrollFrameRight
|
||||
end
|
||||
@@ -0,0 +1,424 @@
|
||||
|
||||
local addonName, Details222 = ...
|
||||
local breakdownWindow = Details.BreakdownWindow
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local unpack = unpack
|
||||
local GetTime = GetTime
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink
|
||||
local GetSpellInfo = Details222.GetSpellInfo
|
||||
local _GetSpellInfo = Details.GetSpellInfo
|
||||
local GameTooltip = GameTooltip
|
||||
local DF = DetailsFramework
|
||||
local detailsFramework = DetailsFramework
|
||||
local tinsert = table.insert
|
||||
|
||||
local spellsTab = DetailsSpellBreakdownTab
|
||||
local headerContainerType = spellsTab.headerContainerType
|
||||
|
||||
local CONST_BAR_HEIGHT = 20
|
||||
local CONST_SPELLSCROLL_LINEHEIGHT = 20
|
||||
local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]]
|
||||
local CONST_SPELLBLOCK_DEFAULT_COLOR = {.4, .4, .4, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_COLOR = {.9, .8, 0, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_SIZE = 11
|
||||
|
||||
|
||||
---create a targetbar within the target scroll
|
||||
---@param self breakdownphasescrollframe
|
||||
---@param index number
|
||||
---@return breakdownphasebar
|
||||
function spellsTab.CreatePhaseBar(self, index) --~create ~createphase ~phasebar
|
||||
---@type breakdownphasebar
|
||||
local phaseBar = CreateFrame("button", self:GetName() .. "PhaseBarButton" .. index, self)
|
||||
phaseBar.index = index
|
||||
|
||||
--size and positioning
|
||||
phaseBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15
|
||||
phaseBar:SetPoint("topleft", self, "topleft", 1, y)
|
||||
phaseBar:SetPoint("topright", self, "topright", -1, y)
|
||||
|
||||
phaseBar:EnableMouse(true)
|
||||
|
||||
phaseBar:SetAlpha(0.823)
|
||||
phaseBar:SetFrameStrata("HIGH")
|
||||
phaseBar:SetScript("OnEnter", nil)
|
||||
phaseBar:SetScript("OnLeave", nil)
|
||||
|
||||
DF:Mixin(phaseBar, DF.HeaderFunctions)
|
||||
|
||||
---@type breakdownspellbarstatusbar
|
||||
local statusBar = CreateFrame("StatusBar", "$parentStatusBar", phaseBar)
|
||||
statusBar:SetAllPoints()
|
||||
statusBar:SetAlpha(0.5)
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetValue(50)
|
||||
statusBar:EnableMouse(false)
|
||||
statusBar:SetFrameLevel(phaseBar:GetFrameLevel() - 1)
|
||||
phaseBar.statusBar = statusBar
|
||||
|
||||
---@type texture this is the statusbar texture
|
||||
local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork")
|
||||
statusBarTexture:SetTexture(SharedMedia:Fetch("statusbar", Details.breakdown_general.bar_texture))
|
||||
statusBar:SetStatusBarTexture(statusBarTexture)
|
||||
statusBar:SetStatusBarColor(1, 1, 1, 1)
|
||||
|
||||
---@type texture shown when the mouse hoverover this bar
|
||||
local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight")
|
||||
hightlightTexture:SetTexture(1, 1, 1, 0.2)
|
||||
hightlightTexture:SetAllPoints()
|
||||
statusBar.highlightTexture = hightlightTexture
|
||||
|
||||
---@type texture background texture
|
||||
local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border")
|
||||
backgroundTexture:SetAllPoints()
|
||||
backgroundTexture:SetTexture(.05, .05, .05)
|
||||
backgroundTexture:SetAlpha(1)
|
||||
statusBar.backgroundTexture = backgroundTexture
|
||||
|
||||
--create an icon
|
||||
---@type texture
|
||||
local icon = statusBar:CreateTexture("$parentTexture", "overlay")
|
||||
icon:SetPoint("left", statusBar, "left", 0, 0)
|
||||
icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
icon:SetTexCoord(.1, .9, .1, .9)
|
||||
phaseBar.Icon = icon
|
||||
|
||||
phaseBar:AddFrameToHeaderAlignment(icon)
|
||||
|
||||
phaseBar.InLineTexts = {}
|
||||
|
||||
for i = 1, 5 do
|
||||
---@type fontstring
|
||||
local fontString = phaseBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall")
|
||||
fontString:SetJustifyH("left")
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
fontString:SetNonSpaceWrap(true)
|
||||
fontString:SetWordWrap(false)
|
||||
phaseBar["lineText" .. i] = fontString
|
||||
phaseBar.InLineTexts[i] = fontString
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
phaseBar:AddFrameToHeaderAlignment(fontString)
|
||||
end
|
||||
|
||||
phaseBar:AlignWithHeader(self.Header, "left")
|
||||
|
||||
return phaseBar
|
||||
end
|
||||
|
||||
---get a spell bar from the scroll box, if it doesn't exist, return nil
|
||||
---@param scrollFrame table
|
||||
---@param lineIndex number
|
||||
---@return breakdownphasebar
|
||||
local getPhaseBar = function(scrollFrame, lineIndex)
|
||||
---@type breakdownphasebar
|
||||
local phaseBar = scrollFrame:GetLine(lineIndex)
|
||||
|
||||
--reset header alignment
|
||||
phaseBar:ResetFramesToHeaderAlignment()
|
||||
|
||||
spellsTab.UpdateBarSettings(phaseBar)
|
||||
|
||||
--reset columns, hiding them
|
||||
phaseBar.Icon:Hide()
|
||||
for inLineIndex = 1, #phaseBar.InLineTexts do
|
||||
phaseBar.InLineTexts[inLineIndex]:SetText("")
|
||||
end
|
||||
|
||||
return phaseBar
|
||||
end
|
||||
|
||||
---@param scrollFrame table
|
||||
---@param scrollData table
|
||||
---@param offset number
|
||||
---@param totalLines number
|
||||
local refreshPhaseFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshphases ~refreshfunc ~refresh ~refreshp ~updatephasebar
|
||||
local lineIndex = 1
|
||||
local formatFunc = Details:GetCurrentToKFunction()
|
||||
local phaseElapsedTime = scrollData.phaseElapsed
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local dataTable = scrollData[index]
|
||||
|
||||
if (dataTable) then
|
||||
local phaseBar = getPhaseBar(scrollFrame, lineIndex)
|
||||
|
||||
phaseBar.statusBar:SetValue(100)
|
||||
|
||||
local totalDone = dataTable.amountDone
|
||||
local phaseName = dataTable.phaseName
|
||||
local phaseNameFormatted = "Phase: " .. phaseName
|
||||
local amountDoneFormatted = formatFunc(nil, totalDone)
|
||||
local positionWithInPhase = math.floor(dataTable.positionWithInPhase)
|
||||
local percentDone = string.format("%.1f", dataTable.percentDone)
|
||||
|
||||
local elapsedTime = phaseElapsedTime[phaseName]
|
||||
local phaseDps = formatFunc(nil, totalDone / elapsedTime)
|
||||
|
||||
phaseBar.Icon:Show()
|
||||
phaseBar.Icon:SetTexture([[Interface\Garrison\orderhall-missions-mechanic9]])
|
||||
phaseBar.Icon:SetTexCoord(11/64, 53/64, 11/64, 53/64)
|
||||
phaseBar.Icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
phaseBar:AddFrameToHeaderAlignment(phaseBar.Icon)
|
||||
|
||||
for inLineIndex = 1, #phaseBar.InLineTexts do
|
||||
phaseBar.InLineTexts[inLineIndex]:SetText("")
|
||||
end
|
||||
|
||||
local text1 = phaseBar.InLineTexts[1]
|
||||
phaseBar:AddFrameToHeaderAlignment(text1)
|
||||
text1:SetText(phaseNameFormatted)
|
||||
|
||||
local text2 = phaseBar.InLineTexts[2]
|
||||
phaseBar:AddFrameToHeaderAlignment(text2)
|
||||
text2:SetText("#" .. positionWithInPhase)
|
||||
|
||||
local text3 = phaseBar.InLineTexts[3]
|
||||
phaseBar:AddFrameToHeaderAlignment(text3)
|
||||
text3:SetText(amountDoneFormatted)
|
||||
|
||||
local text4 = phaseBar.InLineTexts[4]
|
||||
phaseBar:AddFrameToHeaderAlignment(text4)
|
||||
text4:SetText(phaseDps)
|
||||
|
||||
local text5 = phaseBar.InLineTexts[5]
|
||||
phaseBar:AddFrameToHeaderAlignment(text5)
|
||||
text5:SetText(percentDone .. "%")
|
||||
|
||||
lineIndex = lineIndex + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---create a container to show value per phase
|
||||
---@param tabFrame tabframe
|
||||
---@return breakdownphasescrollframe
|
||||
function spellsTab.CreatePhasesContainer(tabFrame) --~phase ~createphasecontainer ~createphasescroll
|
||||
---@type width
|
||||
local width = Details.breakdown_spell_tab.phasecontainer_width
|
||||
---@type height
|
||||
local height = Details.breakdown_spell_tab.phasecontainer_height
|
||||
|
||||
local defaultAmountOfLines = 10
|
||||
|
||||
--create a container for the scrollframe
|
||||
local options = {
|
||||
width = Details.breakdown_spell_tab.phasecontainer_width,
|
||||
height = Details.breakdown_spell_tab.phasecontainer_height,
|
||||
is_locked = Details.breakdown_spell_tab.phasecontainer_islocked,
|
||||
can_move = false,
|
||||
can_move_children = false,
|
||||
use_top_resizer = true,
|
||||
use_right_resizer = true,
|
||||
use_left_resizer = true,
|
||||
use_bottom_resizer = true,
|
||||
}
|
||||
|
||||
---@type df_framecontainer
|
||||
local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "PhaseScrollContainer")
|
||||
container:SetPoint("topleft", spellsTab.GetTargetScrollContainer(), "topright", 26, 0)
|
||||
container:SetFrameLevel(tabFrame:GetFrameLevel() + 10)
|
||||
spellsTab.PhaseContainerFrame = container
|
||||
|
||||
local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue)
|
||||
if (frameContainer:IsShown()) then
|
||||
if (settingName == "height") then
|
||||
---@type number
|
||||
local currentHeight = spellsTab.GetPhaseScrollFrame():GetHeight()
|
||||
Details.breakdown_spell_tab.phasecontainer_height = settingValue
|
||||
local lineAmount = math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
spellsTab.GetPhaseScrollFrame():SetNumFramesShown(lineAmount)
|
||||
|
||||
elseif (settingName == "width") then
|
||||
Details.breakdown_spell_tab.phasecontainer_width = settingValue
|
||||
|
||||
elseif (settingName == "is_locked") then
|
||||
Details.breakdown_spell_tab.phasecontainer_islocked = settingValue
|
||||
end
|
||||
end
|
||||
end
|
||||
container:SetSettingChangedCallback(settingChangedCallbackFunction)
|
||||
|
||||
---@type breakdownphasescrollframe not sure is this is correct
|
||||
local phaseScrollFrame = DF:CreateScrollBox(container, "$parentPhaseScroll", refreshPhaseFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
DF:ReskinSlider(phaseScrollFrame)
|
||||
|
||||
---@param self breakdownphasescrollframe
|
||||
---@return breakdownreporttable
|
||||
function phaseScrollFrame:GetReportData()
|
||||
local instance = spellsTab.GetInstance()
|
||||
local data = phaseScrollFrame:GetData()
|
||||
local formatFunc = Details:GetCurrentToKFunction()
|
||||
local actorObject = spellsTab.GetActor()
|
||||
local displayId, subDisplayId = instance:GetDisplay()
|
||||
local subDisplayName = Details:GetSubAttributeName(displayId, subDisplayId)
|
||||
local combatName = instance:GetCombat():GetCombatName()
|
||||
|
||||
---@type breakdownreporttable
|
||||
local reportData = {
|
||||
title = "Phases for " .. detailsFramework:RemoveRealmName(actorObject:Name()) .. " | " .. subDisplayName .. " | " .. combatName
|
||||
}
|
||||
|
||||
for i = 1, #data do
|
||||
local dataTable = data[i]
|
||||
reportData[#reportData+1] = {
|
||||
name = "Phase:" .. dataTable.phaseName,
|
||||
amount = formatFunc(nil, dataTable.amountDone),
|
||||
percent = string.format("%.1f", dataTable.percentDone) .. "%",
|
||||
}
|
||||
end
|
||||
|
||||
return reportData
|
||||
end
|
||||
|
||||
phaseScrollFrame:SetBackdrop({})
|
||||
phaseScrollFrame:SetAllPoints()
|
||||
|
||||
container:RegisterChildForDrag(phaseScrollFrame)
|
||||
|
||||
phaseScrollFrame.DontHideChildrenOnPreRefresh = false
|
||||
tabFrame.PhaseScrollFrame = phaseScrollFrame
|
||||
spellsTab.PhaseScrollFrame = phaseScrollFrame
|
||||
|
||||
spellsTab.ApplyStandardBackdrop(container, phaseScrollFrame)
|
||||
|
||||
function phaseScrollFrame:RefreshMe() --~refreshme (phases) ~refreshmep
|
||||
--get the value of the top 1 ranking spell
|
||||
---@type actor
|
||||
local actorObject = spellsTab.GetActor()
|
||||
---@type combat
|
||||
local combatObject = spellsTab.GetCombat()
|
||||
local actorName = actorObject:Name()
|
||||
---@type instance
|
||||
local instanceObject = spellsTab.GetInstance()
|
||||
|
||||
local mainAttribute = instanceObject:GetDisplay()
|
||||
|
||||
local data = {
|
||||
--playerObject = playerObject,
|
||||
--attribute = attribute,
|
||||
--combatObject = combatObject,
|
||||
combatTime = combatObject:GetCombatTime(),
|
||||
}
|
||||
|
||||
local playerPhases = {}
|
||||
local totalDamage = 0
|
||||
local phaseElapsed = {}
|
||||
|
||||
local phasesInfo = combatObject:GetPhases()
|
||||
|
||||
if (not phasesInfo) then
|
||||
spellsTab.PhaseContainerFrame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if (#phasesInfo == 1) then
|
||||
--if there's only one phase, then there's no need to show phases
|
||||
spellsTab.PhaseContainerFrame:Hide()
|
||||
return
|
||||
else
|
||||
spellsTab.PhaseContainerFrame:Show()
|
||||
end
|
||||
|
||||
if (#phasesInfo >= 1) then
|
||||
--get phase elapsed time
|
||||
for i = 1, #phasesInfo do
|
||||
local thisPhase = phasesInfo[i]
|
||||
local phaseName = thisPhase[1]
|
||||
local startTime = thisPhase[2]
|
||||
|
||||
local nextPhase = phasesInfo[i + 1]
|
||||
if (nextPhase) then
|
||||
--if there's a next phase, use it's start time as end time to calcule elapsed time
|
||||
local endTime = nextPhase[2]
|
||||
local elapsedTime = endTime - startTime
|
||||
phaseElapsed[phaseName] = (phaseElapsed[phaseName] or 0) + elapsedTime
|
||||
else
|
||||
--if there's no next phase, use the combat end time as end time to calcule elapsed time
|
||||
local endTime = combatObject:GetCombatTime()
|
||||
local elapsedTime = endTime - startTime
|
||||
phaseElapsed[phaseName] = (phaseElapsed[phaseName] or 0) + elapsedTime
|
||||
end
|
||||
end
|
||||
|
||||
--get damage info
|
||||
local dataTable = mainAttribute == 1 and phasesInfo.damage or phasesInfo.heal
|
||||
for phaseName, playersTable in pairs(dataTable) do --each phase
|
||||
local allPlayers = {} --all players for this phase
|
||||
for playerName, amount in pairs(playersTable) do
|
||||
tinsert(allPlayers, {playerName, amount})
|
||||
totalDamage = totalDamage + amount
|
||||
end
|
||||
table.sort(allPlayers, function(a, b)
|
||||
return a[2] > b[2]
|
||||
end)
|
||||
|
||||
local myRank = 0
|
||||
for i = 1, #allPlayers do
|
||||
if (allPlayers[i][1] == actorName) then
|
||||
myRank = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
tinsert(playerPhases, {phaseName, playersTable[actorName] or 0, myRank, (playersTable[actorName] or 0) / totalDamage * 100})
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(playerPhases, function(a, b) return a[1] < b[1] end)
|
||||
|
||||
for i = 1, #playerPhases do
|
||||
data[#data+1] = {
|
||||
phaseName = playerPhases[i][1],
|
||||
amountDone = playerPhases[i][2],
|
||||
positionWithInPhase = playerPhases[i][3],
|
||||
percentDone = playerPhases[i][4],
|
||||
}
|
||||
end
|
||||
|
||||
data.totalDamage = totalDamage
|
||||
data.phaseElapsed = phaseElapsed
|
||||
|
||||
phaseScrollFrame:SetData(data)
|
||||
phaseScrollFrame:Refresh()
|
||||
end
|
||||
|
||||
--~header
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
header_height = 14,
|
||||
|
||||
reziser_shown = true,
|
||||
reziser_width = 2,
|
||||
reziser_color = {.5, .5, .5, 0.7},
|
||||
reziser_max_width = 246,
|
||||
|
||||
header_click_callback = spellsTab.OnAnyColumnHeaderClickCallback,
|
||||
|
||||
header_backdrop_color = {0.1, 0.1, 0.1, 0.4},
|
||||
text_color = {1, 1, 1, 0.823},
|
||||
}
|
||||
|
||||
---@type df_headerframe
|
||||
local header = DetailsFramework:CreateHeader(container, spellsTab.phaseContainerColumnData, headerOptions)
|
||||
phaseScrollFrame.Header = header
|
||||
phaseScrollFrame.Header:SetPoint("topleft", phaseScrollFrame, "topleft", 0, 1)
|
||||
phaseScrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged)
|
||||
|
||||
--cache the type of this container
|
||||
headerContainerType[phaseScrollFrame.Header] = "phases"
|
||||
|
||||
--create the scroll lines
|
||||
for i = 1, defaultAmountOfLines do
|
||||
phaseScrollFrame:CreateLine(spellsTab.CreatePhaseBar)
|
||||
end
|
||||
|
||||
tabFrame.phases = container:CreateFontString(nil, "overlay", "QuestFont_Large")
|
||||
tabFrame.phases:SetPoint("bottomleft", container, "topleft", 2, 2)
|
||||
tabFrame.phases:SetText("Phases:") --localize-me
|
||||
|
||||
return phaseScrollFrame
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,608 @@
|
||||
|
||||
local addonName, Details222 = ...
|
||||
local breakdownWindow = Details.BreakdownWindow
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local unpack = unpack
|
||||
local GetTime = GetTime
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
|
||||
local GetSpellInfo = Details222.GetSpellInfo
|
||||
local _GetSpellInfo = Details.GetSpellInfo
|
||||
local GameTooltip = GameTooltip
|
||||
local IsShiftKeyDown = IsShiftKeyDown
|
||||
local tinsert = table.insert
|
||||
|
||||
---@type detailsframework
|
||||
local DF = DetailsFramework
|
||||
---@type detailsframework
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
local spellsTab = DetailsSpellBreakdownTab
|
||||
local headerContainerType = spellsTab.headerContainerType
|
||||
|
||||
local CONST_BAR_HEIGHT = 20
|
||||
local CONST_SPELLSCROLL_LINEHEIGHT = 20
|
||||
local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]]
|
||||
local CONST_SPELLBLOCK_DEFAULT_COLOR = {.4, .4, .4, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_COLOR = {.9, .8, 0, 1}
|
||||
local CONST_SPELLBLOCK_HEADERTEXT_SIZE = 11
|
||||
|
||||
---get a target bar from the scroll box, if it doesn't exist, return nil
|
||||
---@param scrollFrame table
|
||||
---@param lineIndex number
|
||||
---@return breakdowntargetbar
|
||||
local getTargetBar = function(scrollFrame, lineIndex)
|
||||
---@type breakdowntargetbar
|
||||
local targetBar = scrollFrame:GetLine(lineIndex)
|
||||
|
||||
--reset header alignment
|
||||
targetBar:ResetFramesToHeaderAlignment()
|
||||
|
||||
spellsTab.UpdateBarSettings(targetBar)
|
||||
|
||||
--reset columns, hiding them
|
||||
targetBar.Icon:Hide()
|
||||
for inLineIndex = 1, #targetBar.InLineTexts do
|
||||
targetBar.InLineTexts[inLineIndex]:SetText("")
|
||||
end
|
||||
|
||||
return targetBar
|
||||
end
|
||||
|
||||
|
||||
---update a line using the data passed
|
||||
---@param targetBar breakdowntargetbar
|
||||
---@param index number spell position (from best to wrost)
|
||||
---@param combatObject combat
|
||||
---@param scrollFrame table
|
||||
---@param headerTable table
|
||||
---@param bkTargetData breakdowntargettable
|
||||
---@param totalValue number
|
||||
---@param topValue number the amount done of the first target, used to calculate the length of the statusbar
|
||||
---@param sortKey string
|
||||
local updateTargetBar = function(targetBar, index, combatObject, scrollFrame, headerTable, bkTargetData, totalValue, topValue, sortKey) --~target ~update ~targetbar ~updatetargetbar
|
||||
--scrollFrame is defined as a table which is false, scrollFrame is a frame
|
||||
local textIndex = 1
|
||||
|
||||
for headerIndex = 1, #headerTable do
|
||||
---@type number
|
||||
local value
|
||||
|
||||
targetBar.bkTargetData = bkTargetData
|
||||
value = bkTargetData.total
|
||||
|
||||
---@type number
|
||||
local combatTime = combatObject:GetCombatTime()
|
||||
|
||||
local actorContainer = combatObject:GetContainer(spellsTab.mainAttribute)
|
||||
local targetActorObject = actorContainer:GetActor(bkTargetData.name)
|
||||
|
||||
targetBar.statusBar.backgroundTexture:SetAlpha(Details.breakdown_spell_tab.spellbar_background_alpha)
|
||||
|
||||
--statusbar size by percent
|
||||
if (topValue > 0) then
|
||||
targetBar.statusBar:SetValue(bkTargetData[sortKey] / topValue * 100)
|
||||
else
|
||||
targetBar.statusBar:SetValue(0)
|
||||
end
|
||||
|
||||
--statusbar color
|
||||
targetBar.statusBar:SetStatusBarColor(1, 1, 1, 1)
|
||||
|
||||
local platerNameplates = _G.Plater
|
||||
if (platerNameplates and targetActorObject) then
|
||||
local npcId = tonumber(targetActorObject.aID)
|
||||
if (npcId) then
|
||||
local platerProfile = platerNameplates.db.profile
|
||||
local npcColors = platerProfile.npc_colors
|
||||
local platerNpcColorTable = npcColors[npcId]
|
||||
if (platerNpcColorTable) then
|
||||
if (platerNpcColorTable[1] == true) then
|
||||
local color = platerNpcColorTable[3]
|
||||
local r, g, b, a = DF:ParseColors(color)
|
||||
targetBar.statusBar:SetStatusBarColor(r, g, b, a)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
targetBar.combatTime = combatTime
|
||||
targetBar.actorName = bkTargetData.name
|
||||
|
||||
---@type fontstring
|
||||
local text = targetBar.InLineTexts[textIndex]
|
||||
local header = headerTable[headerIndex]
|
||||
|
||||
if (header.name == "icon") then
|
||||
targetBar.Icon:Show()
|
||||
|
||||
if (targetActorObject) then
|
||||
Details.SetClassIcon(targetActorObject, targetBar.Icon, spellsTab.GetInstance(), targetActorObject:Class())
|
||||
else
|
||||
targetBar.Icon:SetTexture([[Interface\AddOns\Details\images\classes_small_alpha]])
|
||||
---@type {key1: number, key2: number, key3: number, key4: number}
|
||||
local texCoords = Details.class_coords["ENEMY"]
|
||||
targetBar.Icon:SetTexCoord(unpack(texCoords))
|
||||
end
|
||||
|
||||
targetBar:AddFrameToHeaderAlignment(targetBar.Icon)
|
||||
|
||||
elseif (header.name == "rank") then
|
||||
text:SetText(index)
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
targetBar.rank = index
|
||||
textIndex = textIndex + 1
|
||||
|
||||
elseif (header.name == "name") then
|
||||
local noRealmName = DF:RemoveRealmName(bkTargetData.name)
|
||||
local noOwnerName = noRealmName:gsub((" <.*"), "")
|
||||
text:SetText(noOwnerName)
|
||||
targetBar.name = bkTargetData.name
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
textIndex = textIndex + 1
|
||||
|
||||
elseif (header.name == "amount") then
|
||||
text:SetText(Details:Format(value))
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
textIndex = textIndex + 1
|
||||
|
||||
elseif (header.name == "percent") then
|
||||
targetBar.percent = value / math.max(totalValue, 0.001) * 100 --totalValue is nil
|
||||
---@type string
|
||||
local percentFormatted = string.format("%.1f", targetBar.percent) .. "%"
|
||||
text:SetText(percentFormatted)
|
||||
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
textIndex = textIndex + 1
|
||||
|
||||
elseif (header.name == "overheal" and bkTargetData.overheal) then
|
||||
if (bkTargetData.overheal > 0) then
|
||||
local totalHeal = bkTargetData.overheal + value
|
||||
text:SetText(string.format("%.1f", bkTargetData.overheal / totalHeal * 100) .. "%")
|
||||
else
|
||||
text:SetText("0%")
|
||||
end
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
textIndex = textIndex + 1
|
||||
|
||||
elseif (header.name == "absorbed") then
|
||||
text:SetText(Details:Format(bkTargetData.absorbed or 0))
|
||||
targetBar:AddFrameToHeaderAlignment(text)
|
||||
textIndex = textIndex + 1
|
||||
end
|
||||
end
|
||||
|
||||
targetBar:AlignWithHeader(scrollFrame.Header, "left")
|
||||
end
|
||||
|
||||
---refresh the data shown in the spells scroll box
|
||||
---@param scrollFrame table
|
||||
---@param scrollData breakdowntargettablelist
|
||||
---@param offset number
|
||||
---@param totalLines number
|
||||
local refreshTargetsFunc = function(scrollFrame, scrollData, offset, totalLines) --~refresh ~target ~refreshtargets
|
||||
---@type number
|
||||
local topValue = scrollFrame.topValue
|
||||
---@type number
|
||||
local totalValue = scrollData.totalValue
|
||||
---@type actor
|
||||
local actorObject = spellsTab.GetActor()
|
||||
---@type string
|
||||
local actorName = actorObject:Name()
|
||||
---@type combat
|
||||
local combatObject = spellsTab.GetCombat()
|
||||
---@type instance
|
||||
local instanceObject = spellsTab.GetInstance()
|
||||
|
||||
---@type number
|
||||
local mainAttribute = spellsTab.mainAttribute
|
||||
|
||||
local sortKey = scrollFrame.SortKey
|
||||
local headerTable = spellsTab.targetsHeaderData
|
||||
|
||||
local lineIndex = 1
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
|
||||
---@type breakdowntargettable
|
||||
local bkTargetData = scrollData[index]
|
||||
if (bkTargetData) then
|
||||
---called mainSpellBar because it is the line that shows the sum of all spells merged (if any)
|
||||
---@type breakdowntargetbar
|
||||
local targetBar = getTargetBar(scrollFrame, lineIndex)
|
||||
do
|
||||
if (targetBar) then
|
||||
lineIndex = lineIndex + 1
|
||||
updateTargetBar(targetBar, index, combatObject, scrollFrame, headerTable, bkTargetData, totalValue, topValue, sortKey)
|
||||
end
|
||||
end
|
||||
|
||||
if (lineIndex > totalLines) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---create the target container
|
||||
---@param tabFrame tabframe
|
||||
---@return breakdowntargetscrollframe
|
||||
function spellsTab.CreateTargetContainer(tabFrame) --~create ~target ~createtargetcontainer ~createtargetscroll ~createtarget
|
||||
---@type width
|
||||
local width = Details.breakdown_spell_tab.targetcontainer_width
|
||||
---@type height
|
||||
local height = Details.breakdown_spell_tab.targetcontainer_height
|
||||
|
||||
local defaultAmountOfLines = 50
|
||||
|
||||
--create a container for the scrollframe
|
||||
local options = {
|
||||
width = Details.breakdown_spell_tab.targetcontainer_width,
|
||||
height = Details.breakdown_spell_tab.targetcontainer_height,
|
||||
is_locked = Details.breakdown_spell_tab.targetcontainer_islocked,
|
||||
can_move = false,
|
||||
can_move_children = false,
|
||||
use_top_resizer = true,
|
||||
use_right_resizer = true,
|
||||
}
|
||||
|
||||
---@type df_framecontainer
|
||||
local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "TargetScrollContainer")
|
||||
container:SetPoint("topleft", spellsTab.GetSpellScrollContainer(), "bottomleft", 0, -25)
|
||||
container:SetFrameLevel(tabFrame:GetFrameLevel() + 10)
|
||||
spellsTab.TargetsContainerFrame = container
|
||||
|
||||
local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue)
|
||||
if (frameContainer:IsShown()) then
|
||||
if (settingName == "height") then
|
||||
---@type number
|
||||
local currentHeight = spellsTab.GetTargetScrollFrame():GetHeight()
|
||||
Details.breakdown_spell_tab.targetcontainer_height = settingValue
|
||||
--the -0.1 is the avoid the random fraction of 1.9999999990 to 2.0000000001
|
||||
local lineAmount = currentHeight / CONST_SPELLSCROLL_LINEHEIGHT - 0.1
|
||||
lineAmount = math.floor(lineAmount)
|
||||
spellsTab.GetTargetScrollFrame():SetNumFramesShown(lineAmount)
|
||||
|
||||
elseif (settingName == "width") then
|
||||
Details.breakdown_spell_tab.targetcontainer_width = settingValue
|
||||
|
||||
elseif (settingName == "is_locked") then
|
||||
Details.breakdown_spell_tab.targetcontainer_islocked = settingValue
|
||||
end
|
||||
end
|
||||
end
|
||||
container:SetSettingChangedCallback(settingChangedCallbackFunction)
|
||||
|
||||
--create the scrollframe similar to scrollframe used in the spellscrollframe
|
||||
--replace this with a framework scrollframe
|
||||
---@type breakdowntargetscrollframe
|
||||
local targetScrollFrame = DF:CreateScrollBox(container, "$parentTargetScroll", refreshTargetsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
DF:ReskinSlider(targetScrollFrame)
|
||||
targetScrollFrame:SetBackdrop({})
|
||||
targetScrollFrame:SetAllPoints()
|
||||
|
||||
---@param self breakdownphasescrollframe
|
||||
---@return breakdownreporttable
|
||||
function targetScrollFrame:GetReportData()
|
||||
local instance = spellsTab.GetInstance()
|
||||
local data = targetScrollFrame:GetData()
|
||||
local formatFunc = Details:GetCurrentToKFunction()
|
||||
local actorObject = spellsTab.GetActor()
|
||||
local displayId, subDisplayId = instance:GetDisplay()
|
||||
local subDisplayName = Details:GetSubAttributeName(displayId, subDisplayId)
|
||||
local combatName = instance:GetCombat():GetCombatName()
|
||||
|
||||
---@type breakdownreporttable
|
||||
local reportData = {
|
||||
title = "Target of " .. detailsFramework:RemoveRealmName(actorObject:Name()) .. " | " .. subDisplayName .. " | " .. combatName
|
||||
}
|
||||
|
||||
local topValue = data[1] and data[1].total or 0
|
||||
|
||||
for i = 1, #data do
|
||||
---@type breakdowntargettable
|
||||
local dataTable = data[i]
|
||||
|
||||
reportData[#reportData+1] = {
|
||||
name = dataTable.name,
|
||||
amount = formatFunc(nil, dataTable.total),
|
||||
percent = string.format("%.1f", dataTable.total / topValue * 100) .. "%",
|
||||
}
|
||||
end
|
||||
|
||||
return reportData
|
||||
end
|
||||
|
||||
container:RegisterChildForDrag(targetScrollFrame)
|
||||
|
||||
targetScrollFrame.DontHideChildrenOnPreRefresh = false
|
||||
tabFrame.TargetScrollFrame = targetScrollFrame
|
||||
spellsTab.TargetScrollFrame = targetScrollFrame
|
||||
|
||||
spellsTab.ApplyStandardBackdrop(container, targetScrollFrame)
|
||||
|
||||
---@param data breakdowntargettablelist
|
||||
function targetScrollFrame:RefreshMe(data) --~refreshme (targets) ~refreshmet
|
||||
--get which column is currently selected and the sort order
|
||||
local columnIndex, order, key = targetScrollFrame.Header:GetSelectedColumn()
|
||||
targetScrollFrame.SortKey = key
|
||||
|
||||
---@type string
|
||||
local keyToSort = key
|
||||
|
||||
if (order == "DESC") then
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] > t2[keyToSort]
|
||||
end)
|
||||
targetScrollFrame.topValue = data[1] and data[1][keyToSort]
|
||||
else
|
||||
table.sort(data,
|
||||
function(t1, t2)
|
||||
return t1[keyToSort] < t2[keyToSort]
|
||||
end)
|
||||
targetScrollFrame.topValue = data[#data] and data[#data][keyToSort]
|
||||
end
|
||||
|
||||
if (key == "overheal") then
|
||||
data.totalValue = data.totalValueOverheal
|
||||
end
|
||||
--default: data.totalValue
|
||||
--data.totalValueOverheal
|
||||
|
||||
targetScrollFrame:SetData(data)
|
||||
targetScrollFrame:Refresh()
|
||||
end
|
||||
|
||||
--~header
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
header_height = 14,
|
||||
|
||||
reziser_shown = true,
|
||||
reziser_width = 2,
|
||||
reziser_color = {.5, .5, .5, 0.7},
|
||||
reziser_max_width = 246,
|
||||
|
||||
header_click_callback = spellsTab.OnAnyColumnHeaderClickCallback,
|
||||
|
||||
header_backdrop_color = {0.1, 0.1, 0.1, 0.4},
|
||||
text_color = {1, 1, 1, 0.823},
|
||||
}
|
||||
|
||||
---@type df_headerframe
|
||||
local header = DetailsFramework:CreateHeader(container, spellsTab.targetContainerColumnData, headerOptions)
|
||||
targetScrollFrame.Header = header
|
||||
targetScrollFrame.Header:SetPoint("topleft", targetScrollFrame, "topleft", 0, 1)
|
||||
targetScrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged)
|
||||
|
||||
--cache the type of this container
|
||||
headerContainerType[targetScrollFrame.Header] = "targets"
|
||||
|
||||
--create the scroll lines
|
||||
for i = 1, defaultAmountOfLines do
|
||||
targetScrollFrame:CreateLine(spellsTab.CreateTargetBar)
|
||||
end
|
||||
|
||||
tabFrame.targets = targetScrollFrame:CreateFontString(nil, "overlay", "QuestFont_Large")
|
||||
tabFrame.targets:SetPoint("bottomleft", container, "topleft", 2, 2)
|
||||
tabFrame.targets:SetText(Loc ["STRING_TARGETS"] .. ":")
|
||||
|
||||
return targetScrollFrame
|
||||
end
|
||||
|
||||
|
||||
---@param targetBar breakdowntargetbar
|
||||
local onEnterBreakdownTargetBar = function(targetBar)
|
||||
targetBar:SetAlpha(1)
|
||||
|
||||
---@type string @the name of the target
|
||||
local targetName = targetBar.actorName
|
||||
|
||||
Details:FormatCooltipForSpells()
|
||||
GameCooltip:SetOwner(targetBar, "bottom", "top", 4, -5)
|
||||
GameCooltip:SetOption("MinWidth", math.max(230, targetBar:GetWidth() * 0.98))
|
||||
|
||||
--build a list of spells which the target was hit by
|
||||
local spellsSortedResult = {}
|
||||
local total = 0
|
||||
|
||||
---@type actor
|
||||
local actorObject = spellsTab.GetActor()
|
||||
|
||||
---@type combat
|
||||
local combatObject = spellsTab.GetCombat()
|
||||
|
||||
---@type instance
|
||||
local instanceObject = spellsTab.GetInstance()
|
||||
|
||||
---@type number
|
||||
local mainAttribute = instanceObject:GetDisplay()
|
||||
|
||||
---@type spellcontainer
|
||||
local spellContainer = actorObject:GetSpellContainer("spell")
|
||||
|
||||
local targetScrollFrame = spellsTab.GetTargetScrollFrame()
|
||||
|
||||
---@type number, string, string
|
||||
local columnIndex, order, key = targetScrollFrame.Header:GetSelectedColumn()
|
||||
|
||||
---@type string the label shown at the top of the tooltip
|
||||
local labelTooltipTitle = Loc ["STRING_DAMAGE_FROM"]
|
||||
|
||||
local targetTableName = "targets"
|
||||
if (mainAttribute == DETAILS_ATTRIBUTE_HEAL) then
|
||||
if (key == "total") then
|
||||
labelTooltipTitle = Loc ["STRING_HEALING_FROM"]
|
||||
|
||||
elseif (key == "overheal") then
|
||||
targetTableName = "targets_overheal"
|
||||
labelTooltipTitle = Loc ["STRING_OVERHEALED"]
|
||||
end
|
||||
end
|
||||
|
||||
--this part kinda belong top damage or healing class, shouldn't be here
|
||||
|
||||
---@type number, spelltable
|
||||
for spellId, spellTable in spellContainer:ListActors() do
|
||||
if (spellTable.isReflection) then
|
||||
---@type string, number
|
||||
for spellTargetName in pairs(spellTable.targets) do
|
||||
if (spellTargetName == targetName) then
|
||||
for reflectedSpellId, reflectedAmount in pairs(spellTable.extra) do
|
||||
local spellName, _, spellIcon = _GetSpellInfo(reflectedSpellId)
|
||||
table.insert(spellsSortedResult, {reflectedSpellId, reflectedAmount, spellName .. " (|cFFCCBBBBreflected|r)", spellIcon})
|
||||
total = total + reflectedAmount
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for spellTargetName, amount in pairs(spellTable[targetTableName]) do
|
||||
if (spellTargetName == targetName) then
|
||||
local spellName, _, spellIcon = _GetSpellInfo(spellId)
|
||||
table.insert(spellsSortedResult, {spellId, amount, spellName, spellIcon})
|
||||
total = total + amount
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--add pets
|
||||
local petArray = actorObject:GetPets()
|
||||
for _, petName in ipairs(petArray) do
|
||||
local petActorObject = combatObject(mainAttribute, petName)
|
||||
if (petActorObject) then
|
||||
---@type spellcontainer
|
||||
local petSpellContainer = petActorObject:GetSpellContainer("spell")
|
||||
|
||||
---@type spellid, spelltable
|
||||
for spellId, spellTable in petSpellContainer:ListActors() do --user reported petSpellContainer is nil x1
|
||||
for spellTargetName, amount in pairs(spellTable[targetTableName]) do
|
||||
if (spellTargetName == targetName) then
|
||||
local spellName, _, spellIcon = _GetSpellInfo(spellId)
|
||||
table.insert(spellsSortedResult, {spellId, amount, spellName .. " (" .. petName:gsub((" <.*"), "") .. ")", spellIcon})
|
||||
total = total + amount
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(spellsSortedResult, Details.Sort2)
|
||||
|
||||
--need to change is this is a healing
|
||||
Details:AddTooltipSpellHeaderText(labelTooltipTitle .. ":", {1, 0.9, 0.0, 1}, 1, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
|
||||
Details:AddTooltipHeaderStatusbar(1, 1, 1, 1)
|
||||
|
||||
---@type tablesize
|
||||
local iconSize = Details.tooltip.icon_size
|
||||
---@type tablecoords
|
||||
local iconBorder = Details.tooltip.icon_border_texcoord
|
||||
|
||||
local topValue = spellsSortedResult[1] and spellsSortedResult[1][2]
|
||||
|
||||
if (topValue) then
|
||||
for index, tabela in ipairs(spellsSortedResult) do
|
||||
local spellId, amount, spellName, spellIcon = unpack(tabela)
|
||||
if (amount < 1) then
|
||||
break
|
||||
end
|
||||
GameCooltip:AddLine(spellName, Details:Format(amount) .. " (" .. string.format("%.1f", amount / total * 100) .. "%)")
|
||||
GameCooltip:AddIcon(spellIcon, nil, nil, iconSize.W + 4, iconSize.H + 4, iconBorder.L, iconBorder.R, iconBorder.T, iconBorder.B)
|
||||
Details:AddTooltipBackgroundStatusbar(false, amount / topValue * 100)
|
||||
end
|
||||
end
|
||||
|
||||
GameCooltip:Show()
|
||||
end
|
||||
|
||||
---@param self breakdowntargetbar
|
||||
local onLeaveBreakdownTargetBar = function(self)
|
||||
self:SetAlpha(0.9)
|
||||
GameCooltip:Hide()
|
||||
end
|
||||
|
||||
---create a targetbar within the target scroll
|
||||
---@param self breakdowntargetscrollframe
|
||||
---@param index number
|
||||
---@return breakdowntargetbar
|
||||
function spellsTab.CreateTargetBar(self, index) --~create ~target ~createtarget ~targetbar
|
||||
---@type breakdowntargetbar
|
||||
local targetBar = CreateFrame("button", self:GetName() .. "TargetBarButton" .. index, self)
|
||||
targetBar.index = index
|
||||
|
||||
--size and positioning
|
||||
targetBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT)
|
||||
local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15
|
||||
targetBar:SetPoint("topleft", self, "topleft", 1, y)
|
||||
targetBar:SetPoint("topright", self, "topright", -1, y)
|
||||
targetBar:EnableMouse(true)
|
||||
|
||||
targetBar:SetAlpha(0.823)
|
||||
targetBar:SetFrameStrata("HIGH")
|
||||
targetBar:SetScript("OnEnter", onEnterBreakdownTargetBar)
|
||||
targetBar:SetScript("OnLeave", onLeaveBreakdownTargetBar)
|
||||
|
||||
DF:Mixin(targetBar, DF.HeaderFunctions)
|
||||
|
||||
---@type breakdownspellbarstatusbar
|
||||
local statusBar = CreateFrame("StatusBar", "$parentStatusBar", targetBar)
|
||||
statusBar:SetAllPoints()
|
||||
statusBar:SetAlpha(0.5)
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetValue(50)
|
||||
statusBar:EnableMouse(false)
|
||||
statusBar:SetFrameLevel(targetBar:GetFrameLevel() - 1)
|
||||
targetBar.statusBar = statusBar
|
||||
|
||||
---@type texture this is the statusbar texture
|
||||
local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork")
|
||||
statusBarTexture:SetTexture(SharedMedia:Fetch("statusbar", Details.breakdown_general.bar_texture))
|
||||
statusBar:SetStatusBarTexture(statusBarTexture)
|
||||
statusBar:SetStatusBarColor(1, 1, 1, 1)
|
||||
|
||||
---@type texture shown when the mouse hoverover this bar
|
||||
local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight")
|
||||
hightlightTexture:SetTexture(1, 1, 1, 0.2)
|
||||
hightlightTexture:SetAllPoints()
|
||||
statusBar.highlightTexture = hightlightTexture
|
||||
|
||||
---@type texture background texture
|
||||
local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border")
|
||||
backgroundTexture:SetAllPoints()
|
||||
backgroundTexture:SetTexture(.05, .05, .05)
|
||||
backgroundTexture:SetAlpha(1)
|
||||
statusBar.backgroundTexture = backgroundTexture
|
||||
|
||||
--create an icon
|
||||
---@type texture
|
||||
local icon = statusBar:CreateTexture("$parentTexture", "overlay")
|
||||
icon:SetPoint("left", statusBar, "left", 0, 0)
|
||||
icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2)
|
||||
icon:SetTexCoord(.1, .9, .1, .9)
|
||||
targetBar.Icon = icon
|
||||
|
||||
targetBar:AddFrameToHeaderAlignment(icon)
|
||||
|
||||
targetBar.InLineTexts = {}
|
||||
|
||||
for i = 1, 5 do
|
||||
---@type fontstring
|
||||
local fontString = targetBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall")
|
||||
fontString:SetJustifyH("left")
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
fontString:SetNonSpaceWrap(true)
|
||||
fontString:SetWordWrap(false)
|
||||
targetBar["lineText" .. i] = fontString
|
||||
targetBar.InLineTexts[i] = fontString
|
||||
fontString:SetTextColor(1, 1, 1, 1)
|
||||
targetBar:AddFrameToHeaderAlignment(fontString)
|
||||
end
|
||||
|
||||
targetBar:AlignWithHeader(self.Header, "left")
|
||||
|
||||
return targetBar
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,305 @@
|
||||
|
||||
---@type details
|
||||
local Details = Details
|
||||
---@type detailsframework
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
local GameTooltip = GameTooltip
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
local _
|
||||
|
||||
Details.BuffUptimeSpellsToIgnore = {
|
||||
[186401] = true, --Sign of the Skirmisher
|
||||
[366646] = true, --Familiar Skies
|
||||
[403265] = true, --Bronze Attunement
|
||||
[381748] = true, --Blessing of the Bronze
|
||||
[397734] = true, --Word of a Worthy Ally
|
||||
[402221] = true, --Obsidian Resonance
|
||||
[225788] = true, --Sign of the Emissary
|
||||
--[] = true, --
|
||||
}
|
||||
|
||||
local createAuraTabOnBreakdownWindow = function(tab, frame)
|
||||
local scroll_line_amount = 25
|
||||
local scroll_width = 410
|
||||
local scrollHeight = 495
|
||||
local scroll_line_height = 19
|
||||
local text_size = 10
|
||||
|
||||
local debuffScrollStartX = 445
|
||||
|
||||
local lineBackgroundColor = {{1, 1, 1, .1}, {1, 1, 1, 0}}
|
||||
|
||||
local headerOffsetsBuffs = {
|
||||
--buff label, uptime, applications, refreshes, wa
|
||||
6, 190, 290, 336, 380
|
||||
}
|
||||
|
||||
local headerOffsetsDebuffs = {
|
||||
--debuff label, uptime, applications, refreshes, wa
|
||||
426, 630, 729, 775, 820
|
||||
}
|
||||
|
||||
local onEnterLine = function(self)
|
||||
if (self.spellID) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
|
||||
Details:GameTooltipSetSpellByID(self.spellID)
|
||||
GameTooltip:Show()
|
||||
self:SetBackdropColor(1, 1, 1, .2)
|
||||
end
|
||||
end
|
||||
|
||||
local onLeaveLine = function(self)
|
||||
GameTooltip:Hide()
|
||||
self:SetBackdropColor(unpack(self.BackgroundColor))
|
||||
end
|
||||
|
||||
local onClickLine = function(self)
|
||||
|
||||
end
|
||||
|
||||
local createLineScroll = function(self, index)
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self,"BackdropTemplate")
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(scroll_line_height+1)))
|
||||
line:SetSize(scroll_width -2, scroll_line_height)
|
||||
line:SetScript("OnEnter", onEnterLine)
|
||||
line:SetScript("OnLeave", onLeaveLine)
|
||||
line:SetScript("OnClick", onClickLine)
|
||||
|
||||
line:SetBackdrop({bgFile =[[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(0, 0, 0, 0.2)
|
||||
line.BackgroundColor = lineBackgroundColor[1]
|
||||
|
||||
local iconTexture = line:CreateTexture("$parentIcon", "overlay")
|
||||
iconTexture:SetSize(scroll_line_height -2 , scroll_line_height - 2)
|
||||
iconTexture:SetAlpha(0.924)
|
||||
|
||||
local nameLabel = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||||
local uptimeLabel = line:CreateFontString("$parentUptime", "overlay", "GameFontNormal")
|
||||
local uptimePercentLabel = line:CreateFontString("$parentPercent", "overlay", "GameFontNormal")
|
||||
local applyLabel = line:CreateFontString("$parentApplyed", "overlay", "GameFontNormal")
|
||||
local refreshLabel = line:CreateFontString("$parentRefreshed", "overlay", "GameFontNormal")
|
||||
|
||||
local receivedTexture = line:CreateTexture("$parentReceived", "artwork")
|
||||
receivedTexture:SetPoint("topright", line, "topright", 0, 0)
|
||||
receivedTexture:SetPoint("bottomright", line, "bottomright", 0, 0)
|
||||
receivedTexture:SetWidth(line:GetWidth())
|
||||
receivedTexture:SetTexture([[Interface\AddOns\Details\images\bar_textures\gradient_white_10percent_left]])
|
||||
receivedTexture:SetTexCoord(0, 1, 0, 1)
|
||||
receivedTexture:SetVertexColor(0, .8, 0, 0.7)
|
||||
receivedTexture:Hide()
|
||||
|
||||
detailsFramework:SetFontSize(nameLabel, text_size)
|
||||
detailsFramework:SetFontSize(uptimeLabel, text_size)
|
||||
detailsFramework:SetFontSize(uptimePercentLabel, text_size)
|
||||
detailsFramework:SetFontSize(applyLabel, text_size)
|
||||
detailsFramework:SetFontSize(refreshLabel, text_size)
|
||||
|
||||
iconTexture:SetPoint("left", line, "left", 2, 0)
|
||||
nameLabel:SetPoint("left", iconTexture, "right", 2, 0)
|
||||
uptimeLabel:SetPoint("left", line, "left", 186, 0)
|
||||
uptimePercentLabel:SetPoint("left", line, "left", 220, 0)
|
||||
applyLabel:SetPoint("left", line, "left", 276, 0)
|
||||
refreshLabel:SetPoint("left", line, "left", 322, 0)
|
||||
|
||||
line.Icon = iconTexture
|
||||
line.Name = nameLabel
|
||||
line.Uptime = uptimeLabel
|
||||
line.UptimePercent = uptimePercentLabel
|
||||
line.Apply = applyLabel
|
||||
line.Refresh = refreshLabel
|
||||
line.ReceivedAura = receivedTexture
|
||||
|
||||
nameLabel:SetJustifyH("left")
|
||||
uptimeLabel:SetJustifyH("left")
|
||||
uptimePercentLabel:SetJustifyH("left")
|
||||
|
||||
applyLabel:SetJustifyH("center")
|
||||
refreshLabel:SetJustifyH("center")
|
||||
applyLabel:SetWidth(26)
|
||||
refreshLabel:SetWidth(26)
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
local scrollRefreshBuffs = function(self, data, offset, total_lines)
|
||||
for i = 1, total_lines do
|
||||
local index = i + offset
|
||||
local aura = data[index]
|
||||
|
||||
if (aura) then
|
||||
local spellIcon, spellName, uptime, applicationsAmount, refreshedAmount, uptimePercent = unpack(aura)
|
||||
local line = self:GetLine(i)
|
||||
|
||||
if (aura.bReceived) then
|
||||
line.ReceivedAura:Show()
|
||||
else
|
||||
line.ReceivedAura:Hide()
|
||||
end
|
||||
|
||||
line.spellID = aura.spellID
|
||||
line.Icon:SetTexture(spellIcon)
|
||||
|
||||
line.Icon:SetTexCoord(.1, .9, .1, .9)
|
||||
|
||||
line.Name:SetText(spellName)
|
||||
line.Uptime:SetText(detailsFramework:IntegerToTimer(uptime))
|
||||
line.UptimePercent:SetText("|cFFBBAAAA" .. math.floor(uptimePercent) .. "%|r")
|
||||
line.Apply:SetText(applicationsAmount)
|
||||
line.Refresh:SetText(refreshedAmount)
|
||||
|
||||
if (i % 2 == 0) then
|
||||
line:SetBackdropColor(unpack(lineBackgroundColor[1]))
|
||||
line.BackgroundColor = lineBackgroundColor[1]
|
||||
else
|
||||
line:SetBackdropColor(unpack(lineBackgroundColor[2]))
|
||||
line.BackgroundColor = lineBackgroundColor[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local createTitleDesc_Frame = function(anchorWidget, desc)
|
||||
local newTitleDescFrame = CreateFrame("frame", nil, frame)
|
||||
newTitleDescFrame:SetSize(40, 20)
|
||||
newTitleDescFrame:SetPoint("center", anchorWidget, "center")
|
||||
|
||||
newTitleDescFrame:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(newTitleDescFrame, "ANCHOR_TOPRIGHT")
|
||||
GameTooltip:AddLine(desc)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
|
||||
newTitleDescFrame:SetScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
return newTitleDescFrame
|
||||
end
|
||||
|
||||
local buffLabel = detailsFramework:CreateLabel(frame, "Buff Name")
|
||||
buffLabel:SetPoint(headerOffsetsBuffs[1], -10)
|
||||
local uptimeLabel = detailsFramework:CreateLabel(frame, "Uptime")
|
||||
uptimeLabel:SetPoint(headerOffsetsBuffs[2], -10)
|
||||
|
||||
local appliedLabel = detailsFramework:CreateLabel(frame, "A")
|
||||
appliedLabel:SetPoint(headerOffsetsBuffs[3], -10)
|
||||
createTitleDesc_Frame(appliedLabel.widget, "applications")
|
||||
|
||||
local refreshedLabel = detailsFramework:CreateLabel(frame, "R")
|
||||
refreshedLabel:SetPoint(headerOffsetsBuffs[4], -10)
|
||||
createTitleDesc_Frame(refreshedLabel.widget, "refreshes")
|
||||
|
||||
local buffScroll = detailsFramework:CreateScrollBox(frame, "$parentBuffUptimeScroll", scrollRefreshBuffs, {}, scroll_width, scrollHeight, scroll_line_amount, scroll_line_height)
|
||||
buffScroll:SetPoint("topleft", frame, "topleft", 5, -30)
|
||||
for i = 1, scroll_line_amount do
|
||||
local line = buffScroll:CreateLine(createLineScroll)
|
||||
line.AuraType = "BUFF"
|
||||
end
|
||||
detailsFramework:ReskinSlider(buffScroll)
|
||||
tab.BuffScroll = buffScroll
|
||||
|
||||
local debuffLabel = detailsFramework:CreateLabel(frame, "Debuff Name")
|
||||
debuffLabel:SetPoint(headerOffsetsDebuffs[1], -10)
|
||||
|
||||
local uptimeLabel2 = detailsFramework:CreateLabel(frame, "Uptime")
|
||||
uptimeLabel2:SetPoint(headerOffsetsDebuffs[2], -10)
|
||||
|
||||
local appliedLabel2 = detailsFramework:CreateLabel(frame, "A")
|
||||
appliedLabel2:SetPoint(headerOffsetsDebuffs[3], -10)
|
||||
createTitleDesc_Frame(appliedLabel2.widget, "applications")
|
||||
|
||||
local refreshedLabel2 = detailsFramework:CreateLabel(frame, "R")
|
||||
refreshedLabel2:SetPoint(headerOffsetsDebuffs[4], -10)
|
||||
createTitleDesc_Frame(refreshedLabel2.widget, "refreshes")
|
||||
|
||||
local debuffScroll = detailsFramework:CreateScrollBox(frame, "$parentDebuffUptimeScroll", scrollRefreshBuffs, {}, scroll_width, scrollHeight, scroll_line_amount, scroll_line_height)
|
||||
debuffScroll:SetPoint("topleft", frame, "topleft", debuffScrollStartX, -30)
|
||||
for i = 1, scroll_line_amount do
|
||||
local line = debuffScroll:CreateLine(createLineScroll)
|
||||
line.AuraType = "DEBUFF"
|
||||
end
|
||||
detailsFramework:ReskinSlider(debuffScroll)
|
||||
|
||||
tab.DebuffScroll = debuffScroll
|
||||
|
||||
if (not frame.__background) then
|
||||
DetailsFramework:ApplyStandardBackdrop(frame)
|
||||
frame.__background:SetAlpha(0.6)
|
||||
end
|
||||
end
|
||||
|
||||
local aurasTabFillCallback = function(tab, player, combat)
|
||||
---@type actor
|
||||
local utilityActor = combat:GetActor(DETAILS_ATTRIBUTE_MISC, player:Name())
|
||||
---@type number
|
||||
local combatTime = combat:GetCombatTime()
|
||||
|
||||
if (utilityActor) then
|
||||
do --buffs
|
||||
local newAuraTable = {}
|
||||
local spellContainer = utilityActor:GetSpellContainer("buff")
|
||||
if (spellContainer) then
|
||||
for spellId, spellTable in spellContainer:ListSpells() do
|
||||
local spellName, _, spellIcon = Details.GetSpellInfo(spellId)
|
||||
local uptime = spellTable.uptime or 0
|
||||
if (not Details.BuffUptimeSpellsToIgnore[spellId]) then
|
||||
table.insert(newAuraTable, {spellIcon, spellName, uptime, spellTable.appliedamt, spellTable.refreshamt, uptime / combatTime * 100, spellID = spellId})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(newAuraTable, Details.Sort3)
|
||||
tab.BuffScroll:SetData(newAuraTable)
|
||||
tab.BuffScroll:Refresh()
|
||||
end
|
||||
|
||||
do --debuffs
|
||||
local newAuraTable = {}
|
||||
local spellContainer = utilityActor:GetSpellContainer("debuff")
|
||||
if (spellContainer) then
|
||||
for spellId, spellTable in spellContainer:ListSpells() do
|
||||
local spellName, _, spellIcon = Details.GetSpellInfo(spellId)
|
||||
table.insert(newAuraTable, {spellIcon, spellName, spellTable.uptime, spellTable.appliedamt, spellTable.refreshamt, spellTable.uptime / combatTime * 100, spellID = spellId})
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(newAuraTable, Details.Sort3)
|
||||
tab.DebuffScroll:SetData(newAuraTable)
|
||||
tab.DebuffScroll:Refresh()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local iconTableAuras = {
|
||||
texture = [[Interface\AddOns\Details\images\icons]],
|
||||
coords = {257/512, 278/512, 0/512, 19/512},
|
||||
width = 16,
|
||||
height = 16,
|
||||
}
|
||||
|
||||
function Details:InitializeAurasTab()
|
||||
--check if the tab is already created
|
||||
for i = 1, #Details.player_details_tabs do
|
||||
local tabButton = Details.player_details_tabs[i]
|
||||
if (tabButton.tabname == "Auras") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Details:CreatePlayerDetailsTab("Auras", --[1] tab name
|
||||
"Auras", --[2] localized name
|
||||
function(tabOBject, playerObject) --[3] condition
|
||||
return true
|
||||
end,
|
||||
|
||||
aurasTabFillCallback, --[4] fill function
|
||||
|
||||
nil, --[5] onclick
|
||||
|
||||
createAuraTabOnBreakdownWindow, --[6] oncreate
|
||||
iconTableAuras --icon table
|
||||
)
|
||||
end
|
||||
@@ -0,0 +1,715 @@
|
||||
|
||||
local Details = Details
|
||||
|
||||
local unpack = unpack
|
||||
local _GetSpellInfo = Details.GetSpellInfo
|
||||
local PLAYER_DETAILS_STATUSBAR_HEIGHT = 20
|
||||
local CreateFrame = CreateFrame
|
||||
local GameTooltip = GameTooltip
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" )
|
||||
|
||||
local red = "FFFFAAAA"
|
||||
local green = "FFAAFFAA"
|
||||
|
||||
local avoidance_create = function(tab, frame)
|
||||
--Percent Desc
|
||||
local percent_desc = frame:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
percent_desc:SetText("Percent values are comparisons with the previous try.")
|
||||
percent_desc:SetPoint("bottomleft", frame, "bottomleft", 13, 13 + PLAYER_DETAILS_STATUSBAR_HEIGHT)
|
||||
percent_desc:SetTextColor(.5, .5, .5, 1)
|
||||
|
||||
--SUMMARY
|
||||
local summaryBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
|
||||
Details.gump:ApplyStandardBackdrop(summaryBox)
|
||||
summaryBox:SetPoint("topleft", frame, "topleft", 10, -15)
|
||||
summaryBox:SetSize(200, 160)
|
||||
|
||||
local y = -5
|
||||
local padding = 16
|
||||
|
||||
local summary_text = summaryBox:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
summary_text:SetText("Summary")
|
||||
summary_text :SetPoint("topleft", summaryBox, "topleft", 5, y)
|
||||
|
||||
y = y - padding
|
||||
|
||||
--total damage received
|
||||
local damagereceived = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
damagereceived:SetPoint("topleft", summaryBox, "topleft", 15, y)
|
||||
damagereceived:SetText("Total Damage Taken:") --localize-me
|
||||
damagereceived:SetTextColor(.8, .8, .8, 1)
|
||||
|
||||
local damagereceived_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
damagereceived_amt:SetPoint("left", damagereceived, "right", 2, 0)
|
||||
damagereceived_amt:SetText("0")
|
||||
tab.damagereceived = damagereceived_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--per second
|
||||
local damagepersecond = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
damagepersecond:SetPoint("topleft", summaryBox, "topleft", 20, y)
|
||||
damagepersecond:SetText("Per Second:") --localize-me
|
||||
|
||||
local damagepersecond_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
damagepersecond_amt:SetPoint("left", damagepersecond, "right", 2, 0)
|
||||
damagepersecond_amt:SetText("0")
|
||||
tab.damagepersecond = damagepersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--total absorbs
|
||||
local absorbstotal = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
absorbstotal:SetPoint("topleft", summaryBox, "topleft", 15, y)
|
||||
absorbstotal:SetText("Total Absorbs:") --localize-me
|
||||
absorbstotal:SetTextColor(.8, .8, .8, 1)
|
||||
|
||||
local absorbstotal_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
absorbstotal_amt:SetPoint("left", absorbstotal, "right", 2, 0)
|
||||
absorbstotal_amt:SetText("0")
|
||||
tab.absorbstotal = absorbstotal_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--per second
|
||||
local absorbstotalpersecond = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
absorbstotalpersecond:SetPoint("topleft", summaryBox, "topleft", 20, y)
|
||||
absorbstotalpersecond:SetText("Per Second:") --localize-me
|
||||
|
||||
local absorbstotalpersecond_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
absorbstotalpersecond_amt:SetPoint("left", absorbstotalpersecond, "right", 2, 0)
|
||||
absorbstotalpersecond_amt:SetText("0")
|
||||
tab.absorbstotalpersecond = absorbstotalpersecond_amt
|
||||
|
||||
|
||||
--MELEE
|
||||
|
||||
y = -5
|
||||
|
||||
local meleeBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
|
||||
Details.gump:ApplyStandardBackdrop(meleeBox)
|
||||
meleeBox:SetPoint("topleft", summaryBox, "bottomleft", 0, -5)
|
||||
meleeBox:SetSize(200, 160)
|
||||
|
||||
local melee_text = meleeBox:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
melee_text:SetText("Melee")
|
||||
melee_text :SetPoint("topleft", meleeBox, "topleft", 5, y)
|
||||
|
||||
y = y - padding
|
||||
|
||||
--dodge
|
||||
local dodge = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
dodge:SetPoint("topleft", meleeBox, "topleft", 15, y)
|
||||
dodge:SetText("Dodge:") --localize-me
|
||||
dodge:SetTextColor(.8, .8, .8, 1)
|
||||
local dodge_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
dodge_amt:SetPoint("left", dodge, "right", 2, 0)
|
||||
dodge_amt:SetText("0")
|
||||
tab.dodge = dodge_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
local dodgepersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
dodgepersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
|
||||
dodgepersecond:SetText("Per Second:") --localize-me
|
||||
|
||||
local dodgepersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
dodgepersecond_amt:SetPoint("left", dodgepersecond, "right", 2, 0)
|
||||
dodgepersecond_amt:SetText("0")
|
||||
tab.dodgepersecond = dodgepersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
-- parry
|
||||
local parry = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
parry:SetPoint("topleft", meleeBox, "topleft", 15, y)
|
||||
parry:SetText("Parry:") --localize-me
|
||||
parry:SetTextColor(.8, .8, .8, 1)
|
||||
local parry_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
parry_amt:SetPoint("left", parry, "right", 2, 0)
|
||||
parry_amt:SetText("0")
|
||||
tab.parry = parry_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
local parrypersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
parrypersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
|
||||
parrypersecond:SetText("Per Second:") --localize-me
|
||||
local parrypersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
parrypersecond_amt:SetPoint("left", parrypersecond, "right", 2, 0)
|
||||
parrypersecond_amt:SetText("0")
|
||||
tab.parrypersecond = parrypersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
-- block
|
||||
local block = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
block:SetPoint("topleft", meleeBox, "topleft", 15, y)
|
||||
block:SetText("Block:") --localize-me
|
||||
block:SetTextColor(.8, .8, .8, 1)
|
||||
local block_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
block_amt:SetPoint("left", block, "right", 2, 0)
|
||||
block_amt:SetText("0")
|
||||
tab.block = block_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
local blockpersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
blockpersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
|
||||
blockpersecond:SetText("Per Second:") --localize-me
|
||||
local blockpersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
blockpersecond_amt:SetPoint("left", blockpersecond, "right", 2, 0)
|
||||
blockpersecond_amt:SetText("0")
|
||||
tab.blockpersecond = blockpersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
local blockeddamage = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
blockeddamage:SetPoint("topleft", meleeBox, "topleft", 20, y)
|
||||
blockeddamage:SetText("Damage Blocked:") --localize-me
|
||||
local blockeddamage_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
blockeddamage_amt:SetPoint("left", blockeddamage, "right", 2, 0)
|
||||
blockeddamage_amt:SetText("0")
|
||||
tab.blockeddamage_amt = blockeddamage_amt
|
||||
|
||||
--ABSORBS
|
||||
y = -5
|
||||
|
||||
local absorbsBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
|
||||
Details.gump:ApplyStandardBackdrop(absorbsBox)
|
||||
absorbsBox:SetPoint("topleft", summaryBox, "topright", 10, 0)
|
||||
absorbsBox:SetSize(200, 160)
|
||||
|
||||
local absorb_text = absorbsBox:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
absorb_text:SetText("Absorb")
|
||||
absorb_text :SetPoint("topleft", absorbsBox, "topleft", 5, y)
|
||||
|
||||
y = y - padding
|
||||
|
||||
--full absorbs
|
||||
local fullsbsorbed = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
fullsbsorbed:SetPoint("topleft", absorbsBox, "topleft", 20, y)
|
||||
fullsbsorbed:SetText("Full Absorbs:") --localize-me
|
||||
fullsbsorbed:SetTextColor(.8, .8, .8, 1)
|
||||
local fullsbsorbed_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
fullsbsorbed_amt:SetPoint("left", fullsbsorbed, "right", 2, 0)
|
||||
fullsbsorbed_amt:SetText("0")
|
||||
tab.fullsbsorbed = fullsbsorbed_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--partially absorbs
|
||||
local partiallyabsorbed = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
partiallyabsorbed:SetPoint("topleft", absorbsBox, "topleft", 20, y)
|
||||
partiallyabsorbed:SetText("Partially Absorbed:") --localize-me
|
||||
partiallyabsorbed:SetTextColor(.8, .8, .8, 1)
|
||||
local partiallyabsorbed_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
partiallyabsorbed_amt:SetPoint("left", partiallyabsorbed, "right", 2, 0)
|
||||
partiallyabsorbed_amt:SetText("0")
|
||||
tab.partiallyabsorbed = partiallyabsorbed_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--partially absorbs per second
|
||||
local partiallyabsorbedpersecond = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
partiallyabsorbedpersecond:SetPoint("topleft", absorbsBox, "topleft", 25, y)
|
||||
partiallyabsorbedpersecond:SetText("Average:") --localize-me
|
||||
local partiallyabsorbedpersecond_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
partiallyabsorbedpersecond_amt:SetPoint("left", partiallyabsorbedpersecond, "right", 2, 0)
|
||||
partiallyabsorbedpersecond_amt:SetText("0")
|
||||
tab.partiallyabsorbedpersecond = partiallyabsorbedpersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--no absorbs
|
||||
local noabsorbs = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
noabsorbs:SetPoint("topleft", absorbsBox, "topleft", 20, y)
|
||||
noabsorbs:SetText("No Absorption:") --localize-me
|
||||
noabsorbs:SetTextColor(.8, .8, .8, 1)
|
||||
local noabsorbs_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
noabsorbs_amt:SetPoint("left", noabsorbs, "right", 2, 0)
|
||||
noabsorbs_amt:SetText("0")
|
||||
tab.noabsorbs = noabsorbs_amt
|
||||
|
||||
--HEALING
|
||||
|
||||
y = -5
|
||||
local healingBox = CreateFrame("frame", nil, frame,"BackdropTemplate")
|
||||
Details.gump:ApplyStandardBackdrop(healingBox)
|
||||
healingBox:SetPoint("topleft", absorbsBox, "bottomleft", 0, -5)
|
||||
healingBox:SetSize(200, 160)
|
||||
|
||||
local healing_text = healingBox:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
healing_text:SetText("Healing")
|
||||
healing_text :SetPoint("topleft", healingBox, "topleft", 5, y)
|
||||
|
||||
y = y - padding
|
||||
|
||||
--self healing
|
||||
local selfhealing = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
selfhealing:SetPoint("topleft", healingBox, "topleft", 20, y)
|
||||
selfhealing:SetText("Self Healing:") --localize-me
|
||||
selfhealing:SetTextColor(.8, .8, .8, 1)
|
||||
local selfhealing_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
selfhealing_amt:SetPoint("left", selfhealing, "right", 2, 0)
|
||||
selfhealing_amt:SetText("0")
|
||||
tab.selfhealing = selfhealing_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
--self healing per second
|
||||
local selfhealingpersecond = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
selfhealingpersecond:SetPoint("topleft", healingBox, "topleft", 25, y)
|
||||
selfhealingpersecond:SetText("Per Second:") --localize-me
|
||||
local selfhealingpersecond_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
selfhealingpersecond_amt:SetPoint("left", selfhealingpersecond, "right", 2, 0)
|
||||
selfhealingpersecond_amt:SetText("0")
|
||||
tab.selfhealingpersecond = selfhealingpersecond_amt
|
||||
|
||||
y = y - padding
|
||||
|
||||
for i = 1, 5 do
|
||||
local healer = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
healer:SetPoint("topleft", healingBox, "topleft", 20, y + ((i-1)*15)*-1)
|
||||
healer:SetText("healer name:") --localize-me
|
||||
healer:SetTextColor(.8, .8, .8, 1)
|
||||
local healer_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
healer_amt:SetPoint("left", healer, "right", 2, 0)
|
||||
healer_amt:SetText("0")
|
||||
tab ["healer" .. i] = {healer, healer_amt}
|
||||
end
|
||||
|
||||
--SPELLS
|
||||
|
||||
y = -5
|
||||
|
||||
local spellsBox = CreateFrame("frame", nil, frame,"BackdropTemplate")
|
||||
Details.gump:ApplyStandardBackdrop(spellsBox)
|
||||
spellsBox:SetPoint("topleft", absorbsBox, "topright", 10, 0)
|
||||
spellsBox:SetSize(346, 160 * 2 + 5)
|
||||
|
||||
local spells_text = spellsBox:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
spells_text:SetText("Spells")
|
||||
spells_text :SetPoint("topleft", spellsBox, "topleft", 5, y)
|
||||
|
||||
local frame_tooltip_onenter = function(self)
|
||||
if (self.spellid) then
|
||||
--self:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 512, edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", edgeSize = 8})
|
||||
self:SetBackdropColor(.5, .5, .5, .5)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
||||
Details:GameTooltipSetSpellByID (self.spellid)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
local frame_tooltip_onleave = function(self)
|
||||
if (self.spellid) then
|
||||
self:SetBackdropColor(.5, .5, .5, .1)
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
y = y - padding
|
||||
|
||||
for i = 1, 40 do
|
||||
local frame_tooltip = CreateFrame("frame", nil, spellsBox,"BackdropTemplate")
|
||||
frame_tooltip:SetPoint("topleft", spellsBox, "topleft", 5, y + ((i-1)*17)*-1)
|
||||
frame_tooltip:SetSize(spellsBox:GetWidth()-10, 16)
|
||||
frame_tooltip:SetScript("OnEnter", frame_tooltip_onenter)
|
||||
frame_tooltip:SetScript("OnLeave", frame_tooltip_onleave)
|
||||
frame_tooltip:Hide()
|
||||
|
||||
frame_tooltip:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 512})
|
||||
frame_tooltip:SetBackdropColor(.5, .5, .5, .1)
|
||||
|
||||
local icon = frame_tooltip:CreateTexture(nil, "artwork")
|
||||
icon:SetSize(14, 14)
|
||||
icon:SetPoint("left", frame_tooltip, "left")
|
||||
|
||||
local spell = frame_tooltip:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
spell:SetPoint("left", icon, "right", 2, 0)
|
||||
spell:SetText("spell name:") --localize-me
|
||||
spell:SetTextColor(.8, .8, .8, 1)
|
||||
|
||||
local spell_amt = frame_tooltip:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
|
||||
spell_amt:SetPoint("left", spell, "right", 2, 0)
|
||||
spell_amt:SetText("0")
|
||||
|
||||
tab ["spell" .. i] = {spell, spell_amt, icon, frame_tooltip}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local getpercent = function(value, lastvalue, elapsed_time, inverse)
|
||||
local ps = value / elapsed_time
|
||||
local diff
|
||||
|
||||
if (lastvalue == 0) then
|
||||
diff = "+0%"
|
||||
else
|
||||
if (ps >= lastvalue) then
|
||||
local d = ps - lastvalue
|
||||
d = d / lastvalue * 100
|
||||
d = math.floor(math.abs(d))
|
||||
|
||||
if (d > 999) then
|
||||
d = "> 999"
|
||||
end
|
||||
|
||||
if (inverse) then
|
||||
diff = "|c" .. green .. "+" .. d .. "%|r"
|
||||
else
|
||||
diff = "|c" .. red .. "+" .. d .. "%|r"
|
||||
end
|
||||
else
|
||||
local d = lastvalue - ps
|
||||
d = d / math.max(ps, 0.001) * 100
|
||||
d = math.floor(math.abs(d))
|
||||
|
||||
if (d > 999) then
|
||||
d = "> 999"
|
||||
end
|
||||
|
||||
if (inverse) then
|
||||
diff = "|c" .. red .. "-" .. d .. "%|r"
|
||||
else
|
||||
diff = "|c" .. green .. "-" .. d .. "%|r"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ps, diff
|
||||
end
|
||||
|
||||
local avoidance_fill = function(tab, player, combat)
|
||||
local elapsed_time = combat:GetCombatTime()
|
||||
|
||||
local last_combat = combat.previous_combat --this is always nil from 2023 may 26
|
||||
if (not last_combat or not last_combat [1]) then
|
||||
last_combat = combat
|
||||
end
|
||||
|
||||
local last_actor = last_combat (1, player.nome)
|
||||
local n = player.nome
|
||||
if (n:find("-")) then
|
||||
n = n:gsub(("-.*"), "")
|
||||
end
|
||||
|
||||
--damage taken
|
||||
local playerdamage = combat (1, player.nome)
|
||||
|
||||
if (not playerdamage.avoidance) then
|
||||
playerdamage.avoidance = Details:CreateActorAvoidanceTable()
|
||||
end
|
||||
|
||||
local damagetaken = playerdamage.damage_taken
|
||||
local last_damage_received = 0
|
||||
if (last_actor) then
|
||||
last_damage_received = last_actor.damage_taken / last_combat:GetCombatTime()
|
||||
end
|
||||
|
||||
tab.damagereceived:SetText(Details:ToK2 (damagetaken))
|
||||
|
||||
local ps, diff = getpercent (damagetaken, last_damage_received, elapsed_time)
|
||||
tab.damagepersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
|
||||
|
||||
--absorbs
|
||||
local totalabsorbs = playerdamage.avoidance.overall.ABSORB_AMT
|
||||
local incomingtotal = damagetaken + totalabsorbs
|
||||
|
||||
local last_total_absorbs = 0
|
||||
if (last_actor and last_actor.avoidance) then
|
||||
last_total_absorbs = last_actor.avoidance.overall.ABSORB_AMT / last_combat:GetCombatTime()
|
||||
end
|
||||
|
||||
tab.absorbstotal:SetText(Details:ToK2 (totalabsorbs) .. " (" .. math.floor(totalabsorbs / incomingtotal * 100) .. "%)")
|
||||
|
||||
local ps, diff = getpercent (totalabsorbs, last_total_absorbs, elapsed_time, true)
|
||||
tab.absorbstotalpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
|
||||
|
||||
--dodge
|
||||
local totaldodge = playerdamage.avoidance.overall.DODGE
|
||||
tab.dodge:SetText(totaldodge)
|
||||
|
||||
local last_total_dodge = 0
|
||||
if (last_actor and last_actor.avoidance) then
|
||||
last_total_dodge = last_actor.avoidance.overall.DODGE / last_combat:GetCombatTime()
|
||||
end
|
||||
local ps, diff = getpercent (totaldodge, last_total_dodge, elapsed_time, true)
|
||||
tab.dodgepersecond:SetText( string.format("%.2f", ps) .. " (" .. diff .. ")")
|
||||
|
||||
--parry
|
||||
local totalparry = playerdamage.avoidance.overall.PARRY
|
||||
tab.parry:SetText(totalparry)
|
||||
|
||||
local last_total_parry = 0
|
||||
if (last_actor and last_actor.avoidance) then
|
||||
last_total_parry = last_actor.avoidance.overall.PARRY / last_combat:GetCombatTime()
|
||||
end
|
||||
local ps, diff = getpercent (totalparry, last_total_parry, elapsed_time, true)
|
||||
tab.parrypersecond:SetText(string.format("%.2f", ps) .. " (" .. diff .. ")")
|
||||
|
||||
--block
|
||||
local totalblock = playerdamage.avoidance.overall.BLOCKED_HITS
|
||||
tab.block:SetText(totalblock)
|
||||
|
||||
local last_total_block = 0
|
||||
if (last_actor and last_actor.avoidance) then
|
||||
last_total_block = last_actor.avoidance.overall.BLOCKED_HITS / last_combat:GetCombatTime()
|
||||
end
|
||||
local ps, diff = getpercent (totalblock, last_total_block, elapsed_time, true)
|
||||
tab.blockpersecond:SetText(string.format("%.2f", ps) .. " (" .. diff .. ")")
|
||||
|
||||
tab.blockeddamage_amt:SetText(Details:ToK2 (playerdamage.avoidance.overall.BLOCKED_AMT))
|
||||
|
||||
--absorb
|
||||
local fullabsorb = playerdamage.avoidance.overall.FULL_ABSORBED
|
||||
local halfabsorb = playerdamage.avoidance.overall.PARTIAL_ABSORBED
|
||||
local halfabsorb_amt = playerdamage.avoidance.overall.PARTIAL_ABSORB_AMT
|
||||
local noabsorb = playerdamage.avoidance.overall.FULL_HIT
|
||||
|
||||
tab.fullsbsorbed:SetText(fullabsorb)
|
||||
tab.partiallyabsorbed:SetText(halfabsorb)
|
||||
tab.noabsorbs:SetText(noabsorb)
|
||||
|
||||
if (halfabsorb_amt > 0) then
|
||||
local average = halfabsorb_amt / halfabsorb --tenho o average
|
||||
local last_average = 0
|
||||
if (last_actor and last_actor.avoidance and last_actor.avoidance.overall.PARTIAL_ABSORBED > 0) then
|
||||
last_average = last_actor.avoidance.overall.PARTIAL_ABSORB_AMT / last_actor.avoidance.overall.PARTIAL_ABSORBED
|
||||
end
|
||||
|
||||
local ps, diff = getpercent (halfabsorb_amt, last_average, halfabsorb, true)
|
||||
tab.partiallyabsorbedpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
|
||||
else
|
||||
tab.partiallyabsorbedpersecond:SetText("0.00 (0%)")
|
||||
end
|
||||
|
||||
|
||||
|
||||
--healing
|
||||
|
||||
local actor_heal = combat (2, player.nome)
|
||||
if (not actor_heal) then
|
||||
tab.selfhealing:SetText("0")
|
||||
tab.selfhealingpersecond:SetText("0 (0%)")
|
||||
else
|
||||
local last_actor_heal = last_combat (2, player.nome)
|
||||
local este_alvo = actor_heal.targets [player.nome]
|
||||
if (este_alvo) then
|
||||
local heal_total = este_alvo
|
||||
tab.selfhealing:SetText(Details:ToK2 (heal_total))
|
||||
|
||||
if (last_actor_heal) then
|
||||
local este_alvo = last_actor_heal.targets [player.nome]
|
||||
if (este_alvo) then
|
||||
local heal = este_alvo
|
||||
|
||||
local last_heal = heal / last_combat:GetCombatTime()
|
||||
|
||||
local ps, diff = getpercent (heal_total, last_heal, elapsed_time, true)
|
||||
tab.selfhealingpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
|
||||
|
||||
else
|
||||
tab.selfhealingpersecond:SetText("0 (0%)")
|
||||
end
|
||||
else
|
||||
tab.selfhealingpersecond:SetText("0 (0%)")
|
||||
end
|
||||
|
||||
else
|
||||
tab.selfhealing:SetText("0")
|
||||
tab.selfhealingpersecond:SetText("0 (0%)")
|
||||
end
|
||||
|
||||
|
||||
-- taken from healer
|
||||
local heal_from = actor_heal.healing_from
|
||||
local myReceivedHeal = {}
|
||||
|
||||
for actorName, _ in pairs(heal_from) do
|
||||
local thisActor = combat (2, actorName)
|
||||
local targets = thisActor.targets --targets is a container with target classes
|
||||
local amount = targets [player.nome] or 0
|
||||
myReceivedHeal [#myReceivedHeal+1] = {actorName, amount, thisActor.classe}
|
||||
end
|
||||
|
||||
table.sort (myReceivedHeal, Details.Sort2) --Sort2 sort by second index
|
||||
|
||||
for i = 1, 5 do
|
||||
local label1, label2 = unpack(tab ["healer" .. i])
|
||||
if (myReceivedHeal [i]) then
|
||||
local name = myReceivedHeal [i][1]
|
||||
|
||||
name = Details:GetOnlyName(name)
|
||||
--name = Details:RemoveOwnerName (name)
|
||||
|
||||
label1:SetText(name .. ":")
|
||||
local class = myReceivedHeal [i][3]
|
||||
if (class) then
|
||||
local c = _G["RAID_CLASS_COLORS"][class]
|
||||
if (c) then
|
||||
label1:SetTextColor(c.r, c.g, c.b)
|
||||
end
|
||||
else
|
||||
label1:SetTextColor(.8, .8, .8, 1)
|
||||
end
|
||||
|
||||
local last_actor = last_combat (2, myReceivedHeal [i][1])
|
||||
if (last_actor) then
|
||||
local targets = last_actor.targets
|
||||
local amount = targets [player.nome] or 0
|
||||
if (amount) then
|
||||
|
||||
local last_heal = amount
|
||||
|
||||
local ps, diff = getpercent (myReceivedHeal[i][2], last_heal, 1, true)
|
||||
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0) .. " (" .. diff .. ")")
|
||||
|
||||
else
|
||||
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0))
|
||||
end
|
||||
else
|
||||
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0))
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
label1:SetText("-- -- -- --")
|
||||
label1:SetTextColor(.8, .8, .8, 1)
|
||||
label2:SetText("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Spells
|
||||
--cooldowns
|
||||
local index_used = 1
|
||||
local misc_player = combat (4, player.nome)
|
||||
local encounter_time = combat:GetCombatTime()
|
||||
|
||||
if (misc_player) then
|
||||
if (misc_player.cooldowns_defensive_spells) then
|
||||
local minha_tabela = misc_player.cooldowns_defensive_spells._ActorTable
|
||||
local buffUpdateSpells = misc_player.buff_uptime_spells -- ._ActorTable
|
||||
|
||||
local cooldowns_usados = {}
|
||||
|
||||
for _spellid, _tabela in pairs(minha_tabela) do
|
||||
cooldowns_usados [#cooldowns_usados+1] = {_spellid, _tabela.counter}
|
||||
end
|
||||
|
||||
if (#cooldowns_usados > 0) then
|
||||
|
||||
table.sort (cooldowns_usados, Details.Sort2)
|
||||
|
||||
for i = 1, #cooldowns_usados do
|
||||
local esta_habilidade = cooldowns_usados[i]
|
||||
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
|
||||
|
||||
local label1, label2, icon1, framebg = unpack(tab ["spell" .. index_used])
|
||||
framebg.spellid = esta_habilidade[1]
|
||||
framebg:Show()
|
||||
|
||||
--attempt to get the buff update
|
||||
local spellInfo = buffUpdateSpells:GetSpell (framebg.spellid)
|
||||
if (spellInfo) then
|
||||
label2:SetText(esta_habilidade[2] .. " (" .. math.floor(spellInfo.uptime / encounter_time * 100) .. "% uptime)")
|
||||
else
|
||||
label2:SetText(esta_habilidade[2])
|
||||
end
|
||||
|
||||
--update the line
|
||||
label1:SetText(nome_magia .. ":")
|
||||
|
||||
icon1:SetTexture(icone_magia)
|
||||
icon1:SetTexCoord(0.0625, 0.953125, 0.0625, 0.953125)
|
||||
|
||||
index_used = index_used + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cooldownInfo = DetailsFramework.CooldownsInfo
|
||||
|
||||
--see cooldowns that other players used in this actor
|
||||
for playerName, _ in pairs(combat.raid_roster) do
|
||||
if (playerName ~= player.nome) then
|
||||
local miscPlayer = combat (4, playerName)
|
||||
if (miscPlayer) then
|
||||
if (miscPlayer.cooldowns_defensive_spells) then
|
||||
local cooldowns = miscPlayer.cooldowns_defensive_spells
|
||||
for spellID, spellTable in cooldowns:ListActors() do
|
||||
local targets = spellTable.targets
|
||||
if (targets) then
|
||||
for targetName, amountCasted in pairs(targets) do
|
||||
if (targetName == player.nome) then
|
||||
local spellName, _, spellIcon = _GetSpellInfo(spellID)
|
||||
local label1, label2, icon1, framebg = unpack(tab ["spell" .. index_used])
|
||||
framebg.spellid = spellID
|
||||
framebg:Show()
|
||||
|
||||
--attempt to get the buff update
|
||||
local info = cooldownInfo [spellID]
|
||||
local cooldownDuration = info and info.duration or 0
|
||||
|
||||
if (cooldownDuration > 0) then
|
||||
label2:SetText(amountCasted .. " (" .. "|cFFFFFF00" .. miscPlayer.nome .. "|r " .. math.floor(cooldownDuration / encounter_time * 100) .. "% uptime)")
|
||||
else
|
||||
label2:SetText(amountCasted)
|
||||
end
|
||||
|
||||
--update the line
|
||||
label1:SetText(spellName .. ":")
|
||||
|
||||
icon1:SetTexture(spellIcon)
|
||||
icon1:SetTexCoord(0.0625, 0.953125, 0.0625, 0.953125)
|
||||
|
||||
index_used = index_used + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = index_used, 40 do
|
||||
local label1, label2, icon1, framebg = unpack(tab ["spell" .. i])
|
||||
|
||||
framebg.spellid = nil
|
||||
framebg:Hide()
|
||||
label1:SetText("")
|
||||
label2:SetText("")
|
||||
icon1:SetTexture("")
|
||||
end
|
||||
|
||||
--habilidade usada para interromper
|
||||
end
|
||||
|
||||
local iconTableAvoidance = {
|
||||
texture = [[Interface\AddOns\Details\images\icons]],
|
||||
--coords = {363/512, 381/512, 0/512, 17/512},
|
||||
coords = {384/512, 402/512, 19/512, 38/512},
|
||||
width = 16,
|
||||
height = 16,
|
||||
}
|
||||
|
||||
Details:CreatePlayerDetailsTab ("Avoidance", --[1] tab name
|
||||
Loc ["STRING_INFO_TAB_AVOIDANCE"], --[2] localized name
|
||||
function(tabOBject, playerObject) --[3] condition
|
||||
if (playerObject.isTank) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
avoidance_fill, --[4] fill function
|
||||
|
||||
nil, --[5] onclick
|
||||
|
||||
avoidance_create, --[6] oncreate
|
||||
iconTableAvoidance --[7] icon
|
||||
)
|
||||
@@ -0,0 +1,523 @@
|
||||
|
||||
--whenever it say 'CombatID' it is referencing the Details! unique combatId
|
||||
--whenever it say 'SegmentID' it is referencing the internal chart data registered for some details! combat
|
||||
|
||||
local Details = _G.Details
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local addonName, detailsInternal = ...
|
||||
|
||||
local CONST_LATEST_SEGMENT = 1
|
||||
|
||||
local tinsert = table.insert
|
||||
local tremove = table.remove
|
||||
|
||||
local CONST_TICKER_NAME = "ChartDataTicker"
|
||||
local CONST_TICKER_INTERVAL = 3
|
||||
|
||||
--create the chart object
|
||||
detailsInternal.Charts = {}
|
||||
local chartsObject = detailsInternal.Charts
|
||||
|
||||
--store all segments data
|
||||
chartsObject.SegmentsData = {}
|
||||
--current segment being displayed in the charts
|
||||
chartsObject.SegmentOnVisualization = 0
|
||||
|
||||
--this table will hold the saved variable which tells which infomation to get during combat
|
||||
chartsObject.DataToCapture = {}
|
||||
|
||||
function chartsObject.GetConfigToCaptureData()
|
||||
return chartsObject.DataToCapture
|
||||
end
|
||||
|
||||
function chartsObject.SetConfigToCaptureData(configTable)
|
||||
chartsObject.DataToCapture = configTable
|
||||
end
|
||||
|
||||
function chartsObject.GetSavedVariable()
|
||||
return Details.data_harvested_for_charts
|
||||
end
|
||||
|
||||
function chartsObject.StoreChartsForCurrentCombat()
|
||||
local savedVariableTable = chartsObject.GetSavedVariable()
|
||||
|
||||
--Details.data_harvested_for_charts
|
||||
end
|
||||
|
||||
function chartsObject.BuildPlayersTable(playersTable)
|
||||
if (IsInRaid()) then
|
||||
for i = 1, GetNumGroupMembers() do
|
||||
local unitName = GetUnitName("raid" .. i, true)
|
||||
playersTable[unitName] = {}
|
||||
end
|
||||
|
||||
elseif (InIsParty()) then
|
||||
for i = 1, GetNumGroupMembers() - 1 do
|
||||
local unitName = GetUnitName("party" .. i, true)
|
||||
playersTable[unitName] = {}
|
||||
end
|
||||
playersTable[UnitName("player")] = {}
|
||||
else
|
||||
playersTable[UnitName("player")] = {}
|
||||
end
|
||||
end
|
||||
|
||||
function chartsObject.CreateTableToReceiveChartData()
|
||||
local t = {}
|
||||
|
||||
--get the list of players captures
|
||||
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
|
||||
|
||||
--data set to capture data of each individual player
|
||||
local playerCaptures = configsForCaptureData.players
|
||||
--data set to capture data of some combat attribute or totals
|
||||
local combatTotalCaptures = configsForCaptureData.totals
|
||||
|
||||
if (#playerCaptures > 0) then
|
||||
t.players = {}
|
||||
for i = 1, #playerCaptures do
|
||||
local capturePreset = playerCaptures[i]
|
||||
local playersTable = {}
|
||||
t.players[capturePreset.name] = playersTable
|
||||
chartsObject.BuildPlayersTable(playersTable)
|
||||
end
|
||||
end
|
||||
|
||||
if (#combatTotalCaptures > 0) then
|
||||
t.totals = {}
|
||||
for i = 1, #combatTotalCaptures do
|
||||
local capturePreset = combatTotalCaptures[i]
|
||||
t.totals[capturePreset.name] = {}
|
||||
end
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
--function to grab data during combat
|
||||
function chartsObject.Ticker()
|
||||
if (chartsObject.HasValidAndOpenCombat()) then
|
||||
--get Details! combat object
|
||||
local detaisCurrentCombat = Details:GetCurrentCombat()
|
||||
|
||||
--get the list of players captures
|
||||
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
|
||||
|
||||
--data set to capture data of each individual player
|
||||
local playerCaptures = configsForCaptureData.players
|
||||
--data set to capture data of some combat attribute or totals
|
||||
local combatTotalCaptures = configsForCaptureData.totals
|
||||
|
||||
local currentSegmentData = chartsObject.GetCurrentCombatData()
|
||||
local chartData = currentSegmentData.ChartData
|
||||
|
||||
if (#playerCaptures > 0) then
|
||||
--PAREI AQUI, PRECISA PEGAR O CAPTURE NAME, A TABELA COM OS NOMES DOS JOGADORES E PEGAR OS DADOS DO SEGMENTO DO DETAILS!
|
||||
--DEPOIS TEM QUE FECHAR ISSO AQUI E GRAGAR NO SEGMENT DA CHART
|
||||
--DEPOIS FAZER O MENU DE SELECIONAR O SEGMENTO MOSTRAR OS SEGMENTOS DO DETAILS PARA SELECIONAR
|
||||
--POR FIM PROGRAMAR AS CHARTS PRA MOSTRAR OS GRAFICOS
|
||||
for i = 1, #playerCaptures do
|
||||
local capturePreset = playerCaptures[i]
|
||||
local thisCaptureTable = chartData[capturePreset.Name]
|
||||
t.players[capturePreset.name] = playersTable
|
||||
chartsObject.BuildPlayersTable(playersTable)
|
||||
end
|
||||
end
|
||||
|
||||
if (#combatTotalCaptures > 0) then
|
||||
t.totals = {}
|
||||
for i = 1, #combatTotalCaptures do
|
||||
local capturePreset = combatTotalCaptures[i]
|
||||
t.totals[capturePreset.name] = {}
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #playerCaptures do
|
||||
local capturePreset = playerCaptures[i]
|
||||
if (capturePreset.combatObjectSubTable) then
|
||||
local subTable = detaisCurrentCombat[capturePreset.combatObjectSubTableName]
|
||||
local value = subTable[capturePreset.combatObjectSubTableKey]
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[=[]]
|
||||
players = {
|
||||
--damage done by each player
|
||||
{
|
||||
name = "Damage of Each Individual Player",
|
||||
combatObjectContainer = 1,
|
||||
playerOnly = true,
|
||||
playerKey = "total",
|
||||
},
|
||||
|
||||
--total damage done by the raid group
|
||||
{
|
||||
name = "Damage of All Player Combined",
|
||||
combatObjectSubTableName = "totals",
|
||||
combatObjectSubTableKey = 1,
|
||||
},
|
||||
},
|
||||
--]=]
|
||||
|
||||
function chartsObject.GetConfigToDataCaptureFromDetailsOptions()
|
||||
local detailsObject = Details
|
||||
local configTable = detailsObject.data_harvest_for_charsts
|
||||
chartsObject.SetConfigToCaptureData(configTable)
|
||||
end
|
||||
|
||||
function chartsObject.StartCombatDataTicker()
|
||||
detailsInternal.Scheduler.NewTicker(CONST_TICKER_INTERVAL, chartsObject.Ticker, CONST_TICKER_NAME)
|
||||
end
|
||||
|
||||
function chartsObject.StopCombatDataTicker()
|
||||
detailsInternal.Scheduler.Cancel(CONST_TICKER_NAME)
|
||||
end
|
||||
|
||||
--get a segment combat data
|
||||
function chartsObject.GetSegmentsCombatData(combatIndex)
|
||||
return chartsObject.SegmentsData[combatIndex]
|
||||
end
|
||||
|
||||
--get a segment combat data by Details! combatId
|
||||
function chartsObject.GetSegmentCombatDataByDetailsCombatID(detailsCombatId)
|
||||
for i = 1, chartsObject.GetNumSegments() do
|
||||
local thisSegmentCombatData = chartsObject.SegmentsData[i]
|
||||
if (thisSegmentCombatData.detailsCombatID == detailsCombatId) then
|
||||
return thisSegmentCombatData
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--select a combat to make the chart frames show
|
||||
function chartsObject.SelectSegmentDataToShow(segmentId)
|
||||
segmentId = segmentId or CONST_LATEST_SEGMENT
|
||||
local numSegments = chartsObject.GetNumSegments()
|
||||
if (numSegments > 0) then
|
||||
--pre step before calling the function which will signal the frame to update
|
||||
chartsObject.ChartFramesShowSegment(CONST_LATEST_SEGMENT)
|
||||
else
|
||||
chartsObject.ChartFramesClear()
|
||||
end
|
||||
end
|
||||
|
||||
function chartsObject.ChartFramesClear()
|
||||
--pre step before calling the function which will signal the frame to update
|
||||
chartsObject.ChartFramesShowSegment(0)
|
||||
end
|
||||
|
||||
--this function shouldn't be called directly, always call from SelectSegmentDataToShow or ChartFramesClear
|
||||
function chartsObject.ChartFramesShowSegment(segmentId)
|
||||
--set the combat data into the charts
|
||||
chartsObject.SegmentOnVisualization = segmentId
|
||||
--here go into the frames created and call refresh using the segment data
|
||||
|
||||
local segmentCombatData = chartsObject.GetSegmentsCombatData(segmentId)
|
||||
if (segmentCombatData) then
|
||||
--this is the lowest function and will call the frame api to refresh the data
|
||||
else
|
||||
chartsObject.SegmentOnVisualization = 0
|
||||
--this is the lowest function and will call the frame api to refresh the data
|
||||
end
|
||||
end
|
||||
|
||||
--called when Details! reset the data
|
||||
function chartsObject.ResetSegmentData()
|
||||
Details:Destroy(chartsObject.SegmentsData)
|
||||
|
||||
--stop the ticker
|
||||
chartsObject.StopCombatDataTicker()
|
||||
--don't allow anything to be process under the start of a new combat
|
||||
chartsObject.SetCombatState(false)
|
||||
--signal the frames to update and shown no data
|
||||
chartsObject.ChartFramesClear()
|
||||
end
|
||||
|
||||
--set the combat state
|
||||
function chartsObject.SetCombatState(state)
|
||||
chartsObject.InCombat = state
|
||||
end
|
||||
|
||||
function chartsObject.HasValidAndOpenCombat()
|
||||
local bCombatState = chartsObject.GetCombatState()
|
||||
if (bCombatState) then
|
||||
local detaisCurrentCombat = Details:GetCurrentCombat()
|
||||
local chartCurrentSegmentData = chartsObject.GetCurrentCombatData()
|
||||
if (detaisCurrentCombat:GetCombatId() == chartCurrentSegmentData:GetCombatId()) then
|
||||
--it's all good
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--return true if in combat
|
||||
function chartsObject.GetCombatState()
|
||||
return chartsObject.InCombat
|
||||
end
|
||||
|
||||
function chartsObject.RemoveSegmentData(segmentId)
|
||||
tremove(chartsObject.SegmentsData, segmentId)
|
||||
chartsObject.SelectSegmentDataToShow(CONST_LATEST_SEGMENT)
|
||||
end
|
||||
|
||||
function chartsObject.GetNumSegments()
|
||||
return #chartsObject.SegmentsData
|
||||
end
|
||||
|
||||
function chartsObject.GetCurrentCombatData()
|
||||
return chartsObject.segmentData
|
||||
end
|
||||
|
||||
--add the new combatData into the first index
|
||||
local segmentDataMixin = {
|
||||
GetCombatId = function(self)
|
||||
return self.detailsCombatID
|
||||
end,
|
||||
}
|
||||
|
||||
--this is called when the player enter in combat
|
||||
function chartsObject.CreateNewSegmentData(detailsCombatObject)
|
||||
chartsObject.segmentData = {
|
||||
--players Damage for the segment
|
||||
PlayersDamage = {},
|
||||
--players Healing for the segment
|
||||
PlayersHealing = {},
|
||||
--each index is a boss fight
|
||||
BossTryDamage = 0,
|
||||
--blood lust timer
|
||||
BloodLustTimers = {},
|
||||
--combatId
|
||||
detailsCombatID = detailsCombatObject:GetCombatId(),
|
||||
--charts data captured
|
||||
ChartData = chartsObject.CreateTableToReceiveChartData(),
|
||||
}
|
||||
|
||||
detailsFramework:Mixin(chartsObject.segmentData, segmentDataMixin)
|
||||
tinsert(chartsObject.SegmentsData, 1, chartsObject.segmentData)
|
||||
|
||||
chartsObject.GetConfigToDataCaptureFromDetailsOptions()
|
||||
chartsObject.SetCombatState(true)
|
||||
chartsObject.StartCombatDataTicker()
|
||||
|
||||
return chartsObject.segmentData
|
||||
end
|
||||
|
||||
--when a combat is finished, close and store the current combatData
|
||||
function chartsObject.CloseSegmentData(bIsInvalid)
|
||||
--in case a combat_invalid passed by here first
|
||||
if (not chartsObject.GetCombatState()) then
|
||||
return
|
||||
end
|
||||
|
||||
chartsObject.StopCombatDataTicker()
|
||||
chartsObject.SetCombatState(false)
|
||||
|
||||
local currentCombat = chartsObject.GetSegmentsCombatData(1)
|
||||
currentCombat.Done = true
|
||||
|
||||
if (bIsInvalid) then
|
||||
currentCombat.Invalid = true
|
||||
chartsObject.RemoveSegmentData(1)
|
||||
else
|
||||
--check if the window is opened and update the chart current in sight
|
||||
end
|
||||
end
|
||||
|
||||
--Details Events:
|
||||
function chartsObject.OnDetailsEvent(event, ...)
|
||||
if (event == "COMBAT_PLAYER_ENTER") then --> combat started
|
||||
local combatObject = select(1, ...)
|
||||
if (not combatObject and Details) then
|
||||
combatObject = Details:GetCurrentCombat()
|
||||
if (not combatObject) then
|
||||
return
|
||||
end
|
||||
end
|
||||
chartsObject.CreateNewSegmentData(combatObject)
|
||||
|
||||
elseif (event == "COMBAT_PLAYER_LEAVE") then
|
||||
chartsObject.CloseSegmentData()
|
||||
|
||||
elseif (event == "DETAILS_DATA_RESET") then
|
||||
chartsObject.ResetSegmentData()
|
||||
|
||||
elseif (event == "COMBAT_INVALID") then
|
||||
local bIsInvalid = true
|
||||
chartsObject.CloseSegmentData(bIsInvalid)
|
||||
|
||||
elseif (event == "DETAILS_STARTED") then
|
||||
--install the new tab on the Player Breakdown
|
||||
chartsObject.InstallTab()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local eventListener = Details:CreateEventListener()
|
||||
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", chartsObject.OnDetailsEvent)
|
||||
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", chartsObject.OnDetailsEvent)
|
||||
eventListener:RegisterEvent("DETAILS_DATA_RESET", chartsObject.OnDetailsEvent)
|
||||
eventListener:RegisterEvent("COMBAT_INVALID", chartsObject.OnDetailsEvent)
|
||||
eventListener:RegisterEvent("DETAILS_STARTED", chartsObject.OnDetailsEvent)
|
||||
|
||||
function chartsObject.InstallTab()
|
||||
local tabName = "Charts"
|
||||
local tabNameLoc = "Damage Charts"
|
||||
|
||||
local canShowTab = function(tabOBject, playerObject)
|
||||
local combatObject = Details:GetCombatFromBreakdownWindow()
|
||||
if (combatObject) then
|
||||
local chartsCombatData = chartsObject.GetSegmentCombatDataByDetailsCombatID(combatObject:GetCombatId())
|
||||
if (chartsCombatData) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local fillTab = function(tab, playerObject, combat)
|
||||
--update the tab frame with information
|
||||
|
||||
end
|
||||
|
||||
local createdChartsTab = function(tab, frame)
|
||||
chartsObject.CreateChartFrames(tab, frame)
|
||||
end
|
||||
|
||||
local iconSettings = {
|
||||
texture = [[Interface\BUTTONS\UI-GuildButton-OfficerNote-Disabled]],
|
||||
coords = {0, 1, 0, 1},
|
||||
width = 16,
|
||||
height = 16,
|
||||
}
|
||||
|
||||
Details:CreatePlayerDetailsTab(tabName, tabNameLoc, canShowTab, fillTab, nil, createdChartsTab, iconSettings)
|
||||
end
|
||||
|
||||
|
||||
function chartsObject.CreateChartFrames(tab, tabFrame)
|
||||
|
||||
--First Option: each player dps chart on each segment, this show the evolution of damage of each player
|
||||
--Second Option: Total Damage Done by the entire raid comparing with other segments (one line of raid damage per segment)
|
||||
--Thrid Option: your damage compared with other of the same class (chart damage of each player required)
|
||||
--Your habilites compared segment by segment (no chart data required)
|
||||
|
||||
--segment scroll in the left
|
||||
--boss image, boss name,
|
||||
|
||||
--when selecting a boss show the chart for the boss
|
||||
|
||||
local defaultChartSections = {
|
||||
{
|
||||
Name = "Raid Damage",
|
||||
ChartID = 1,
|
||||
ChartData = "alldamagers-segment",
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local scrollWidth = 200
|
||||
local scrollHeight = 500
|
||||
local scrollButtonHeight = 20
|
||||
local amountScrollLines = floor(scrollHeight / scrollButtonHeight)
|
||||
local allLinesCreated = {}
|
||||
local lineSelectedBackdropColor = {.5, .5, .5, .5}
|
||||
|
||||
local onClickLine_SelectChartToView = function(button, mouseButton)
|
||||
for buttonId, line in ipairs(allLinesCreated) do
|
||||
line:SetDefaultBackdropColor()
|
||||
end
|
||||
end
|
||||
|
||||
local lineMixin = {
|
||||
SetDefaultBackdropColor = function(line)
|
||||
line.__background:SetVertexColor(unpack(line.defaultBackgroundColor))
|
||||
end,
|
||||
|
||||
SetSelectedBackdropColor = function(line)
|
||||
line.__background:SetVertexColor(unpack(lineSelectedBackdropColor))
|
||||
end,
|
||||
|
||||
OnClickLine = function(line)
|
||||
--select the chart to view
|
||||
end,
|
||||
}
|
||||
|
||||
--function to create a line in the scroll frame
|
||||
local createScrollLine = function(self, index)
|
||||
--create a new line
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
||||
detailsFramework:Mixin(line, lineMixin)
|
||||
|
||||
--set its parameters
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((index-1) * (scrollButtonHeight+1)) - 1)
|
||||
line:SetSize(scrollWidth-19, scrollButtonHeight)
|
||||
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
|
||||
|
||||
line:SetScript("OnClick", line.OnClickLine)
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(line)
|
||||
line.defaultBackgroundColor = {line.__background:GetVertexColor()}
|
||||
|
||||
local icon = line:CreateTexture("$parentSpecIcon", "artwork")
|
||||
icon:SetSize(scrollButtonHeight, scrollButtonHeight)
|
||||
icon:SetAlpha(0.71)
|
||||
|
||||
local chartData = defaultChartSections[index]
|
||||
local chartName = detailsFramework:CreateLabel(line, chartData.Name, 11, "white", "GameFontNormal")
|
||||
|
||||
icon:SetPoint("left", line, "left", 0, 0)
|
||||
chartName:SetPoint("topleft", icon, "topright", 2, -3)
|
||||
|
||||
line.Icon = icon
|
||||
line.ChartName = chartName
|
||||
return line
|
||||
end
|
||||
|
||||
local refreshScroll = function(self, data, offset, totalLines)
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local chartData = data[index]
|
||||
if (chartData) then
|
||||
local line = self:GetLine(i)
|
||||
line.ChartID = chartData.ChartID
|
||||
line.ChartData = chartData.ChartData
|
||||
line.ChartName.text = chartData.Name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Create the scrollbox showing the selection for charts
|
||||
local chartSelectionScrollBox = detailsFramework:CreateScrollBox(
|
||||
tabFrame,
|
||||
"$parentChartSelectionScroll",
|
||||
refreshScroll,
|
||||
{},
|
||||
scrollWidth,
|
||||
scrollHeight,
|
||||
amountScrollLines,
|
||||
scrollButtonHeight
|
||||
)
|
||||
|
||||
detailsFramework:ReskinSlider(chartSelectionScrollBox)
|
||||
chartSelectionScrollBox.ScrollBar:ClearAllPoints()
|
||||
chartSelectionScrollBox.ScrollBar:SetPoint("topright", chartSelectionScrollBox, "topright", -2, -17)
|
||||
chartSelectionScrollBox.ScrollBar:SetPoint("bottomright", chartSelectionScrollBox, "bottomright", -2, 17)
|
||||
chartSelectionScrollBox:SetPoint("topright", tabFrame, "topleft", -1, 0)
|
||||
chartSelectionScrollBox:SetPoint("bottomright", tabFrame, "bottomleft", -1, 0)
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(chartSelectionScrollBox)
|
||||
|
||||
tabFrame.chartSelectionScrollBox = chartSelectionScrollBox
|
||||
|
||||
--create the scrollbox lines
|
||||
for i = 1, amountScrollLines do
|
||||
chartSelectionScrollBox:CreateLine(createScrollLine)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,772 @@
|
||||
|
||||
--this file controls the left panel of the breakdown window, where the player list and plugins are shown
|
||||
---@type details
|
||||
local Details = _G.Details
|
||||
|
||||
---@class detailsframework
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
|
||||
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
|
||||
local addonName, Details222 = ...
|
||||
|
||||
local breakdownWindowPlayerList = {}
|
||||
|
||||
local unpack = table.unpack or unpack
|
||||
local C_Timer = _G.C_Timer
|
||||
local tinsert = table.insert
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpecializationInfoByID = GetSpecializationInfoByID
|
||||
local PixelUtil = PixelUtil
|
||||
|
||||
local scrollbox_size = {215, 405}
|
||||
local scrollbox_lines = 20
|
||||
local player_line_height = 20
|
||||
local scrollbox_line_backdrop_color = {0.2, 0.2, 0.2, 0.5}
|
||||
local scrollbox_line_backdrop_color_selected = {1, 1, 0, 0.45}
|
||||
local scrollbox_line_backdrop_color_highlight = {.9, .9, .9, 0.5}
|
||||
local player_scroll_size = {195, 288}
|
||||
|
||||
---@type table<uniquecombatid, actorname>
|
||||
local lastSelectedPlayerPerSegment = {}
|
||||
|
||||
---@type actorname
|
||||
local lastSelectedPlayerName = ""
|
||||
|
||||
local onPlayerSelected = function(breakdownWindowFrame, playerObject)
|
||||
---@type instance
|
||||
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
||||
Details:OpenBreakdownWindow(instanceObject, playerObject, false, true)
|
||||
|
||||
--cache the latest selected player for this combat
|
||||
---@type combat
|
||||
local combatObject = instanceObject:GetCombat()
|
||||
---@type actorname
|
||||
local playerName = playerObject:Name()
|
||||
|
||||
lastSelectedPlayerPerSegment[combatObject:GetCombatUID()] = playerName
|
||||
lastSelectedPlayerName = playerName
|
||||
|
||||
breakdownWindowFrame.playerScrollBox:Refresh()
|
||||
end
|
||||
|
||||
local getActorToShowInBreakdownWindow = function(combatObject)
|
||||
---@type breakdownwindow
|
||||
local breakdownWindowFrame = Details.BreakdownWindowFrame
|
||||
|
||||
--when the select is selected, figure out which player need to be selected in the playerScroll
|
||||
---@type instance
|
||||
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
||||
---@type uniquecombatid
|
||||
local combatUID = combatObject:GetCombatUID()
|
||||
|
||||
local displayId, subDisplayId = instanceObject:GetDisplay()
|
||||
|
||||
---@type actorname
|
||||
local playerName = lastSelectedPlayerPerSegment[combatUID]
|
||||
|
||||
if (playerName) then
|
||||
---@type actor
|
||||
local playerObject = combatObject:GetActor(displayId, playerName)
|
||||
return playerObject
|
||||
else
|
||||
---@type actor
|
||||
local playerObject = combatObject:GetActor(displayId, lastSelectedPlayerName)
|
||||
if (playerObject) then
|
||||
lastSelectedPlayerPerSegment[combatUID] = playerObject:Name()
|
||||
return playerObject
|
||||
else
|
||||
playerObject = combatObject:GetActor(displayId, Details.playername)
|
||||
if (playerObject) then
|
||||
lastSelectedPlayerPerSegment[combatUID] = playerObject:Name()
|
||||
return playerObject
|
||||
end
|
||||
|
||||
--get the top player from the combat display and subDisplay and select it
|
||||
---@type actor
|
||||
local actorObject = instanceObject:GetActorBySubDisplayAndRank(displayId, subDisplayId, 1)
|
||||
if (actorObject) then
|
||||
lastSelectedPlayerPerSegment[combatUID] = actorObject:Name()
|
||||
return actorObject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---this function get the list of active plugins which has a frame to show in the breakdown window and create a button for each one
|
||||
---@param breakdownWindowFrame breakdownwindow
|
||||
---@param pluginsFrame frame
|
||||
---@param breakdownSideMenu frame
|
||||
---@return number height how much space pluginsFrame is using
|
||||
local refreshPluginButtons = function(breakdownWindowFrame, pluginsFrame, breakdownSideMenu)
|
||||
local amountPluginButtons = #breakdownWindowFrame.RegisteredPluginButtons
|
||||
local pluginButtonHeight = 20
|
||||
local spacingBetweenButtons = 1
|
||||
local totalHeight = 0
|
||||
|
||||
for i = 1, amountPluginButtons do
|
||||
---@type button
|
||||
local pluginButton = breakdownWindowFrame.RegisteredPluginButtons[i]
|
||||
pluginButton:Show()
|
||||
PixelUtil.SetSize(pluginButton, pluginsFrame:GetWidth() - 4, pluginButtonHeight)
|
||||
pluginButton:ClearAllPoints()
|
||||
|
||||
if (i == 1) then
|
||||
PixelUtil.SetPoint(pluginButton, "topleft", pluginsFrame, "topleft", 2, -22)
|
||||
else
|
||||
PixelUtil.SetPoint(pluginButton, "topleft", breakdownWindowFrame.RegisteredPluginButtons[i - 1], "bottomleft", 0, -spacingBetweenButtons)
|
||||
end
|
||||
|
||||
local fontString = _G[pluginButton:GetName() .. "_Text"]
|
||||
Details222.BreakdownWindow.ApplyFontSettings(fontString)
|
||||
|
||||
totalHeight = totalHeight + pluginButtonHeight + spacingBetweenButtons
|
||||
end
|
||||
|
||||
--add the height of the header and the spacing between the header and the first button and the last button and the bottom of the frame
|
||||
totalHeight = totalHeight + 20 + 2
|
||||
|
||||
pluginsFrame:SetPoint("topleft", breakdownSideMenu, "topleft", 0, 0)
|
||||
pluginsFrame:SetWidth(breakdownSideMenu:GetWidth())
|
||||
pluginsFrame:SetHeight(amountPluginButtons * pluginButtonHeight + 22 + (amountPluginButtons * 1))
|
||||
|
||||
return totalHeight
|
||||
end
|
||||
|
||||
local createPlayerScrollBox = function(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
||||
local refreshPlayerScrollFunc = function(self, data, offset, totalLines)
|
||||
local topResult = data[1]
|
||||
if (topResult) then
|
||||
topResult = topResult.total
|
||||
end
|
||||
|
||||
---@type combat
|
||||
local combatObject = Details:GetCombatFromBreakdownWindow()
|
||||
local encounterId = combatObject:GetEncounterCleuID()
|
||||
local difficultyId = combatObject:GetDifficulty()
|
||||
|
||||
for i = 1, totalLines do --~refresh
|
||||
local index = i + offset
|
||||
local playerObject = data[index]
|
||||
if (playerObject) then
|
||||
local line = self:GetLine(i)
|
||||
if (line) then
|
||||
line.playerObject = playerObject
|
||||
line.combatObject = combatObject
|
||||
line.index = index
|
||||
line:UpdateLine(topResult, encounterId, difficultyId)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnClick = function(self)
|
||||
if (self.playerObject ~= Details:GetActorObjectFromBreakdownWindow() or breakdownWindowFrame.shownPluginObject) then
|
||||
onPlayerSelected(breakdownWindowFrame, self.playerObject)
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnEnter = function(self)
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_highlight))
|
||||
self.specIcon:SetBlendMode("ADD")
|
||||
self.roleIcon:SetBlendMode("ADD")
|
||||
end
|
||||
|
||||
local lineOnLeave = function(self)
|
||||
if (self.isSelected) then
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
||||
else
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
end
|
||||
self.specIcon:SetBlendMode("BLEND")
|
||||
self.roleIcon:SetBlendMode("BLEND")
|
||||
end
|
||||
|
||||
local updatePlayerLine = function(self, topResult, encounterId, difficultyId) --~update
|
||||
local playerSelected = lastSelectedPlayerName
|
||||
if (playerSelected == self.playerObject:Name()) then
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
||||
self.isSelected = true
|
||||
else
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
self.isSelected = nil
|
||||
end
|
||||
|
||||
local specRole
|
||||
|
||||
--adjust the player icon
|
||||
if (self.playerObject.spellicon) then
|
||||
self.specIcon:SetTexture(self.playerObject.spellicon)
|
||||
self.specIcon:SetTexCoord(.1, .9, .1, .9)
|
||||
else
|
||||
local specIcon, L, R, T, B = Details:GetSpecIcon(self.playerObject.spec, false)
|
||||
|
||||
if (specIcon) then
|
||||
self.specIcon:SetTexture(specIcon)
|
||||
self.specIcon:SetTexCoord(L, R, T, B)
|
||||
|
||||
specRole = "NONE"
|
||||
else
|
||||
self.specIcon:SetTexture("")
|
||||
end
|
||||
end
|
||||
|
||||
--adjust the role icon
|
||||
if (specRole) then
|
||||
local roleIcon, L, R, T, B = Details:GetRoleIcon(specRole)
|
||||
if (roleIcon) then
|
||||
self.roleIcon:SetTexture(roleIcon)
|
||||
self.roleIcon:SetTexCoord(L, R, T, B)
|
||||
else
|
||||
self.roleIcon:SetTexture("")
|
||||
end
|
||||
else
|
||||
self.roleIcon:SetTexture("")
|
||||
end
|
||||
|
||||
local playerGear = openRaidLib and openRaidLib.GetUnitGear(self.playerObject.nome)
|
||||
|
||||
--do not show the role icon
|
||||
self.roleIcon:SetTexture("") --not in use
|
||||
|
||||
--set the player name
|
||||
self.playerName:SetText(Details:GetOnlyName(self.playerObject.nome))
|
||||
self.rankText:SetText(self.index) --not in use
|
||||
|
||||
--item level
|
||||
local itemLevel = Details.ilevel:GetIlvl(self.playerObject.serial)
|
||||
self.itemLevelText:SetText((itemLevel and itemLevel.ilvl and math.floor(itemLevel.ilvl)) or (self.playerObject.ilvl) or (playerGear and playerGear.ilevel) or "0")
|
||||
|
||||
local actorSpecId = self.playerObject.spec
|
||||
local actorTotal = self.playerObject.total
|
||||
local combatObject = self.combatObject
|
||||
|
||||
-- we dont have warcraft logs or any percentile stuff.
|
||||
self.percentileText:SetText("N/A")
|
||||
self.percentileText:SetAlpha(0.25)
|
||||
|
||||
Details222.BreakdownWindow.ApplyFontSettings(self.playerName)
|
||||
Details222.BreakdownWindow.ApplyFontSettings(self.itemLevelText)
|
||||
Details222.BreakdownWindow.ApplyFontSettings(self.percentileText)
|
||||
|
||||
Details222.BreakdownWindow.ApplyTextureSettings(self.totalStatusBar)
|
||||
|
||||
--set the statusbar
|
||||
local r, g, b = self.playerObject:GetClassColor()
|
||||
self.totalStatusBar:SetStatusBarColor(r, g, b, 1)
|
||||
self.totalStatusBar:SetMinMaxValues(0, topResult)
|
||||
self.totalStatusBar:SetValue(actorTotal)
|
||||
end
|
||||
|
||||
--get a Details! window
|
||||
local lowerInstanceId = Details:GetLowerInstanceNumber()
|
||||
local fontFile
|
||||
local fontSize
|
||||
local fontOutline
|
||||
|
||||
--header setup
|
||||
local headerTable = {
|
||||
{text = "", width = 20},
|
||||
{text = "Player Name", width = 100},
|
||||
{text = "iLvL", width = 30},
|
||||
{text = "WCL Parse", width = 60},
|
||||
}
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
if (lowerInstanceId) then
|
||||
local instance = Details:GetInstance(lowerInstanceId)
|
||||
if (instance) then
|
||||
fontFile = instance.row_info.font_face
|
||||
fontSize = instance.row_info.font_size
|
||||
fontOutline = instance.row_info.textL_outline
|
||||
end
|
||||
end
|
||||
|
||||
local createPlayerLine = function(self, index)
|
||||
--create a new line
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
||||
detailsFramework:SetTemplate(line, "STANDARD_GRAY")
|
||||
|
||||
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||||
|
||||
---@type frame
|
||||
local OTTFrame = CreateFrame("frame", nil, line)
|
||||
OTTFrame:SetFrameLevel(line:GetFrameLevel()+2)
|
||||
OTTFrame:SetAllPoints()
|
||||
line.OTTFrame = OTTFrame
|
||||
|
||||
PixelUtil.SetPoint(line, "topleft", breakdownWindowFrame.PlayerSelectionHeader, "topleft", 1, -((index) * (player_line_height+1)))
|
||||
PixelUtil.SetSize(line, scrollbox_size[1]-2, player_line_height)
|
||||
|
||||
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
|
||||
line:SetScript("OnEnter", lineOnEnter)
|
||||
line:SetScript("OnLeave", lineOnLeave)
|
||||
line:SetScript("OnClick", lineOnClick)
|
||||
|
||||
local specIcon = OTTFrame:CreateTexture("$parentSpecIcon", "artwork")
|
||||
specIcon:SetSize(headerTable[1].width - 1, headerTable[1].width - 1)
|
||||
specIcon:SetAlpha(0.834)
|
||||
|
||||
local roleIcon = OTTFrame:CreateTexture("$parentRoleIcon", "overlay")
|
||||
roleIcon:SetSize((player_line_height-2) / 2, (player_line_height-2) / 2)
|
||||
roleIcon:SetAlpha(0.71)
|
||||
|
||||
local playerName = OTTFrame:CreateFontString("$parentPlayerName", "artwork", "GameFontNormal")
|
||||
playerName:SetTextColor(1, 1, 1, .9)
|
||||
|
||||
local className = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
||||
className.textcolor = {.95, .8, .2, 0}
|
||||
className.textsize = 9
|
||||
|
||||
local itemLevelText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
||||
itemLevelText.textcolor = {1, 1, 1, .7}
|
||||
itemLevelText.textsize = 11
|
||||
|
||||
local percentileText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
||||
percentileText.textcolor = {1, 1, 1, .7}
|
||||
percentileText.textsize = 11
|
||||
|
||||
local rankText = detailsFramework:CreateLabel(OTTFrame, "", "GameFontNormal")
|
||||
rankText.textcolor = {.3, .3, .3, .7}
|
||||
rankText.textsize = fontSize
|
||||
|
||||
local totalStatusBar = CreateFrame("statusbar", nil, line)
|
||||
totalStatusBar:SetSize(scrollbox_size[1]-player_line_height, player_line_height)
|
||||
totalStatusBar:SetMinMaxValues(0, 100)
|
||||
totalStatusBar:SetFrameLevel(line:GetFrameLevel()+1)
|
||||
totalStatusBar:SetAlpha(0.5)
|
||||
totalStatusBar:SetPoint("bottomleft", specIcon, "bottomright", 0, 0)
|
||||
|
||||
local gradientTexture = DetailsFramework:CreateTexture(OTTFrame, {gradient = "horizontal", fromColor = {.1, .1, .1, .634}, toColor = "transparent"}, 100, 1, "border", {0, 1, 0, 1}, "segmentsGradient")
|
||||
gradientTexture:SetPoint("lefts")
|
||||
|
||||
line.specIcon = specIcon
|
||||
line.roleIcon = roleIcon
|
||||
line.playerName = playerName
|
||||
line.className = className
|
||||
line.rankText = rankText
|
||||
line.totalStatusBar = totalStatusBar
|
||||
line.itemLevelText = itemLevelText
|
||||
line.percentileText = percentileText
|
||||
|
||||
line:AddFrameToHeaderAlignment(specIcon)
|
||||
line:AddFrameToHeaderAlignment(playerName)
|
||||
line:AddFrameToHeaderAlignment(itemLevelText)
|
||||
line:AddFrameToHeaderAlignment(percentileText)
|
||||
|
||||
line:AlignWithHeader(breakdownWindowFrame.PlayerSelectionHeader, "left")
|
||||
|
||||
line.UpdateLine = updatePlayerLine
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
---@type width
|
||||
local width = player_scroll_size[1] + 22
|
||||
---@type height
|
||||
local height = player_scroll_size[2]
|
||||
|
||||
local playerScroll = detailsFramework:CreateScrollBox(breakdownSideMenu, "DetailsBreakdownWindowPlayerScrollBox", refreshPlayerScrollFunc, {}, width, height, scrollbox_lines, player_line_height)
|
||||
detailsFramework:ReskinSlider(playerScroll)
|
||||
playerScroll.ScrollBar:ClearAllPoints()
|
||||
playerScroll.ScrollBar:SetPoint("topright", playerScroll, "topright", -2, -37)
|
||||
playerScroll.ScrollBar:SetPoint("bottomright", playerScroll, "bottomright", -2, 17)
|
||||
breakdownWindowFrame.playerScrollBox = playerScroll
|
||||
playerScroll.ScrollBar:Hide()
|
||||
|
||||
--remove the standard backdrop
|
||||
playerScroll:SetBackdrop({})
|
||||
playerScroll:SetBackdropColor(0, 0, 0, 0)
|
||||
playerScroll:SetBackdropBorderColor(0, 0, 0, 0)
|
||||
playerScroll.__background:Hide()
|
||||
|
||||
--create the header frame for the player scrollbox selection
|
||||
---@type df_headerframe
|
||||
breakdownWindowFrame.PlayerSelectionHeader = DetailsFramework:CreateHeader(playerScroll, headerTable, headerOptions)
|
||||
breakdownWindowFrame.PlayerSelectionHeader:SetAlpha(0.823)
|
||||
breakdownWindowFrame.PlayerSelectionHeader:SetPoint("topleft", playerSelectionHeaderFrame, "bottomleft", 0, -2)
|
||||
breakdownWindowFrame.PlayerSelectionHeader:SetPoint("topright", playerSelectionHeaderFrame, "bottomright", 0, -2)
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(breakdownWindowFrame.PlayerSelectionHeader)
|
||||
breakdownWindowFrame.PlayerSelectionHeader.__background:SetTexture(.60, .60, .60)
|
||||
|
||||
--create the scrollbox lines
|
||||
for i = 1, scrollbox_lines do
|
||||
playerScroll:CreateLine(createPlayerLine)
|
||||
end
|
||||
|
||||
return playerScroll
|
||||
end
|
||||
|
||||
local createSegmentsScrollBox = function(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
||||
local refreshSegmentsScrollFunc = function(self, data, offset, totalLines)
|
||||
for lineIndex = 1, totalLines do --~refresh
|
||||
local index = lineIndex + offset
|
||||
---@type breakdownsegmentdata
|
||||
local segmentData = data[index]
|
||||
if (segmentData) then
|
||||
---@type breakdownsegmentline
|
||||
local line = self:GetLine(lineIndex)
|
||||
if (line) then
|
||||
line:UpdateLine(lineIndex, segmentData)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnClick = function(self)
|
||||
--unique combat id from the button clicked
|
||||
local combatUniqueID = self.combatUniqueID
|
||||
if (not Details:DoesCombatWithUIDExists(combatUniqueID)) then
|
||||
Details:Msg("This segment is not available anymore.")
|
||||
return
|
||||
end
|
||||
|
||||
--current breakdown combat
|
||||
local currentBKCombat = Details:GetCombatFromBreakdownWindow()
|
||||
--unique combat id from the combat the breakdown window is using
|
||||
local currentBKCombatUniqueID = currentBKCombat:GetCombatUID()
|
||||
|
||||
if (combatUniqueID ~= currentBKCombatUniqueID) then
|
||||
local newCombatToShowInBreakdownWindow = Details:GetCombatByUID(combatUniqueID)
|
||||
if (newCombatToShowInBreakdownWindow) then
|
||||
---@cast newCombatToShowInBreakdownWindow combat
|
||||
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
||||
--set the segment of the instance to be the segment just selected by the user
|
||||
instanceObject:SetSegment(newCombatToShowInBreakdownWindow:GetSegmentSlotId())
|
||||
|
||||
local bFromAttributeChange = false
|
||||
local bIsRefresh = true
|
||||
|
||||
local actor = getActorToShowInBreakdownWindow(newCombatToShowInBreakdownWindow)
|
||||
if (actor) then
|
||||
Details:OpenBreakdownWindow(instanceObject, actor, bFromAttributeChange, bIsRefresh)
|
||||
else
|
||||
local actorObject = Details:GetActorObjectFromBreakdownWindow()
|
||||
lastSelectedPlayerPerSegment[combatUniqueID] = actorObject:Name()
|
||||
Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttributeChange, bIsRefresh)
|
||||
end
|
||||
|
||||
breakdownWindowFrame.segmentScrollBox:Refresh()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnEnter = function(self)
|
||||
if (not self.isSelected) then
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_highlight))
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnLeave = function(self)
|
||||
if (not self.isSelected) then
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
end
|
||||
end
|
||||
|
||||
---update the segment line from the segments scrollbox
|
||||
---@param self breakdownsegmentline
|
||||
---@param index number
|
||||
---@param segmentData breakdownsegmentdata
|
||||
local updateSegmentLine = function(self, index, segmentData) --~update
|
||||
local combatName = segmentData.combatName
|
||||
local r, g, b = segmentData.r, segmentData.g, segmentData.b
|
||||
local combatIcon1 = segmentData.combatIcon
|
||||
|
||||
self.segmentText:SetText(combatName)
|
||||
Details222.BreakdownWindow.ApplyFontSettings(self.segmentText)
|
||||
|
||||
self.segmentText:SetTextColor(r, g, b)
|
||||
detailsFramework:TruncateText(self.segmentText, player_scroll_size[1] - 20)
|
||||
|
||||
local bUseAtlasSize = true
|
||||
detailsFramework:SetAtlas(self.segmentIcon, combatIcon1, bUseAtlasSize)
|
||||
|
||||
self.combatUniqueID = segmentData.UID
|
||||
|
||||
local combatSelected = Details:GetCombatFromBreakdownWindow()
|
||||
if (combatSelected and combatSelected:GetCombatUID() == segmentData.UID) then
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
|
||||
self.isSelected = true
|
||||
else
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
self.isSelected = false
|
||||
end
|
||||
end
|
||||
|
||||
--header setup
|
||||
local headerTable = {
|
||||
{text = "Segment Name", width = 100},
|
||||
}
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
local createSegmentLine = function(self, index)
|
||||
--create a new line
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
|
||||
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||||
detailsFramework:SetTemplate(line, "STANDARD_GRAY")
|
||||
|
||||
PixelUtil.SetPoint(line, "topleft", self, "topleft", 1, -((index-1) * (player_line_height+1)))
|
||||
PixelUtil.SetSize(line, scrollbox_size[1]-2, player_line_height)
|
||||
|
||||
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
|
||||
line:SetScript("OnEnter", lineOnEnter)
|
||||
line:SetScript("OnLeave", lineOnLeave)
|
||||
line:SetScript("OnClick", lineOnClick)
|
||||
|
||||
--segment icon, this icon will tell which type of segment the line is
|
||||
---@type df_image
|
||||
local segmentIcon = detailsFramework:CreateTexture(line, "", player_line_height, player_line_height - 1, "artwork")
|
||||
segmentIcon:SetSize(player_line_height - 4, player_line_height - 4)
|
||||
segmentIcon:SetAlpha(0.834)
|
||||
|
||||
local segmentText = line:CreateFontString("$parentSegmentName", "artwork", "GameFontNormal")
|
||||
line.segmentText = segmentText
|
||||
line.segmentIcon = segmentIcon
|
||||
|
||||
--create a texture gradient in horizontal with the left side starting from black and the right side ending in transparent, the width is 40 and is placed at the left side of the line
|
||||
local gradientTexture = DetailsFramework:CreateTexture(line, {gradient = "horizontal", fromColor = {.1, .1, .1, .634}, toColor = "transparent"}, 100, 1, "border", {0, 1, 0, 1}, "segmentsGradient")
|
||||
gradientTexture:SetPoint("lefts")
|
||||
|
||||
segmentIcon:SetPoint("left", line, "left", 2, 0)
|
||||
segmentText:SetPoint("left", segmentIcon.widget, "right", 5, 0)
|
||||
|
||||
line.UpdateLine = updateSegmentLine
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
---@type width
|
||||
local width = player_scroll_size[1] + 22
|
||||
---@type height
|
||||
local height = player_scroll_size[2]
|
||||
|
||||
local segmentsScroll = detailsFramework:CreateScrollBox(breakdownSideMenu, "DetailsBreakdownWindowSegmentsScrollBox", refreshSegmentsScrollFunc, {}, width, height, scrollbox_lines, player_line_height)
|
||||
detailsFramework:ReskinSlider(segmentsScroll)
|
||||
|
||||
segmentsScroll.ScrollBar:ClearAllPoints()
|
||||
segmentsScroll.ScrollBar:SetPoint("topright", segmentsScroll, "topright", -2, -37)
|
||||
segmentsScroll.ScrollBar:SetPoint("bottomright", segmentsScroll, "bottomright", -2, 17)
|
||||
segmentsScroll.ScrollBar:Hide()
|
||||
|
||||
breakdownWindowFrame.segmentScrollBox = segmentsScroll
|
||||
|
||||
--remove the standard backdrop
|
||||
segmentsScroll:SetBackdrop(nil)
|
||||
segmentsScroll.__background:Hide()
|
||||
|
||||
--create the scrollbox lines
|
||||
for i = 1, scrollbox_lines do
|
||||
segmentsScroll:CreateLine(createSegmentLine)
|
||||
end
|
||||
|
||||
return segmentsScroll
|
||||
end
|
||||
|
||||
function breakdownWindowPlayerList.CreatePlayerListFrame()
|
||||
---@type breakdownwindow
|
||||
local breakdownWindowFrame = Details.BreakdownWindowFrame
|
||||
---@type frame
|
||||
local breakdownSideMenu = breakdownWindowFrame.BreakdownSideMenuFrame
|
||||
---@type frame
|
||||
local pluginsFrame = breakdownWindowFrame.BreakdownPluginSelectionFrame
|
||||
|
||||
breakdownSideMenu:SetSize(scrollbox_size[1], scrollbox_size[2])
|
||||
PixelUtil.SetPoint(breakdownSideMenu, "topright", breakdownWindowFrame, "topleft", -2, 0)
|
||||
PixelUtil.SetPoint(breakdownSideMenu, "bottomright", breakdownWindowFrame, "bottomleft", -2, 0)
|
||||
|
||||
--> create headers
|
||||
local sectionHeaderHeight = 20
|
||||
--plugins header frame
|
||||
local pluginHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
||||
PixelUtil.SetPoint(pluginHeaderFrame, "topleft", breakdownSideMenu, "topleft", 2, -0)
|
||||
PixelUtil.SetPoint(pluginHeaderFrame, "topright", breakdownSideMenu, "topright", -2, -0)
|
||||
pluginHeaderFrame:SetHeight(sectionHeaderHeight)
|
||||
--plugins header label
|
||||
local titleBarPlugins_TitleLabel = detailsFramework:CreateLabel(pluginHeaderFrame, "Plugins", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "pluginsLabel", nil, "overlay")
|
||||
PixelUtil.SetPoint(titleBarPlugins_TitleLabel, "center", pluginHeaderFrame , "center", 0, 0)
|
||||
PixelUtil.SetPoint(titleBarPlugins_TitleLabel, "top", pluginHeaderFrame , "top", 0, -5)
|
||||
|
||||
--player selection header frame
|
||||
local playerSelectionHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
||||
playerSelectionHeaderFrame:SetHeight(sectionHeaderHeight)
|
||||
playerSelectionHeaderFrame:SetPoint("topleft", pluginsFrame, "bottomleft", 0, -1)
|
||||
playerSelectionHeaderFrame:SetPoint("topright", pluginsFrame, "bottomright", 0, -1)
|
||||
--player selection header label
|
||||
--converting from detailsFramework:NewLabel to detailsFramework:CreateLabel
|
||||
--local titleBarTools_TitleLabel = detailsFramework:NewLabel(titleBarPlayerSeparator, titleBarPlayerSeparator, nil, "titulo", "Players", "GameFontHighlightLeft", 12, {227/255, 186/255, 4/255})
|
||||
local titleBarTools_TitleLabel = detailsFramework:CreateLabel(playerSelectionHeaderFrame, "Select Player", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "playersLabel", nil, "overlay")
|
||||
PixelUtil.SetPoint(titleBarTools_TitleLabel, "center", playerSelectionHeaderFrame , "center", 0, 0)
|
||||
PixelUtil.SetPoint(titleBarTools_TitleLabel, "top", playerSelectionHeaderFrame , "top", 0, -5)
|
||||
|
||||
--segment selection header frame
|
||||
local segmentSelectionHeaderFrame = CreateFrame("frame", nil, breakdownSideMenu, "BackdropTemplate")
|
||||
segmentSelectionHeaderFrame:SetHeight(sectionHeaderHeight)
|
||||
--segment selection header label
|
||||
local titleBarSegment_TitleLabel = detailsFramework:CreateLabel(segmentSelectionHeaderFrame, "Select Segment", 12, "DETAILS_HEADER_YELLOW", "GameFontHighlightLeft", "segmentsLabel", nil, "overlay")
|
||||
PixelUtil.SetPoint(titleBarSegment_TitleLabel, "center", segmentSelectionHeaderFrame , "center", 0, 0)
|
||||
PixelUtil.SetPoint(titleBarSegment_TitleLabel, "top", segmentSelectionHeaderFrame , "top", 0, -5)
|
||||
|
||||
local playerScroll = createPlayerScrollBox(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
||||
playerScroll:SetPoint("topleft", breakdownWindowFrame.PlayerSelectionHeader, "bottomleft", 0, -2)
|
||||
playerScroll:SetPoint("topright", breakdownWindowFrame.PlayerSelectionHeader, "bottomright", 0, -2)
|
||||
|
||||
local segmentsScroll = createSegmentsScrollBox(breakdownWindowFrame, breakdownSideMenu, playerSelectionHeaderFrame)
|
||||
segmentsScroll:SetPoint("topleft", playerScroll, "bottomleft", 0, -20)
|
||||
segmentsScroll:SetPoint("topright", playerScroll, "bottomright", 0, -20)
|
||||
|
||||
PixelUtil.SetPoint(segmentSelectionHeaderFrame, "topleft", playerScroll, "bottomleft", 0, -1)
|
||||
PixelUtil.SetPoint(segmentSelectionHeaderFrame, "topright", playerScroll, "bottomright", 0, -1)
|
||||
|
||||
local classIds = detailsFramework.ClassFileNameToIndex
|
||||
|
||||
---get the player list from the segment and build a table compatible with the scroll box
|
||||
---@return actor[]
|
||||
function breakdownWindowPlayerList.BuildPlayerList()
|
||||
---@type combat
|
||||
local combatObject = Details:GetCombatFromBreakdownWindow()
|
||||
---@type {key1: actor, key2: number, key3: number}[]
|
||||
local playerTable = {}
|
||||
|
||||
if (combatObject) then
|
||||
local displayType = Details:GetDisplayTypeFromBreakdownWindow()
|
||||
local containerType = displayType == 1 and DETAILS_ATTRIBUTE_DAMAGE or DETAILS_ATTRIBUTE_HEAL
|
||||
---@type actorcontainer
|
||||
local actorContainer = combatObject:GetContainer(containerType)
|
||||
|
||||
for index, actorObject in actorContainer:ListActors() do
|
||||
---@cast actorObject actor
|
||||
if (actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then
|
||||
local unitClassID = classIds[actorObject:Class()] or 13
|
||||
local unitName = actorObject:Name()
|
||||
--actor position calculation: if two actors has the same amount of a total number, the sort function would flip they around, so we need to add a unique number to the position based on the class and the two first letters of the name
|
||||
local playerPosition = (((unitClassID or 0) + 128) ^ 4) + tonumber(string.byte(unitName, 1) .. "" .. string.byte(unitName, 2))
|
||||
|
||||
---@type {key1: actor, key2: number, key3: number}
|
||||
local data = {actorObject, playerPosition, actorObject.total}
|
||||
tinsert(playerTable, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(playerTable, detailsFramework.SortOrder3)
|
||||
|
||||
---@type actor[]
|
||||
local resultTable = {}
|
||||
for i = 1, #playerTable do
|
||||
---@type actor
|
||||
local actor = playerTable[i][1]
|
||||
resultTable[#resultTable+1] = actor
|
||||
end
|
||||
|
||||
return resultTable
|
||||
end
|
||||
|
||||
local updatePlayerAndSegmentsList = function()
|
||||
--the left menu side has 620 pixels of height
|
||||
|
||||
--when updating the player list, update the plugin buttons as well for convenience
|
||||
--the refreshPluginButtons function returns the height occupied by the pluginsFrame
|
||||
--this height is then used to set the amount of lines the player and segments scroll frames will show
|
||||
local heightOccupied = refreshPluginButtons(breakdownWindowFrame, pluginsFrame, breakdownSideMenu)
|
||||
|
||||
--the height of the player and segments scroll is determined by the height of the pluginsFrame, by the amount of players needed to be shown and the amount of segments needed to be shown
|
||||
--calculate the height "free" to use for both scrolls
|
||||
local heightFree = breakdownSideMenu:GetHeight() - heightOccupied
|
||||
--the -60 is the space used by the player and segments labels, plus the player scroll header
|
||||
--the -5 is the space between the player and segments scroll
|
||||
heightFree = heightFree - 60 - 5
|
||||
|
||||
---@type actor[]
|
||||
local playerList = breakdownWindowPlayerList.BuildPlayerList()
|
||||
|
||||
local amountOfLines = math.floor(heightFree / player_line_height)
|
||||
|
||||
local linesForPlayerScroll = math.floor(amountOfLines/2)
|
||||
if (linesForPlayerScroll < 5) then
|
||||
linesForPlayerScroll = 5
|
||||
elseif (linesForPlayerScroll > 10) then
|
||||
linesForPlayerScroll = 10
|
||||
end
|
||||
|
||||
local selectedPlayerName = Details:GetActorObjectFromBreakdownWindow():Name()
|
||||
lastSelectedPlayerPerSegment[Details:GetCombatFromBreakdownWindow():GetCombatUID()] = selectedPlayerName
|
||||
lastSelectedPlayerName = selectedPlayerName
|
||||
|
||||
local playerLineHeight = player_line_height+1 --the +1 is the space between the lines
|
||||
|
||||
--recalculate the height free, now that we know the amount of lines the player scroll will show
|
||||
heightFree = heightFree - (linesForPlayerScroll * playerLineHeight)
|
||||
local linesForSegmentsScroll = math.floor(heightFree/playerLineHeight)
|
||||
|
||||
playerScroll:SetNumFramesShown(linesForPlayerScroll) --looks like it is not updating the 'totalLines' at the refresh function
|
||||
playerScroll:SetHeight(linesForPlayerScroll * playerLineHeight)
|
||||
|
||||
segmentsScroll:SetNumFramesShown(linesForSegmentsScroll)
|
||||
segmentsScroll:SetHeight(linesForSegmentsScroll * playerLineHeight)
|
||||
|
||||
playerScroll:SetData(playerList)
|
||||
playerScroll:Refresh()
|
||||
playerScroll:Show()
|
||||
|
||||
---@type breakdownsegmentdata[]
|
||||
local segmentsData = {}
|
||||
|
||||
---@type combat[]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
for i = 1, #segmentsTable do
|
||||
---@type combat
|
||||
local combatObject = segmentsTable[i]
|
||||
|
||||
---@type uniquecombatid
|
||||
local UID = combatObject:GetCombatUID()
|
||||
|
||||
local combatName, r, g, b = combatObject:GetCombatName(true)
|
||||
local combatIcon, categoryIcon = combatObject:GetCombatIcon()
|
||||
|
||||
segmentsData[i] = {
|
||||
UID = UID,
|
||||
combatName = combatName,
|
||||
combatIcon = combatIcon,
|
||||
r = r or 1,
|
||||
g = g or 1,
|
||||
b = b or 1,
|
||||
}
|
||||
end
|
||||
|
||||
segmentsScroll:SetData(segmentsData)
|
||||
segmentsScroll:Refresh()
|
||||
segmentsScroll:Show()
|
||||
end
|
||||
|
||||
function Details:UpdateBreakdownPlayerList()
|
||||
--run the update on the next tick
|
||||
C_Timer.After(0, updatePlayerAndSegmentsList)
|
||||
end
|
||||
|
||||
breakdownWindowFrame:HookScript("OnShow", function()
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
end)
|
||||
|
||||
breakdownWindowFrame:HookScript("OnHide", function()
|
||||
for lineIndex, line in ipairs(breakdownWindowFrame.playerScrollBox:GetLines()) do
|
||||
line.playerObject = nil
|
||||
line.combatObject = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Details.PlayerBreakdown.CreatePlayerListFrame()
|
||||
if (not Details.PlayerBreakdown.playerListFrameCreated) then
|
||||
breakdownWindowPlayerList.CreatePlayerListFrame()
|
||||
Details.PlayerBreakdown.playerListFrameCreated = true
|
||||
end
|
||||
end
|
||||
|
||||
function Details222.BreakdownWindow.RefreshScrolls()
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,378 @@
|
||||
|
||||
local Details = Details
|
||||
|
||||
---@type detailsframework
|
||||
local DF = DetailsFramework
|
||||
|
||||
--create the main frame for the options panel
|
||||
|
||||
local createOptionsPanel = function()
|
||||
local startX = 5
|
||||
local startY = -32
|
||||
local heightSize = 540
|
||||
|
||||
local DetailsSpellBreakdownTab = DetailsSpellBreakdownTab
|
||||
local UIParent = UIParent
|
||||
|
||||
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
local optionsFrame = DF:CreateSimplePanel(UIParent, 550, 500, "Details! Breakdown Options", "DetailsSpellBreakdownOptionsPanel")
|
||||
optionsFrame:SetFrameStrata("DIALOG")
|
||||
optionsFrame:SetPoint("topleft", UIParent, "topleft", 2, -40)
|
||||
optionsFrame.Title:SetParent(optionsFrame)
|
||||
optionsFrame.TitleBar:Hide()
|
||||
optionsFrame:Show()
|
||||
|
||||
--remove the backdrop
|
||||
optionsFrame:SetBackdrop(nil)
|
||||
|
||||
--apply rounded corners with the breakdown window preset
|
||||
DF:AddRoundedCornersToFrame(optionsFrame, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
|
||||
local closeButton = DF:CreateCloseButton(optionsFrame, "$parentTopRightCloseButton")
|
||||
closeButton:SetPoint("topright", optionsFrame, "topright", -5, -5)
|
||||
|
||||
Details:RefreshWindowColor()
|
||||
|
||||
local resetSettings = function()
|
||||
--overwrite the settings for the spell frame
|
||||
for key, value in pairs (Details.default_global_data.breakdown_spell_tab) do
|
||||
if (type(value) == "table") then
|
||||
local t = DF.table.copy({}, value)
|
||||
Details.breakdown_spell_tab[key] = t
|
||||
else
|
||||
Details.breakdown_spell_tab[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
--overwrite the settings for the general frame
|
||||
for key, value in pairs (Details.default_global_data.breakdown_general) do
|
||||
if (type(value) == "table") then
|
||||
local t = DF.table.copy({}, value)
|
||||
Details.breakdown_general[key] = t
|
||||
else
|
||||
Details.breakdown_general[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
|
||||
local actorObject = Details:GetActorObjectFromBreakdownWindow()
|
||||
local bFromAttributeChange = true
|
||||
local bIsRefresh = true
|
||||
local bIsShiftKeyDown = false
|
||||
local bIsControlKeyDown = false
|
||||
|
||||
Details:CloseBreakdownWindow()
|
||||
Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttributeChange, bIsRefresh, bIsShiftKeyDown, bIsControlKeyDown)
|
||||
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
|
||||
DetailsSpellBreakdownTab.UpdateShownSpellBlock()
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
|
||||
|
||||
Details:Msg("Settings reseted to default.")
|
||||
end
|
||||
|
||||
local resetSettingsButton = DF:CreateButton(optionsFrame, resetSettings, 130, 20, "Reset Settings")
|
||||
resetSettingsButton:SetPoint("bottomleft", optionsFrame, "bottomleft", 5, 5)
|
||||
resetSettingsButton:SetTemplate(options_button_template)
|
||||
|
||||
local subSectionTitleTextTemplate = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")
|
||||
|
||||
local optionsTable = {
|
||||
{type = "label", get = function() return "General Settings" end, text_template = subSectionTitleTextTemplate},
|
||||
--background color from setting Details.frame_background_color
|
||||
{ --background color
|
||||
type = "color",
|
||||
get = function()
|
||||
local colorTable = Details.frame_background_color
|
||||
return colorTable[1], colorTable[2], colorTable[3], colorTable[4]
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local colorTable = Details.frame_background_color
|
||||
|
||||
--/run Details.frame_background_color = {0.1215, 0.1176, 0.1294, 0.934}
|
||||
|
||||
r = math.min(r, 0.1215)
|
||||
g = math.min(g, 0.1176)
|
||||
b = math.min(b, 0.1294)
|
||||
a = math.min(a, 0.934)
|
||||
|
||||
colorTable[1] = r
|
||||
colorTable[2] = g
|
||||
colorTable[3] = b
|
||||
colorTable[4] = a
|
||||
Details:SetWindowColor(r, g, b, a)
|
||||
end,
|
||||
name = "Background Color",
|
||||
desc = "Background Color",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{type = "label", get = function() return "Spell Details Block" end, text_template = subSectionTitleTextTemplate},
|
||||
{--block height
|
||||
type = "range",
|
||||
get = function() return Details.breakdown_spell_tab.blockspell_height end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.blockspell_height = value
|
||||
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
|
||||
end,
|
||||
min = 50,
|
||||
max = 80,
|
||||
step = 1,
|
||||
name = "Block Height",
|
||||
desc = "Block Height",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{type = "label", get = function() return "What to Show" end, text_template = subSectionTitleTextTemplate},
|
||||
{ --per second
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Per Second",
|
||||
desc = "Per Second",
|
||||
},
|
||||
|
||||
{ --amount of casts
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Casts",
|
||||
desc = "Casts",
|
||||
},
|
||||
|
||||
{ --critical hits percent
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Critical Hits Percent",
|
||||
desc = "Critical Hits Percent",
|
||||
},
|
||||
|
||||
{ --amount of hits
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Hits Amount",
|
||||
desc = "Hits Amount",
|
||||
},
|
||||
|
||||
{ --average damage of healing per cast amount
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Cast Average",
|
||||
desc = "Cast Average",
|
||||
},
|
||||
|
||||
{ --debuff uptime
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Uptime",
|
||||
desc = "Uptime",
|
||||
},
|
||||
|
||||
{ --overheal
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Overheal",
|
||||
desc = "Overheal",
|
||||
},
|
||||
|
||||
{ --absorbed
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled = value
|
||||
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
|
||||
end,
|
||||
name = "Heal Absorbed",
|
||||
desc = "Heal Absorbed",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{type = "label", get = function() return "Text Options" end, text_template = subSectionTitleTextTemplate},
|
||||
{ --font color
|
||||
type = "color",
|
||||
get = function() return Details.breakdown_general.font_color[1], Details.breakdown_general.font_color[2], Details.breakdown_general.font_color[3], Details.breakdown_general.font_color[4] end,
|
||||
set = function(self, r, g, b, a)
|
||||
local colorTable = Details.breakdown_general.font_color
|
||||
colorTable[1] = r
|
||||
colorTable[2] = g
|
||||
colorTable[3] = b
|
||||
colorTable[4] = a
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
DetailsAllAttributesFrame:UpdateFontStrings()
|
||||
end,
|
||||
name = "Text Color",
|
||||
desc = "Text Color",
|
||||
},
|
||||
|
||||
{ --font size
|
||||
type = "range",
|
||||
get = function() return Details.breakdown_general.font_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_general.font_size = value
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
DetailsAllAttributesFrame:UpdateFontStrings()
|
||||
end,
|
||||
min = 8,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Text Size",
|
||||
desc = "Text Size",
|
||||
},
|
||||
|
||||
{ --font outline
|
||||
type = "outlinedropdown",
|
||||
get = function() return Details.breakdown_general.font_outline end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_general.font_outline = value
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
DetailsAllAttributesFrame:UpdateFontStrings()
|
||||
end,
|
||||
name = "Text Outline",
|
||||
desc = "Text Outline",
|
||||
},
|
||||
|
||||
{---font face
|
||||
type = "fontdropdown",
|
||||
get = function() return Details.breakdown_general.font_face end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_general.font_face = value
|
||||
Details:UpdateBreakdownPlayerList()
|
||||
DetailsAllAttributesFrame:UpdateFontStrings()
|
||||
end,
|
||||
name = "Font Face",
|
||||
desc = "Font Face",
|
||||
include_default = true,
|
||||
},
|
||||
|
||||
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Scroll Options" end, text_template = subSectionTitleTextTemplate},
|
||||
|
||||
{ --locked
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.spellcontainer_islocked end,
|
||||
set = function(self, fixedparam, value)
|
||||
---@type df_framecontainer
|
||||
local container = DetailsSpellBreakdownTab.GetSpellScrollContainer()
|
||||
container:SetResizeLocked(value)
|
||||
|
||||
local container = DetailsSpellBreakdownTab.GetTargetScrollContainer()
|
||||
container:SetResizeLocked(value)
|
||||
end,
|
||||
name = "Is Locked",
|
||||
desc = "Is Locked",
|
||||
},
|
||||
|
||||
{--background alpha
|
||||
type = "range",
|
||||
get = function() return Details.breakdown_spell_tab.spellbar_background_alpha end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.spellbar_background_alpha = value
|
||||
DetailsSpellBreakdownTab.GetSpellScrollFrame():Refresh()
|
||||
end,
|
||||
min = 0,
|
||||
max = 1,
|
||||
step = 0.1,
|
||||
usedecimals = true,
|
||||
name = "Background Alpha",
|
||||
desc = "Background Alpha",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
{type = "label", get = function() return "Group Player Spells:" end, text_template = subSectionTitleTextTemplate},
|
||||
{ --nest player spells | merge player spells
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.nest_players_spells_with_same_name end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.nest_players_spells_with_same_name = value
|
||||
end,
|
||||
name = "Group Player Spells With Same Name",
|
||||
desc = "Group spells casted by players which has the same name",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
{type = "label", get = function() return "Group Pet Spells:" end, text_template = subSectionTitleTextTemplate},
|
||||
|
||||
{ --nest pet spells with the same name
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.nest_pet_spells_by_name end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.nest_pet_spells_by_name = value
|
||||
end,
|
||||
name = "Group Pet Names Under a Pet Spell Bar",
|
||||
desc = "Group Pets By Name",
|
||||
hooks = {["OnSwitch"] = function()
|
||||
if (Details.breakdown_spell_tab.nest_pet_spells_by_name) then
|
||||
Details.breakdown_spell_tab.nest_pet_spells_by_caster = false
|
||||
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
|
||||
end
|
||||
end}
|
||||
},
|
||||
|
||||
{ --nest pet spells with the same name
|
||||
type = "toggle",
|
||||
get = function() return Details.breakdown_spell_tab.nest_pet_spells_by_caster end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.breakdown_spell_tab.nest_pet_spells_by_caster = value
|
||||
|
||||
end,
|
||||
name = "Group Pet Spells Under a Pet Name Bar",
|
||||
desc = "Group Pets By Spell",
|
||||
hooks = {["OnSwitch"] = function()
|
||||
if (Details.breakdown_spell_tab.nest_pet_spells_by_caster) then
|
||||
Details.breakdown_spell_tab.nest_pet_spells_by_name = false
|
||||
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
|
||||
end
|
||||
end}
|
||||
},
|
||||
}
|
||||
|
||||
--build the menu
|
||||
optionsTable.always_boxfirst = true
|
||||
DF:BuildMenu(optionsFrame, optionsTable, startX, startY, heightSize, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
end
|
||||
|
||||
|
||||
function Details.OpenSpellBreakdownOptions()
|
||||
if (DetailsSpellBreakdownOptionsPanel) then
|
||||
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
|
||||
DetailsSpellBreakdownOptionsPanel:Show()
|
||||
return
|
||||
end
|
||||
|
||||
createOptionsPanel()
|
||||
end
|
||||
@@ -0,0 +1,221 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
local tabIndex = 11
|
||||
|
||||
function Details:OpenBrokerTextEditor()
|
||||
|
||||
if (not DetailsWindowOptionsBrokerTextEditor) then
|
||||
|
||||
local panel = Details:CreateWelcomePanel("DetailsWindowOptionsBrokerTextEditor", nil, 870, 300, true)
|
||||
panel:SetPoint("center", UIParent, "center")
|
||||
panel:Hide()
|
||||
panel:SetFrameStrata("FULLSCREEN")
|
||||
DF:ApplyStandardBackdrop(panel)
|
||||
|
||||
local titleBar = DF:CreateTitleBar (panel, "Broker Text Editor")
|
||||
|
||||
local textentry = DF:NewSpecialLuaEditorEntry(panel, 650, 270, "editbox", "$parentEntry", true)
|
||||
textentry:SetPoint("topleft", panel, "topleft", 2, -25)
|
||||
|
||||
DF:ApplyStandardBackdrop(textentry)
|
||||
DF:ReskinSlider(textentry.scroll)
|
||||
|
||||
textentry.editbox:SetScript("OnTextChanged", function()
|
||||
local text = panel.editbox:GetText()
|
||||
Details.data_broker_text = text
|
||||
Details:BrokerTick()
|
||||
if (_G.DetailsOptionsWindow) then
|
||||
local dataBrokerString = _G["DetailsOptionsWindowTab" .. tabIndex].widget_list_by_type.textentry[1]
|
||||
dataBrokerString:SetText(Details.data_broker_text)
|
||||
end
|
||||
end)
|
||||
|
||||
local option_selected = 1
|
||||
local onclick= function(_, _, value)
|
||||
option_selected = value
|
||||
end
|
||||
local AddOptions = {
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD1"], value = 1, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD2"], value = 2, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD3"], value = 3, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD4"], value = 4, onclick = onclick},
|
||||
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD5"], value = 5, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD6"], value = 6, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD7"], value = 7, onclick = onclick},
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD8"], value = 8, onclick = onclick},
|
||||
|
||||
{label = Loc ["STRING_OPTIONS_DATABROKER_TEXT_ADD9"], value = 9, onclick = onclick},
|
||||
}
|
||||
local buildAddMenu = function()
|
||||
return AddOptions
|
||||
end
|
||||
|
||||
local d = DF:NewDropDown (panel, _, "$parentTextOptionsDropdown", "TextOptionsDropdown", 150, 20, buildAddMenu, 1)
|
||||
d:SetPoint("topright", panel, "topright", -12, -25)
|
||||
d:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
local optiontable = {"{dmg}", "{dps}", "{dpos}", "{ddiff}", "{heal}", "{hps}", "{hpos}", "{hdiff}", "{time}"}
|
||||
|
||||
local add_button = DF:NewButton(panel, nil, "$parentAddButton", nil, 20, 20, function()
|
||||
textentry.editbox:Insert (optiontable [option_selected])
|
||||
end,
|
||||
nil, nil, nil, "<-")
|
||||
add_button:SetPoint("right", d, "left", -2, 0)
|
||||
add_button:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
|
||||
-- code author Saiket from http://www.wowinterface.com/forums/showpost.php?p=245759&postcount=6
|
||||
--- @return StartPos, EndPos of highlight in this editbox.
|
||||
local function GetTextHighlight ( self )
|
||||
local Text, Cursor = self:GetText(), self:GetCursorPosition();
|
||||
self:Insert( "" ); -- Delete selected text
|
||||
local TextNew, CursorNew = self:GetText(), self:GetCursorPosition();
|
||||
-- Restore previous text
|
||||
self:SetText( Text );
|
||||
self:SetCursorPosition( Cursor );
|
||||
local Start, End = CursorNew, #Text - ( #TextNew - CursorNew );
|
||||
self:HighlightText( Start, End );
|
||||
return Start, End;
|
||||
end
|
||||
|
||||
local StripColors;
|
||||
do
|
||||
local CursorPosition, CursorDelta;
|
||||
--- Callback for gsub to remove unescaped codes.
|
||||
local function StripCodeGsub ( Escapes, Code, End )
|
||||
if ( #Escapes % 2 == 0 ) then -- Doesn't escape Code
|
||||
if ( CursorPosition and CursorPosition >= End - 1 ) then
|
||||
CursorDelta = CursorDelta - #Code;
|
||||
end
|
||||
return Escapes;
|
||||
end
|
||||
end
|
||||
--- Removes a single escape sequence.
|
||||
local function StripCode ( Pattern, Text, OldCursor )
|
||||
CursorPosition, CursorDelta = OldCursor, 0;
|
||||
return Text:gsub( Pattern, StripCodeGsub ), OldCursor and CursorPosition + CursorDelta;
|
||||
end
|
||||
--- Strips Text of all color escape sequences.
|
||||
-- @param Cursor Optional cursor position to keep track of.
|
||||
-- @return Stripped text, and the updated cursor position if Cursor was given.
|
||||
function StripColors ( Text, Cursor )
|
||||
Text, Cursor = StripCode( "(|*)(|c%x%x%x%x%x%x%x%x)()", Text, Cursor );
|
||||
return StripCode( "(|*)(|r)()", Text, Cursor );
|
||||
end
|
||||
end
|
||||
|
||||
local COLOR_END = "|r";
|
||||
--- Wraps this editbox's selected text with the given color.
|
||||
local function ColorSelection ( self, ColorCode )
|
||||
local Start, End = GetTextHighlight( self );
|
||||
local Text, Cursor = self:GetText(), self:GetCursorPosition();
|
||||
if ( Start == End ) then -- Nothing selected
|
||||
--Start, End = Cursor, Cursor; -- Wrap around cursor
|
||||
return; -- Wrapping the cursor in a color code and hitting backspace crashes the client!
|
||||
end
|
||||
-- Find active color code at the end of the selection
|
||||
local ActiveColor;
|
||||
if ( End < #Text ) then -- There is text to color after the selection
|
||||
local ActiveEnd;
|
||||
local CodeEnd, _, Escapes, Color = 0;
|
||||
while ( true ) do
|
||||
_, CodeEnd, Escapes, Color = Text:find( "(|*)(|c%x%x%x%x%x%x%x%x)", CodeEnd + 1 );
|
||||
if ( not CodeEnd or CodeEnd > End ) then
|
||||
break;
|
||||
end
|
||||
if ( #Escapes % 2 == 0 ) then -- Doesn't escape Code
|
||||
ActiveColor, ActiveEnd = Color, CodeEnd;
|
||||
end
|
||||
end
|
||||
|
||||
if ( ActiveColor ) then
|
||||
-- Check if color gets terminated before selection ends
|
||||
CodeEnd = 0;
|
||||
while ( true ) do
|
||||
_, CodeEnd, Escapes = Text:find( "(|*)|r", CodeEnd + 1 );
|
||||
if ( not CodeEnd or CodeEnd > End ) then
|
||||
break;
|
||||
end
|
||||
if ( CodeEnd > ActiveEnd and #Escapes % 2 == 0 ) then -- Terminates ActiveColor
|
||||
ActiveColor = nil;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Selection = Text:sub( Start + 1, End );
|
||||
-- Remove color codes from the selection
|
||||
local Replacement, CursorReplacement = StripColors( Selection, Cursor - Start );
|
||||
|
||||
self:SetText( ( "" ):join(
|
||||
Text:sub( 1, Start ),
|
||||
ColorCode, Replacement, COLOR_END,
|
||||
ActiveColor or "", Text:sub( End + 1 )
|
||||
) );
|
||||
|
||||
-- Restore cursor and highlight, adjusting for wrapper text
|
||||
Cursor = Start + CursorReplacement;
|
||||
if ( CursorReplacement > 0 ) then -- Cursor beyond start of color code
|
||||
Cursor = Cursor + #ColorCode;
|
||||
end
|
||||
if ( CursorReplacement >= #Replacement ) then -- Cursor beyond end of color
|
||||
Cursor = Cursor + #COLOR_END;
|
||||
end
|
||||
|
||||
self:SetCursorPosition( Cursor );
|
||||
-- Highlight selection and wrapper
|
||||
self:HighlightText( Start, #ColorCode + ( #Replacement - #Selection ) + #COLOR_END + End );
|
||||
end
|
||||
|
||||
local color_func = function(_, r, g, b, a)
|
||||
local hex = Details:hex (a*255)..Details:hex (r*255)..Details:hex (g*255)..Details:hex (b*255)
|
||||
ColorSelection ( textentry.editbox, "|c" .. hex)
|
||||
end
|
||||
|
||||
local color_button = DF:NewColorPickButton (panel, "$parentButton5", nil, color_func)
|
||||
color_button:SetSize(80, 20)
|
||||
color_button:SetPoint("topright", panel, "topright", -12, -102)
|
||||
color_button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_COLOR_TOOLTIP"]
|
||||
color_button:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
local done = function()
|
||||
local text = panel.editbox:GetText()
|
||||
Details.data_broker_text = text
|
||||
if (_G.DetailsOptionsWindow) then
|
||||
local dataBrokerString = _G["DetailsOptionsWindowTab" .. tabIndex].widget_list_by_type.textentry[1]
|
||||
dataBrokerString:SetText(Details.data_broker_text)
|
||||
end
|
||||
Details:BrokerTick()
|
||||
panel:Hide()
|
||||
end
|
||||
|
||||
local ok_button = DF:NewButton(panel, nil, "$parentButtonOk", nil, 80, 20, done, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_DONE"], 1)
|
||||
ok_button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_DONE_TOOLTIP"]
|
||||
ok_button:SetPoint("topright", panel, "topright", -12, -174)
|
||||
ok_button:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
local reset_button = DF:NewButton(panel, nil, "$parentDefaultOk", nil, 80, 20, function() textentry.editbox:SetText("") end, nil, nil, nil, "Reset", 1)
|
||||
reset_button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_RESET_TOOLTIP"]
|
||||
reset_button:SetPoint("topright", panel, "topright", -100, -152)
|
||||
reset_button:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
local cancel_button = DF:NewButton(panel, nil, "$parentDefaultCancel", nil, 80, 20, function() textentry.editbox:SetText(panel.default_text); done(); end, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_CANCEL"], 1)
|
||||
cancel_button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_CANCEL_TOOLTIP"]
|
||||
cancel_button:SetPoint("topright", panel, "topright", -100, -174)
|
||||
cancel_button:SetTemplate(DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
end
|
||||
|
||||
local panel = DetailsWindowOptionsBrokerTextEditor
|
||||
|
||||
local text = Details.data_broker_text:gsub("||", "|")
|
||||
panel.default_text = text
|
||||
panel.editbox:SetText(text)
|
||||
|
||||
panel:Show()
|
||||
end
|
||||
@@ -0,0 +1,911 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
|
||||
local addonName, Details222 = ...
|
||||
|
||||
--a cooldownFrame is the frame which holds cooldownLines
|
||||
--cooldownFrame has a key where the value is a table with all cooldownLines created for the frame. The key is called "bars"
|
||||
|
||||
--namespace
|
||||
Details222.CooldownTracking = {
|
||||
--a cooldown panel is a frame that shows the cooldowns of a specific filter type
|
||||
--this table store all frames created to show cooldowns
|
||||
--frames are created for filter types (example: all cooldowns, only player cooldowns, only raid cooldowns, etc)
|
||||
--the key on the table is the filter name and the value is the frame object
|
||||
cooldownPanels = {},
|
||||
}
|
||||
|
||||
local GetSpellTexture = C_Spell and C_Spell.GetSpellTexture or GetSpellTexture
|
||||
|
||||
function Details222.CooldownTracking.IsCooldownIgnored(spellId)
|
||||
return Details.ocd_tracker.ignored_cooldowns[spellId]
|
||||
end
|
||||
|
||||
--return a hash table with all cooldown panels created
|
||||
function Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
return Details222.CooldownTracking.cooldownPanels
|
||||
end
|
||||
|
||||
--return a hash table with all cooldown panels created
|
||||
function Details222.CooldownTracking.GetCooldownFrame(filterName)
|
||||
return Details222.CooldownTracking.cooldownPanels[filterName]
|
||||
end
|
||||
|
||||
--hide all bars created
|
||||
function Details222.CooldownTracking.HideAllBars(filterName)
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
local cooldownFrame = allCooldownFrames[filterName]
|
||||
|
||||
for _, cooldownLine in ipairs(cooldownFrame.bars) do
|
||||
cooldownLine:ClearAllPoints()
|
||||
cooldownLine:Hide()
|
||||
|
||||
cooldownLine.cooldownInfo = nil
|
||||
cooldownLine.spellId = nil
|
||||
cooldownLine.class = nil
|
||||
cooldownLine.unitName = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Details222.CooldownTracking.HideAllLines(cooldownFrame)
|
||||
for _, cooldownLine in ipairs(cooldownFrame.bars) do
|
||||
cooldownLine:ClearAllPoints()
|
||||
cooldownLine:Hide()
|
||||
cooldownLine.cooldownInfo = nil
|
||||
cooldownLine.spellId = nil
|
||||
cooldownLine.class = nil
|
||||
cooldownLine.unitName = nil
|
||||
end
|
||||
end
|
||||
|
||||
--get or create a cooldownLine
|
||||
function Details222.CooldownTracking.GetOrCreateNewCooldownLine(cooldownFrame, lineId)
|
||||
local cooldownLine = cooldownFrame.bars[lineId]
|
||||
|
||||
if (cooldownLine) then
|
||||
return cooldownLine
|
||||
else
|
||||
cooldownLine = DF:CreateTimeBar(cooldownFrame, [[Interface\AddOns\Details\images\bar_serenity]], Details.ocd_tracker.width-2, Details.ocd_tracker.height-2, 100, nil, cooldownFrame:GetName() .. "CDFrame" .. lineId)
|
||||
table.insert(cooldownFrame.bars, cooldownLine)
|
||||
cooldownLine:EnableMouse(false)
|
||||
return cooldownLine
|
||||
end
|
||||
end
|
||||
|
||||
--return truen if the cooldown tracker is enabled
|
||||
function Details222.CooldownTracking.IsEnabled()
|
||||
return Details.ocd_tracker.enabled
|
||||
end
|
||||
|
||||
--enable the cooldown tracker
|
||||
function Details222.CooldownTracking.EnableTracker()
|
||||
if (not Details.ocd_tracker.show_options) then
|
||||
return
|
||||
end
|
||||
|
||||
Details.ocd_tracker.enabled = true
|
||||
|
||||
--register callbacks with the openRaidLib
|
||||
openRaidLib.RegisterCallback(Details222.CooldownTracking, "CooldownListUpdate", "OnReceiveUnitFullCooldownList")
|
||||
openRaidLib.RegisterCallback(Details222.CooldownTracking, "CooldownUpdate", "OnReceiveSingleCooldownUpdate")
|
||||
openRaidLib.RegisterCallback(Details222.CooldownTracking, "CooldownListWipe", "OnCooldownListWipe")
|
||||
openRaidLib.RegisterCallback(Details222.CooldownTracking, "CooldownAdded", "OnCooldownAdded")
|
||||
openRaidLib.RegisterCallback(Details222.CooldownTracking, "CooldownRemoved", "OnCooldownRemoved")
|
||||
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
|
||||
--disable the cooldown tracker
|
||||
function Details222.CooldownTracking.DisableTracker()
|
||||
Details.ocd_tracker.enabled = false
|
||||
|
||||
--hide the panel
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
|
||||
for filterName, cooldownFrame in pairs(allCooldownFrames) do
|
||||
cooldownFrame:Hide()
|
||||
end
|
||||
|
||||
--unregister callbacks
|
||||
openRaidLib.UnregisterCallback(Details222.CooldownTracking, "CooldownListUpdate", "OnReceiveUnitFullCooldownList")
|
||||
openRaidLib.UnregisterCallback(Details222.CooldownTracking, "CooldownUpdate", "OnReceiveSingleCooldownUpdate")
|
||||
openRaidLib.UnregisterCallback(Details222.CooldownTracking, "CooldownListWipe", "OnCooldownListWipe")
|
||||
end
|
||||
|
||||
|
||||
--Library Open Raid Callbacks
|
||||
--callback on the event 'CooldownListUpdate', this is triggered when a player in the group sent the list of cooldowns
|
||||
--@unitId: which unit got updated
|
||||
--@unitCooldows: a table with [spellId] = cooldownInfo
|
||||
--@allUnitsCooldowns: a table containing all units [unitName] = {[spellId] = cooldownInfo}
|
||||
function Details222.CooldownTracking.OnReceiveUnitFullCooldownList(unitId, unitCooldows, allUnitsCooldowns)
|
||||
--print("|cFFFFFF00received full cooldown list|r from:", unitId)
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
|
||||
--callback on the event 'CooldownUpdate', this is triggered when a player uses a cooldown or a cooldown got updated (time left reduced, etc)
|
||||
--@unitId: which unit got updated
|
||||
--@spellId: which cooldown spell got updated
|
||||
--@cooldownInfo: cooldown information table to be passed with other functions
|
||||
--@unitCooldows: a table with [spellId] = cooldownInfo
|
||||
--@allUnitsCooldowns: a table containing all units [unitName] = {[spellId] = cooldownInfo}
|
||||
function Details222.CooldownTracking.OnReceiveSingleCooldownUpdate(unitId, spellId, cooldownInfo, unitCooldows, allUnitsCooldowns)
|
||||
--TODO: make a function inside lib open raid to get the filters the cooldown is in
|
||||
--I dont known which panel will be used
|
||||
--need to get the filter name which that spell belong
|
||||
--and then check if that filter is enabled
|
||||
|
||||
if (Details222.CooldownTracking.IsCooldownIgnored(spellId)) then
|
||||
return
|
||||
end
|
||||
|
||||
local gotUpdate = false
|
||||
|
||||
--get a map with the filters the spell is in, the key is the filter name and the value is boolean true
|
||||
local spellFilters = openRaidLib.CooldownManager.GetSpellFilters(spellId)
|
||||
|
||||
--get all cooldownFrames created
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
|
||||
for filterName in pairs(spellFilters) do
|
||||
local cooldownFrame = allCooldownFrames[filterName]
|
||||
if (cooldownFrame) then
|
||||
local unitName = GetUnitName(unitId, true)
|
||||
local cooldownLine = cooldownFrame.playerCache[unitName] and cooldownFrame.playerCache[unitName][spellId]
|
||||
|
||||
if (cooldownLine) then
|
||||
--get the cooldown time from the lib, it return data ready to use on statusbar
|
||||
|
||||
local isReady, normalizedPercent, timeLeft, charges, minValue, maxValue, currentValue
|
||||
local bRunOkay, errorText = pcall(function()
|
||||
isReady, normalizedPercent, timeLeft, charges, minValue, maxValue, currentValue = openRaidLib.GetCooldownStatusFromCooldownInfo(cooldownInfo)
|
||||
end)
|
||||
if (not bRunOkay) then
|
||||
local spellName = Details222.GetSpellInfo(spellId)
|
||||
--print("error on cooldown update:", unitName, spellName, errorText)
|
||||
return
|
||||
end
|
||||
|
||||
if (not isReady) then
|
||||
cooldownLine:SetTimer(currentValue, minValue, maxValue)
|
||||
else
|
||||
cooldownLine:SetTimer()
|
||||
end
|
||||
|
||||
gotUpdate = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (not gotUpdate) then
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
end
|
||||
|
||||
--when the list of cooldowns got wiped, usually happens when the player left a group
|
||||
--@allUnitsCooldowns: a table containing all units [unitName] = {[spellId] = cooldownInfo}
|
||||
function Details222.CooldownTracking.OnCooldownListWipe(allUnitsCooldowns)
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
|
||||
--when a cooldown has been added to an unit
|
||||
function Details222.CooldownTracking.OnCooldownAdded(unitId, spellId, cooldownInfo, unitCooldows, allUnitsCooldowns)
|
||||
--here could update the cooldown of the unit, but I'm too lazy so it update all units
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
|
||||
--when a cooldown has been removed from an unit
|
||||
function Details222.CooldownTracking.OnCooldownRemoved(unitId, spellId, unitCooldows, allUnitsCooldowns)
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end
|
||||
|
||||
local eventFrame = CreateFrame("frame")
|
||||
eventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||
eventFrame:SetScript("OnShow", function()
|
||||
eventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||
end)
|
||||
|
||||
eventFrame:SetScript("OnHide", function()
|
||||
eventFrame:UnregisterEvent("GROUP_ROSTER_UPDATE")
|
||||
end)
|
||||
|
||||
eventFrame:SetScript("OnEvent", function(self, event)
|
||||
if (event == "GROUP_ROSTER_UPDATE") then
|
||||
if (eventFrame.scheduleRosterUpdate) then
|
||||
return
|
||||
end
|
||||
--eventFrame.scheduleRosterUpdate = C_Timer.NewTimer(1, Details222.CooldownTracking.RefreshCooldownFrames)
|
||||
end
|
||||
end)
|
||||
|
||||
--create the screen panel, goes into the UIParent and show cooldowns
|
||||
function Details222.CooldownTracking.CreateCooldownFrame(filterName)
|
||||
if (not Details222.CooldownTracking.AnchorFrame) then
|
||||
local anchorFrame = CreateFrame("frame", "DetailsOnlineCDTrackerAnchorFrame", UIParent, "BackdropTemplate")
|
||||
Details222.CooldownTracking.AnchorFrame = anchorFrame
|
||||
anchorFrame:SetPoint("center", 0, 0)
|
||||
anchorFrame:SetSize(20, 20)
|
||||
anchorFrame:EnableMouse(true)
|
||||
|
||||
DetailsFramework:ApplyStandardBackdrop(anchorFrame)
|
||||
|
||||
Details.ocd_tracker.frames["anchor_frame"] = Details.ocd_tracker.frames["anchor_frame"] or {}
|
||||
|
||||
--register on libwindow
|
||||
local libWindow = LibStub("LibWindow-1.1")
|
||||
libWindow.RegisterConfig(anchorFrame, Details.ocd_tracker.frames["anchor_frame"])
|
||||
libWindow.MakeDraggable(anchorFrame)
|
||||
libWindow.RestorePosition(anchorFrame)
|
||||
end
|
||||
|
||||
filterName = filterName or "main"
|
||||
local frameName = "DetailsOnlineCDTrackerScreenPanel" .. filterName
|
||||
local cooldownFrame = CreateFrame("frame", frameName, UIParent, "BackdropTemplate")
|
||||
cooldownFrame:Hide()
|
||||
cooldownFrame.filterName = filterName
|
||||
cooldownFrame:SetSize(Details.ocd_tracker.width, Details.ocd_tracker.height)
|
||||
cooldownFrame:SetPoint("center", 0, 0)
|
||||
DetailsFramework:ApplyStandardBackdrop(cooldownFrame)
|
||||
cooldownFrame:EnableMouse(true)
|
||||
|
||||
local titleString = cooldownFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
titleString:SetPoint("bottomleft", cooldownFrame, "topleft", 0, 1)
|
||||
cooldownFrame.TitleString = titleString
|
||||
|
||||
--register on libwindow
|
||||
local libWindow = LibStub("LibWindow-1.1")
|
||||
Details.ocd_tracker.frames[filterName] = Details.ocd_tracker.frames[filterName] or {}
|
||||
libWindow.RegisterConfig(cooldownFrame, Details.ocd_tracker.frames[filterName])
|
||||
libWindow.MakeDraggable(cooldownFrame)
|
||||
libWindow.RestorePosition(cooldownFrame)
|
||||
|
||||
cooldownFrame.bars = {}
|
||||
cooldownFrame.cooldownCache = Details.ocd_tracker.current_cooldowns
|
||||
cooldownFrame.playerCache = {}
|
||||
cooldownFrame.nextLineId = 1
|
||||
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
allCooldownFrames[filterName] = cooldownFrame
|
||||
|
||||
return cooldownFrame
|
||||
end
|
||||
|
||||
function Details222.CooldownTracking.SetupCooldownLine(cooldownLine)
|
||||
local spellIcon = GetSpellTexture(cooldownLine.spellId)
|
||||
if (spellIcon) then
|
||||
cooldownLine:SetIcon(spellIcon, .1, .9, .1, .9)
|
||||
|
||||
local classColor = Details.class_colors[cooldownLine.class or "PRIEST"]
|
||||
if (classColor) then
|
||||
cooldownLine:SetStatusBarColor(classColor.r, classColor.g, classColor.b)
|
||||
else
|
||||
cooldownLine:SetStatusBarColor(1, 1, 1)
|
||||
end
|
||||
cooldownLine:SetLeftText(DF:RemoveRealmName(cooldownLine.unitName))
|
||||
cooldownLine:SetSize(Details.ocd_tracker.width, Details.ocd_tracker.height)
|
||||
end
|
||||
end
|
||||
|
||||
function Details222.CooldownTracking.ProcessUnitCooldowns(cooldownFrame, unitId, unitCooldowns, cooldownsOrganized)
|
||||
if (unitCooldowns) then
|
||||
local unitInfo = openRaidLib.GetUnitInfo(unitId)
|
||||
local filterName = false
|
||||
|
||||
local classId = unitInfo and unitInfo.classId
|
||||
if (unitInfo and not classId) then
|
||||
classId = select(3, UnitClass(unitInfo.nameFull))
|
||||
end
|
||||
|
||||
if (unitInfo and classId and cooldownsOrganized[classId]) then
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
|
||||
for spellId, cooldownInfo in pairs(unitCooldowns) do
|
||||
if (not Details222.CooldownTracking.IsCooldownIgnored(spellId)) then
|
||||
--get a cooldownLine
|
||||
local cooldownLine = Details222.CooldownTracking.GetOrCreateNewCooldownLine(cooldownFrame, cooldownFrame.nextLineId)
|
||||
cooldownLine.cooldownInfo = cooldownInfo
|
||||
--local isReady, normalizedPercent, timeLeft, charges, minValue, maxValue, currentValue = openRaidLib.GetCooldownStatusFromCooldownInfo(cooldownInfo)
|
||||
|
||||
cooldownLine.spellId = spellId
|
||||
cooldownLine.class = unitInfo.class
|
||||
cooldownLine.unitName = unitInfo.nameFull
|
||||
|
||||
--setup the cooldown in the line
|
||||
Details222.CooldownTracking.SetupCooldownLine(cooldownLine)
|
||||
|
||||
--add the cooldown into the organized by class table
|
||||
table.insert(cooldownsOrganized[classId], cooldownLine)
|
||||
|
||||
--iterate to the next cooldown line
|
||||
cooldownFrame.nextLineId = cooldownFrame.nextLineId + 1
|
||||
|
||||
--store the cooldown line into a cache to get the cooldown line quicker when a cooldown receives updates
|
||||
cooldownFrame.playerCache[unitInfo.nameFull] = cooldownFrame.playerCache[unitInfo.nameFull] or {}
|
||||
cooldownFrame.playerCache[unitInfo.nameFull][spellId] = cooldownLine
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Details222.CooldownTracking.RefreshSingleCooldownFrame(cooldownFrame)
|
||||
local filterName = cooldownFrame.filterName
|
||||
|
||||
if (Details.ocd_tracker.framme_locked) then
|
||||
cooldownFrame:EnableMouse(false)
|
||||
else
|
||||
cooldownFrame:EnableMouse(true)
|
||||
end
|
||||
|
||||
Details222.CooldownTracking.HideAllLines(cooldownFrame)
|
||||
|
||||
--check if can show the title string where the text is the filter name
|
||||
if (Details.ocd_tracker.show_title) then
|
||||
cooldownFrame.TitleString:SetText(filterName)
|
||||
cooldownFrame.TitleString:Show()
|
||||
else
|
||||
cooldownFrame.TitleString:Hide()
|
||||
end
|
||||
|
||||
cooldownFrame.scheduleRosterUpdate = nil
|
||||
Details:Destroy(cooldownFrame.playerCache)
|
||||
cooldownFrame.nextLineId = 1
|
||||
|
||||
if (Details.ocd_tracker.show_conditions.only_in_group) then
|
||||
if (not IsInGroup()) then
|
||||
cooldownFrame:Hide()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if (Details.ocd_tracker.show_conditions.only_inside_instance) then
|
||||
local isInInstanceType = select(2, GetInstanceInfo())
|
||||
if (isInInstanceType ~= "party" and isInInstanceType ~= "raid" and isInInstanceType ~= "arena") then
|
||||
cooldownFrame:Hide()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local cooldownsOrganized = {}
|
||||
for classId = 1, 13 do --13 classes
|
||||
cooldownsOrganized[classId] = {}
|
||||
end
|
||||
|
||||
local numGroupMembers = GetNumGroupMembers()
|
||||
|
||||
if (IsInRaid()) then
|
||||
for i = 1, numGroupMembers do
|
||||
local unitId = "raid"..i
|
||||
local unitCooldowns = openRaidLib.GetUnitCooldowns(unitId, filterName)
|
||||
Details222.CooldownTracking.ProcessUnitCooldowns(cooldownFrame, unitId, unitCooldowns, cooldownsOrganized)
|
||||
end
|
||||
|
||||
elseif (IsInGroup()) then
|
||||
for i = 1, numGroupMembers - 1 do
|
||||
local unitId = "party"..i
|
||||
local unitCooldowns = openRaidLib.GetUnitCooldowns(unitId, filterName)
|
||||
Details222.CooldownTracking.ProcessUnitCooldowns(cooldownFrame, unitId, unitCooldowns, cooldownsOrganized)
|
||||
end
|
||||
|
||||
--player
|
||||
local unitCooldowns = openRaidLib.GetUnitCooldowns("player", filterName)
|
||||
Details222.CooldownTracking.ProcessUnitCooldowns(cooldownFrame, "player", unitCooldowns, cooldownsOrganized)
|
||||
|
||||
else
|
||||
--player
|
||||
local unitCooldowns = openRaidLib.GetUnitCooldowns("player", filterName)
|
||||
Details222.CooldownTracking.ProcessUnitCooldowns(cooldownFrame, "player", unitCooldowns, cooldownsOrganized)
|
||||
end
|
||||
|
||||
for classId = 1, 13 do --13 classes
|
||||
table.sort(cooldownsOrganized[classId], function(t1, t2) return t1.spellId < t2.spellId end)
|
||||
end
|
||||
|
||||
local xPos = 1
|
||||
local cooldownFrameIndex = 1
|
||||
local lineIndex = 1
|
||||
local totalLinesUsed = 0
|
||||
|
||||
for classId = 1, 13 do
|
||||
local cooldownFrameList = cooldownsOrganized[classId]
|
||||
for index, cooldownLine in ipairs(cooldownFrameList) do
|
||||
local cooldownInfo = cooldownLine.cooldownInfo
|
||||
local isReady, normalizedPercent, timeLeft, charges, minValue, maxValue, currentValue = openRaidLib.GetCooldownStatusFromCooldownInfo(cooldownInfo)
|
||||
|
||||
if (not isReady) then
|
||||
cooldownLine:SetTimer(currentValue, minValue, maxValue)
|
||||
else
|
||||
cooldownLine:SetTimer()
|
||||
end
|
||||
|
||||
cooldownLine:ClearAllPoints()
|
||||
local yLocation = (lineIndex - 1) * Details.ocd_tracker.height * -1
|
||||
cooldownLine:SetPoint("topleft", cooldownFrame, "topleft", xPos, yLocation - 1)
|
||||
|
||||
lineIndex = lineIndex + 1
|
||||
|
||||
if (lineIndex > Details.ocd_tracker.lines_per_column) then
|
||||
xPos = xPos + Details.ocd_tracker.width + 2
|
||||
lineIndex = 1
|
||||
end
|
||||
|
||||
cooldownFrameIndex = cooldownFrameIndex + 1
|
||||
totalLinesUsed = totalLinesUsed + 1
|
||||
end
|
||||
end
|
||||
|
||||
if (totalLinesUsed == 0) then
|
||||
cooldownFrame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local totalColumns = ceil(totalLinesUsed / Details.ocd_tracker.lines_per_column)
|
||||
local maxRows = math.min(Details.ocd_tracker.lines_per_column, totalLinesUsed)
|
||||
|
||||
local width = 1 + totalColumns * Details.ocd_tracker.width + (totalColumns * 2)
|
||||
local height = 2 + maxRows * Details.ocd_tracker.height
|
||||
|
||||
cooldownFrame:SetSize(width, height)
|
||||
cooldownFrame:Show()
|
||||
end
|
||||
|
||||
--update cooldown frames based on the amount of players in the group or raid
|
||||
function Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
if (not Details.ocd_tracker.enabled) then
|
||||
Details222.CooldownTracking.DisableTracker()
|
||||
return
|
||||
end
|
||||
|
||||
local allCooldownFrames = Details222.CooldownTracking.GetAllCooldownFrames()
|
||||
local allFilters = Details.ocd_tracker.filters
|
||||
|
||||
for filterName, bIsEnabled in pairs(allFilters) do
|
||||
if (bIsEnabled) then
|
||||
local cooldownFrame = allCooldownFrames[filterName]
|
||||
if (not cooldownFrame) then
|
||||
cooldownFrame = Details222.CooldownTracking.CreateCooldownFrame(filterName)
|
||||
end
|
||||
cooldownFrame:Show()
|
||||
else
|
||||
local cooldownFrame = Details222.CooldownTracking.GetCooldownFrame(filterName)
|
||||
if (cooldownFrame) then
|
||||
cooldownFrame:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local previousFrame
|
||||
for filterName, cooldownFrame in pairs(allCooldownFrames) do
|
||||
if (cooldownFrame:IsShown()) then
|
||||
Details222.CooldownTracking.RefreshSingleCooldownFrame(cooldownFrame)
|
||||
--
|
||||
if (Details.ocd_tracker.group_frames) then
|
||||
if (not previousFrame) then
|
||||
previousFrame = cooldownFrame
|
||||
cooldownFrame:ClearAllPoints()
|
||||
cooldownFrame:SetPoint("topleft", Details222.CooldownTracking.AnchorFrame, "topleft", 5, 0)
|
||||
else
|
||||
cooldownFrame:ClearAllPoints()
|
||||
cooldownFrame:SetPoint("topleft", previousFrame, "topright", 2, 0)
|
||||
previousFrame = cooldownFrame
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Options panel
|
||||
|
||||
--initialize the cooldown options window and embed it to Details! options panel
|
||||
function Details:InitializeCDTrackerWindow()
|
||||
if (not Details.ocd_tracker.show_options) then
|
||||
return
|
||||
end
|
||||
|
||||
local DetailsCDTrackerWindow = CreateFrame("frame", "DetailsCDTrackerWindow", UIParent, "BackdropTemplate")
|
||||
DetailsCDTrackerWindow:SetSize(700, 480)
|
||||
DetailsCDTrackerWindow.Frame = DetailsCDTrackerWindow
|
||||
DetailsCDTrackerWindow.__name = "Cooldown Tracker"
|
||||
DetailsCDTrackerWindow.real_name = "DETAILS_CDTRACKERWINDOW"
|
||||
DetailsCDTrackerWindow.__icon = [[Interface\TUTORIALFRAME\UI-TUTORIALFRAME-SPIRITREZ]]
|
||||
DetailsCDTrackerWindow.__iconcoords = {130/512, 256/512, 0, 1}
|
||||
DetailsCDTrackerWindow.__iconcolor = "white"
|
||||
_G.DetailsPluginContainerWindow.EmbedPlugin(DetailsCDTrackerWindow, DetailsCDTrackerWindow, true)
|
||||
|
||||
function DetailsCDTrackerWindow.RefreshWindow()
|
||||
Details222.CooldownTracking.OpenCDTrackerWindow()
|
||||
end
|
||||
|
||||
--check if is enabled at startup
|
||||
if (Details222.CooldownTracking.IsEnabled()) then
|
||||
Details222.CooldownTracking.EnableTracker()
|
||||
end
|
||||
|
||||
DetailsCDTrackerWindow:Hide()
|
||||
end
|
||||
|
||||
function Details222.CooldownTracking.OpenCDTrackerWindow()
|
||||
if (not Details.ocd_tracker.show_options) then
|
||||
return
|
||||
end
|
||||
|
||||
--check if the window exists, if not create it
|
||||
if (not _G.DetailsCDTrackerWindow or not _G.DetailsCDTrackerWindow.Initialized) then
|
||||
local f = _G.DetailsCDTrackerWindow or DF:CreateSimplePanel(UIParent, 700, 480, "Details! Online CD Tracker", "DetailsCDTrackerWindow")
|
||||
_G.DetailsCDTrackerWindow.Initialized = true
|
||||
DF:ApplyStandardBackdrop(f)
|
||||
--enabled with a toggle button
|
||||
--execute to reset position
|
||||
--misc configs
|
||||
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
local generalOptions = {
|
||||
{--enable ocd
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
if (value) then
|
||||
if (not Details.ocd_tracker.show_options) then
|
||||
return
|
||||
end
|
||||
Details222.CooldownTracking.EnableTracker()
|
||||
else
|
||||
Details222.CooldownTracking.DisableTracker()
|
||||
end
|
||||
end,
|
||||
name = "Enable Experimental Cooldown Tracker",
|
||||
desc = "Enable Experimental Cooldown Tracker",
|
||||
},
|
||||
|
||||
{--show only in group
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.show_conditions.only_in_group end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.show_conditions.only_in_group = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Only in Group",
|
||||
desc = "Only in Group",
|
||||
},
|
||||
|
||||
{--show only inside instances
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.show_conditions.only_inside_instance end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.show_conditions.only_inside_instance = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Only Inside Instances",
|
||||
desc = "Only Inside Instances",
|
||||
},
|
||||
{--lock frame
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.framme_locked end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.framme_locked = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Lock Frame",
|
||||
desc = "Lock Frame",
|
||||
},
|
||||
|
||||
{type = "breakline"},
|
||||
|
||||
{--filter: show raid wide defensive cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["defensive-raid"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["defensive-raid"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Defensive: Raid",
|
||||
desc = "Example: druid tranquility.",
|
||||
},
|
||||
|
||||
{--filter: show target defensive cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["defensive-target"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["defensive-target"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Defensive: Target",
|
||||
desc = "Example: priest pain suppression.",
|
||||
},
|
||||
|
||||
{--filter: show personal defensive cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["defensive-personal"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["defensive-personal"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Defensive: Personal",
|
||||
desc = "Example: mage ice block.",
|
||||
},
|
||||
|
||||
{--filter: show ofensive cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["ofensive"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["ofensive"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Offensive Cooldowns",
|
||||
desc = "Example: priest power infusion.",
|
||||
},
|
||||
|
||||
{--filter: show utility cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["utility"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["utility"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Utility Cooldowns",
|
||||
desc = "Example: druid roar.",
|
||||
},
|
||||
|
||||
{--filter: show interrupt cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["interrupt"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["interrupt"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Interrupt Cooldowns",
|
||||
desc = "Example: rogue kick.",
|
||||
},
|
||||
|
||||
{--filter: item cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["itemheal"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["itemheal"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Item: Healing",
|
||||
desc = "Example: Healthstone.",
|
||||
},
|
||||
|
||||
{--filter: item cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["itempower"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["itempower"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Item: Power Increase",
|
||||
desc = "Example: Elemental Potion of Power.",
|
||||
},
|
||||
|
||||
{--filter: item cooldowns
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["itemutil"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["itemutil"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Item: Utility",
|
||||
desc = "Example: Invisibility Potion.",
|
||||
},
|
||||
|
||||
{--filter: crowd control
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.filters["crowdcontrol"] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.filters["crowdcontrol"] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Crowd Control",
|
||||
desc = "Example: Incapacitaion Roar.",
|
||||
},
|
||||
|
||||
{type = "breakline"},
|
||||
|
||||
{--bar width
|
||||
type = "range",
|
||||
get = function() return Details.ocd_tracker.width end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.width = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
min = 10,
|
||||
max = 200,
|
||||
step = 1,
|
||||
name = "Width",
|
||||
desc = "Width",
|
||||
},
|
||||
|
||||
{--bar height
|
||||
type = "range",
|
||||
get = function() return Details.ocd_tracker.height end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.height = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
min = 10,
|
||||
max = 200,
|
||||
step = 1,
|
||||
name = "Height",
|
||||
desc = "Height",
|
||||
},
|
||||
|
||||
{--bar height
|
||||
type = "range",
|
||||
get = function() return Details.ocd_tracker.lines_per_column end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.lines_per_column = floor(value)
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
min = 1,
|
||||
max = 30,
|
||||
step = 1,
|
||||
name = "Lines Per Column",
|
||||
desc = "Lines Per Column",
|
||||
},
|
||||
|
||||
{--show anchor
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.show_title end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.show_title = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Show Title",
|
||||
desc = "Show Title",
|
||||
},
|
||||
|
||||
{--show anchor
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.group_frames end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.group_frames = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = "Group Frames",
|
||||
desc = "Group Frames",
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
generalOptions.always_boxfirst = true
|
||||
DF:BuildMenu(f, generalOptions, 5, -30, 150, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
|
||||
--cooldown selection
|
||||
local cooldownProfile = Details.ocd_tracker.cooldowns
|
||||
|
||||
local cooldownSelectionFrame = CreateFrame("frame", "$parentCooldownSelectionFrame", f, "BackdropTemplate")
|
||||
cooldownSelectionFrame:SetPoint("topleft", f, "topleft", 0, -150)
|
||||
cooldownSelectionFrame:SetPoint("bottomright", f, "bottomright", 0, 10)
|
||||
DF:ApplyStandardBackdrop(cooldownSelectionFrame)
|
||||
|
||||
local warning2 = cooldownSelectionFrame:CreateFontString(nil, "overlay", "GameFontNormal", 5)
|
||||
warning2:SetJustifyH("left")
|
||||
warning2:SetPoint("topleft", f, "topleft", 5, -160)
|
||||
DF:SetFontColor(warning2, "lime")
|
||||
--warning2:SetText("This is a concept of a cooldown tracker using the new library 'Open Raid' which uses comms to update cooldown timers.\nThe code to implement is so small that can fit inside a weakaura\nIf you're a coder, the implementation is on Details/frames/window_cdtracker.lua")
|
||||
|
||||
cooldownSelectionFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||
--cooldownSelectionFrame:RegisterEvent("PLAYER_STARTED_MOVING") --debug
|
||||
|
||||
local maxClasses = 13
|
||||
|
||||
cooldownSelectionFrame.ClassCDsAnchorFrames = {}
|
||||
|
||||
for i = 1, maxClasses do
|
||||
local anchorFrame = CreateFrame("frame", "$parentAnchorFrame"..i, cooldownSelectionFrame, "BackdropTemplate")
|
||||
anchorFrame:SetSize(1, 1)
|
||||
if (i == 1) then
|
||||
anchorFrame:SetPoint("topleft", cooldownSelectionFrame, "topleft", 5, -5)
|
||||
else
|
||||
anchorFrame:SetPoint("topleft", cooldownSelectionFrame.ClassCDsAnchorFrames[i-1], "topright", 310, 0)
|
||||
end
|
||||
|
||||
cooldownSelectionFrame.ClassCDsAnchorFrames[i] = anchorFrame
|
||||
end
|
||||
|
||||
function cooldownSelectionFrame.ClearAllCDsAnchorFrames()
|
||||
for i = 1, maxClasses do
|
||||
cooldownSelectionFrame.ClassCDsAnchorFrames[i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
cooldownSelectionFrame:SetScript("OnEvent", function(self, event)
|
||||
--show a list of players in the group, 1 player per column
|
||||
--below the player name, show a list in vertical with checkboxes to enable/disable cooldowns for that class
|
||||
--use DetailsFramework:BuildMenuVolatile() to build the each list
|
||||
|
||||
if (not cooldownSelectionFrame:IsShown()) then
|
||||
return
|
||||
end
|
||||
|
||||
local amountOfUnits = GetNumGroupMembers()
|
||||
|
||||
if (amountOfUnits == 0) then
|
||||
return
|
||||
end
|
||||
|
||||
local allClasses = {}
|
||||
if (IsInGroup() and not IsInRaid()) then
|
||||
for i = 1, amountOfUnits - 1 do
|
||||
local unitId = "party"..i
|
||||
local _, class = UnitClass(unitId)
|
||||
if (class) then
|
||||
allClasses[class] = {}
|
||||
end
|
||||
end
|
||||
|
||||
local unitId = "player"
|
||||
local _, class = UnitClass(unitId)
|
||||
allClasses[class] = {}
|
||||
|
||||
elseif (IsInRaid()) then
|
||||
for i = 1, amountOfUnits do
|
||||
local unitId = "raid"..i
|
||||
local _, class = UnitClass(unitId)
|
||||
if (class) then
|
||||
allClasses[class] = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local index = 1
|
||||
cooldownSelectionFrame.ClearAllCDsAnchorFrames()
|
||||
|
||||
for className, allClassCDs in pairs(allClasses) do
|
||||
--menu to build with DetailsFramework:BuildMenuVolatile()
|
||||
local menuOptions = {}
|
||||
|
||||
for spellId, spellInfo in pairs(LIB_OPEN_RAID_COOLDOWNS_INFO) do
|
||||
if (spellInfo.class == className) then
|
||||
local spellName, _, spellIcon = Details222.GetSpellInfo(spellId)
|
||||
|
||||
if (spellName) then
|
||||
local smallSpellName = string.sub(spellName, 1, 12)
|
||||
spellName = "|T" .. spellIcon .. ":" .. 20 .. ":" .. 20 .. ":0:0:" .. 64 .. ":" .. 64 .. "|t " .. smallSpellName
|
||||
|
||||
if (spellName) then
|
||||
menuOptions[#menuOptions+1] = {
|
||||
type = "toggle",
|
||||
get = function() return Details.ocd_tracker.ignored_cooldowns[spellId] end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.ocd_tracker.ignored_cooldowns[spellId] = value
|
||||
Details222.CooldownTracking.RefreshAllCooldownFrames()
|
||||
end,
|
||||
name = spellName,
|
||||
desc = spellName,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local anchorFrame = cooldownSelectionFrame.ClassCDsAnchorFrames[index]
|
||||
anchorFrame:Show()
|
||||
|
||||
menuOptions.always_boxfirst = true
|
||||
|
||||
DF:BuildMenuVolatile(anchorFrame, menuOptions, 5, -5, 400, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
end)
|
||||
|
||||
cooldownSelectionFrame:GetScript("OnEvent")(cooldownSelectionFrame, "GROUP_ROSTER_UPDATE")
|
||||
|
||||
cooldownSelectionFrame:SetScript("OnShow", function()
|
||||
cooldownSelectionFrame:GetScript("OnEvent")(cooldownSelectionFrame, "GROUP_ROSTER_UPDATE")
|
||||
end)
|
||||
end
|
||||
|
||||
_G.DetailsPluginContainerWindow.OpenPlugin(_G.DetailsCDTrackerWindow)
|
||||
_G.DetailsCDTrackerWindow:Show()
|
||||
end
|
||||
@@ -0,0 +1,159 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local Loc = _G.LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
--config class colors
|
||||
function Details:OpenClassColorsConfig()
|
||||
if (not _G.DetailsClassColorManager) then
|
||||
DF:CreateSimplePanel(UIParent, 440, 400, Loc ["STRING_OPTIONS_CLASSCOLOR_MODIFY"], "DetailsClassColorManager")
|
||||
local panel = _G.DetailsClassColorManager
|
||||
|
||||
DF:ApplyStandardBackdrop(panel)
|
||||
panel:SetBackdropColor(.1, .1, .1, .9)
|
||||
|
||||
local upper_panel = CreateFrame("frame", nil, panel,"BackdropTemplate")
|
||||
upper_panel:SetAllPoints(panel)
|
||||
upper_panel:SetFrameLevel(panel:GetFrameLevel()+3)
|
||||
|
||||
local y = -30
|
||||
|
||||
local callback = function(button, r, g, b, a, self)
|
||||
self.MyObject.my_texture:SetVertexColor(r, g, b)
|
||||
Details.class_colors [self.MyObject.my_class][1] = r
|
||||
Details.class_colors [self.MyObject.my_class][2] = g
|
||||
Details.class_colors [self.MyObject.my_class][3] = b
|
||||
Details:RefreshMainWindow(-1, true)
|
||||
end
|
||||
|
||||
local set_color = function(self, button, class, index)
|
||||
local current_class_color = Details.class_colors [class]
|
||||
local r, g, b = unpack(current_class_color)
|
||||
DF:ColorPick (self, r, g, b, 1, callback)
|
||||
end
|
||||
|
||||
local reset_color = function(self, button, class, index)
|
||||
local color_table = RAID_CLASS_COLORS [class]
|
||||
local r, g, b = color_table.r, color_table.g, color_table.b
|
||||
self.MyObject.my_texture:SetVertexColor(r, g, b)
|
||||
Details.class_colors [self.MyObject.my_class][1] = r
|
||||
Details.class_colors [self.MyObject.my_class][2] = g
|
||||
Details.class_colors [self.MyObject.my_class][3] = b
|
||||
Details:RefreshMainWindow(-1, true)
|
||||
end
|
||||
|
||||
local on_enter = function(self, capsule)
|
||||
--Details:CooltipPreset(1)
|
||||
--GameCooltip:AddLine("right click to reset")
|
||||
--GameCooltip:Show (self)
|
||||
end
|
||||
local on_leave = function(self, capsule)
|
||||
--GameCooltip:Hide()
|
||||
end
|
||||
|
||||
local reset = DF:NewLabel(panel, panel, nil, nil, "|TInterface\\TUTORIALFRAME\\UI-TUTORIAL-FRAME:" .. 20 .. ":" .. 20 .. ":0:1:512:512:8:70:328:409|t " .. Loc ["STRING_OPTIONS_CLASSCOLOR_RESET"])
|
||||
reset:SetPoint("bottomright", panel, "bottomright", -20, 08)
|
||||
|
||||
local reset_texture = DF:CreateImage(panel, [[Interface\MONEYFRAME\UI-MONEYFRAME-BORDER]], 138, 45, "border")
|
||||
reset_texture:SetPoint("center", reset, "center", 0, -7)
|
||||
reset_texture:SetDesaturated(true)
|
||||
|
||||
panel.buttons = {}
|
||||
|
||||
local next_x = 10
|
||||
for index, className in ipairs(CLASS_SORT_ORDER) do
|
||||
local icon = DF:CreateImage(upper_panel, [[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]], 30, 30, nil, CLASS_ICON_TCOORDS [className], "icon_" .. className)
|
||||
|
||||
if index == 12 then
|
||||
next_x = 150
|
||||
y = -30
|
||||
elseif index == 23 then
|
||||
next_x = 290
|
||||
y = -30
|
||||
end
|
||||
|
||||
icon:SetPoint("topleft", panel, "topleft", next_x, y)
|
||||
y = y - 33
|
||||
|
||||
local backgroundTexture = DF:CreateImage(panel, [[Interface\AddOns\Details\images\bar_skyline]], 135, 30, "artwork")
|
||||
backgroundTexture:SetPoint("left", icon, "right", -30, 0)
|
||||
local localizedClassName = LOCALIZED_CLASS_NAMES_MALE[className]
|
||||
local button = DF:CreateButton(panel, set_color, 135, 30, localizedClassName, className, index)
|
||||
button:SetPoint("left", icon, "right", -30, 0)
|
||||
button:InstallCustomTexture(nil, nil, nil, nil, true)
|
||||
button:SetFrameLevel(panel:GetFrameLevel()+1)
|
||||
|
||||
button.text_overlay:ClearAllPoints()
|
||||
button.text_overlay:SetPoint("left", icon.widget, "right", 2, 0)
|
||||
button.text_overlay.textsize = 10
|
||||
|
||||
button.my_icon = icon
|
||||
button.my_texture = backgroundTexture
|
||||
button.my_class = className
|
||||
button:SetHook("OnEnter", on_enter)
|
||||
button:SetHook("OnLeave", on_leave)
|
||||
button:SetClickFunction(reset_color, nil, nil, "RightClick")
|
||||
panel.buttons [className] = button
|
||||
end
|
||||
|
||||
--make color options for death log bars
|
||||
local function hex (num)
|
||||
local hexstr = '0123456789abcdef'
|
||||
local s = ''
|
||||
while num > 0 do
|
||||
local mod = math.fmod(num, 16)
|
||||
s = string.sub(hexstr, mod+1, mod+1) .. s
|
||||
num = math.floor(num / 16)
|
||||
end
|
||||
if s == '' then s = '00' end
|
||||
if (string.len(s) == 1) then
|
||||
s = "0"..s
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function sort_color (t1, t2)
|
||||
return t1[1][3] > t2[1][3]
|
||||
end
|
||||
|
||||
local colorSelected = function(self, fixParam, value)
|
||||
local colorName, barType = value:match("^(%w+)@(%w+)")
|
||||
Details.death_log_colors[barType] = colorName
|
||||
end
|
||||
|
||||
local buildColorList = function(barType)
|
||||
--all colors
|
||||
local allColors = {}
|
||||
for colorName, colorTable in pairs(DF:GetDefaultColorList()) do
|
||||
table.insert(allColors, {colorTable, colorName, hex(colorTable[1]*255) .. hex(colorTable[2]*255) .. hex(colorTable[3]*255)})
|
||||
end
|
||||
table.sort(allColors, sort_color)
|
||||
|
||||
local result = {}
|
||||
for index, colorTable in ipairs(allColors) do
|
||||
local colortable = colorTable[1]
|
||||
local colorname = colorTable[2]
|
||||
local value = colorname .. "@" .. barType
|
||||
table.insert(result, {label = colorname, value = value, color = colortable, onclick = colorSelected})
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
for class, button in pairs(_G.DetailsClassColorManager.buttons) do
|
||||
button.my_texture:SetVertexColor(unpack(Details.class_colors [class]))
|
||||
end
|
||||
|
||||
|
||||
local colorWindow = _G.DetailsClassColorManager
|
||||
colorWindow:Show()
|
||||
|
||||
local optionsFrame = _G.DetailsOptionsWindow
|
||||
if (optionsFrame) then
|
||||
--parent is the plugin container
|
||||
local currentOptionsScale = optionsFrame:GetParent():GetScale()
|
||||
colorWindow:SetScale(currentOptionsScale)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
do
|
||||
|
||||
local _detalhes = _G.Details
|
||||
local DetailsFrameWork = _detalhes.gump
|
||||
local _
|
||||
--panel
|
||||
|
||||
function _detalhes:CreateCopyPasteWindow()
|
||||
|
||||
local panel = CreateFrame("frame", "DetailsCopy", UIParent, "ButtonFrameTemplate")
|
||||
panel:SetSize(512, 148)
|
||||
table.insert(UISpecialFrames, "DetailsCopy")
|
||||
panel:SetFrameStrata("TOOLTIP")
|
||||
panel:SetPoint("center", UIParent, "center")
|
||||
panel.locked = false
|
||||
panel:SetToplevel(true)
|
||||
panel:SetMovable(true)
|
||||
panel:SetScript("OnMouseDown", function(self, button)
|
||||
if (self.isMoving) then
|
||||
return
|
||||
end
|
||||
if (button == "RightButton") then
|
||||
self:Hide()
|
||||
else
|
||||
self:StartMoving()
|
||||
self.isMoving = true
|
||||
end
|
||||
end)
|
||||
panel:SetScript("OnMouseUp", function(self, button)
|
||||
if (self.isMoving and button == "LeftButton") then
|
||||
self:StopMovingOrSizing()
|
||||
self.isMoving = nil
|
||||
end
|
||||
end)
|
||||
|
||||
DetailsFrameWork:NewImage(panel, "Interface\\AddOns\\Details\\images\\copy", 512, 128, "overlay", nil, "background", "$parentBackGround")
|
||||
panel.background:SetPoint(0, -25)
|
||||
|
||||
--title
|
||||
--panel.TitleText:SetText("Paste & Copy") --10.0 fuck
|
||||
--panel.portrait:SetTexture([[Interface\CHARACTERFRAME\TEMPORARYPORTRAIT-FEMALE-BLOODELF]])
|
||||
|
||||
DetailsFrameWork:NewTextEntry(panel, _, "$parentTextEntry", "text", 476, 14)
|
||||
panel.text:SetPoint(20, -127)
|
||||
panel.text:SetHook("OnEditFocusLost", function() panel:Hide() end)
|
||||
panel.text:SetHook("OnChar", function() panel:Hide() end)
|
||||
|
||||
DetailsFrameWork:NewLabel(panel, _, _, "desc", "paste on your web browser address bar", "GameFontNormalSmall", 12)
|
||||
panel.desc:SetPoint(340, -78)
|
||||
panel.desc.width = 150
|
||||
panel.desc.height = 25
|
||||
panel.desc.align = "|"
|
||||
panel.desc.color = "gray"
|
||||
|
||||
panel:Hide()
|
||||
end
|
||||
|
||||
function _detalhes:CopyPaste (link)
|
||||
_G.DetailsCopy.text.text = link
|
||||
_G.DetailsCopy.text:HighlightText()
|
||||
_G.DetailsCopy:Show()
|
||||
_G.DetailsCopy.text:SetFocus()
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,946 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = DetailsFramework
|
||||
|
||||
local green_team_color
|
||||
local yellow_team_color
|
||||
|
||||
function Details:OpenCurrentRealDPSOptions(from_options_panel)
|
||||
|
||||
if (not DetailsCurrentRealDPSOptions) then
|
||||
|
||||
green_team_color = Details.class_colors.ARENA_GREEN --{.5, 1, .5, 1}
|
||||
yellow_team_color = Details.class_colors.ARENA_YELLOW --{1, 1, .5, 1}
|
||||
|
||||
local DF = Details.gump
|
||||
|
||||
local f = DF:CreateSimplePanel(UIParent, 700, 400, "Details! Arena Damage Bar Options", "DetailsCurrentRealDPSOptions")
|
||||
f:SetPoint("center", UIParent, "center")
|
||||
f:SetScript("OnMouseDown", nil)
|
||||
f:SetScript("OnMouseUp", nil)
|
||||
DF:ApplyStandardBackdrop(f)
|
||||
|
||||
--scale bar
|
||||
local scaleBar = DF:CreateScaleBar(f, Details.realtime_dps_meter.options_frame)
|
||||
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(f, Details.realtime_dps_meter.options_frame)
|
||||
LibWindow.MakeDraggable(f)
|
||||
LibWindow.RestorePosition(f)
|
||||
|
||||
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
--status bar
|
||||
local statusBar = DF:CreateStatusBar(f)
|
||||
statusBar.text = statusBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
statusBar.text:SetPoint("left", statusBar, "left", 5, 0)
|
||||
statusBar.text:SetText("By Terciob | Part of Details! Damage Meter | Built with Details! Framework")
|
||||
DF:SetFontSize(statusBar.text, 11)
|
||||
DF:SetFontColor(statusBar.text, "gray")
|
||||
|
||||
--add an extra background
|
||||
local backgroundTexture = f:CreateTexture("$parentBackgroundTexture", "background")
|
||||
backgroundTexture:SetTexture(.2, .2, .2, .2)
|
||||
backgroundTexture:SetAllPoints()
|
||||
|
||||
|
||||
local testUsing = "arena" --mythicdungeon
|
||||
|
||||
--frame strata options
|
||||
local set_frame_strata = function(_, _, strata)
|
||||
Details.realtime_dps_meter.frame_settings.strata = strata
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end
|
||||
local strataTable = {}
|
||||
strataTable [1] = {value = "BACKGROUND", label = "BACKGROUND", onclick = set_frame_strata}
|
||||
strataTable [2] = {value = "LOW", label = "LOW", onclick = set_frame_strata}
|
||||
strataTable [3] = {value = "MEDIUM", label = "MEDIUM", onclick = set_frame_strata}
|
||||
strataTable [4] = {value = "HIGH", label = "HIGH", onclick = set_frame_strata}
|
||||
strataTable [5] = {value = "DIALOG", label = "DIALOG", onclick = set_frame_strata}
|
||||
|
||||
--font options
|
||||
local set_font_shadow= function(_, _, shadow)
|
||||
Details.realtime_dps_meter.font_shadow = shadow
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end
|
||||
local fontShadowTable = {}
|
||||
fontShadowTable [1] = {value = "NONE", label = "None", onclick = set_font_shadow}
|
||||
fontShadowTable [2] = {value = "OUTLINE", label = "Outline", onclick = set_font_shadow}
|
||||
fontShadowTable [3] = {value = "THICKOUTLINE", label = "Thick Outline", onclick = set_font_shadow}
|
||||
|
||||
local on_select_text_font = function(self, fixed_value, value)
|
||||
Details.realtime_dps_meter.font_face = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end
|
||||
|
||||
local lockCallback = function()
|
||||
local f = _G.DetailsCurrentDpsMeter
|
||||
if (Details.realtime_dps_meter.frame_settings.locked) then
|
||||
f.movemeLabel:Hide()
|
||||
f.lockButton:Hide()
|
||||
f:SetBackdropColor(.2, .2, .2, 0)
|
||||
else
|
||||
f.movemeLabel:Show()
|
||||
f.lockButton:Show()
|
||||
f:SetBackdropColor(.2, .2, .2, 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
--options table
|
||||
local options = {
|
||||
|
||||
{type = "label", get = function() return "Frame Settings:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
--enabled
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.realtime_dps_meter.enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.enabled = not Details.realtime_dps_meter.enabled
|
||||
Details:LoadFramesForBroadcastTools()
|
||||
C_Timer.After(0, function()
|
||||
if (value) then
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
DetailsCurrentDpsMeter:StartForArenaMatch()
|
||||
end
|
||||
end)
|
||||
end,
|
||||
desc = "Enabled",
|
||||
name = "Enabled",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--locked
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.realtime_dps_meter.frame_settings.locked end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.frame_settings.locked = not Details.realtime_dps_meter.frame_settings.locked
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
lockCallback()
|
||||
end,
|
||||
desc = "Locked",
|
||||
name = "Locked",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--showtitle
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.realtime_dps_meter.frame_settings.show_title end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.frame_settings.show_title = not Details.realtime_dps_meter.frame_settings.show_title
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
desc = "Show Title",
|
||||
name = "Show Title",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--backdrop color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
return {Details.realtime_dps_meter.frame_settings.backdrop_color[1], Details.realtime_dps_meter.frame_settings.backdrop_color[2], Details.realtime_dps_meter.frame_settings.backdrop_color[3], Details.realtime_dps_meter.frame_settings.backdrop_color[4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.realtime_dps_meter.frame_settings.backdrop_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
desc = "Backdrop Color",
|
||||
name = "Backdrop Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--statra
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.realtime_dps_meter.frame_settings.strata end,
|
||||
values = function() return strataTable end,
|
||||
name = "Frame Strata"
|
||||
},
|
||||
--speed
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.realtime_dps_meter.sample_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.sample_size = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
min = 1,
|
||||
max = 6,
|
||||
step = 1,
|
||||
name = "Speed",
|
||||
desc = "Low is faster",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--width
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.realtime_dps_meter.frame_settings.width end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.frame_settings.width = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
min = 1,
|
||||
max = 500,
|
||||
step = 1,
|
||||
name = "Width",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--height
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.realtime_dps_meter.frame_settings.height end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.frame_settings.height = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
min = 1,
|
||||
max = 300,
|
||||
step = 1,
|
||||
name = "Height",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
|
||||
--[=[
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Enabled On:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
--arenas
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.realtime_dps_meter.arena_enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.arena_enabled = not Details.realtime_dps_meter.arena_enabled
|
||||
Details:LoadFramesForBroadcastTools()
|
||||
end,
|
||||
name = "Arena Matches",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--mythic dungeon
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.realtime_dps_meter.mythic_dungeon_enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.mythic_dungeon_enabled = not Details.realtime_dps_meter.mythic_dungeon_enabled
|
||||
Details:LoadFramesForBroadcastTools()
|
||||
end,
|
||||
name = "Mythic Dungeons",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--]=]
|
||||
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Text Settings:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
--font size
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.realtime_dps_meter.font_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.font_size = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
min = 4,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Font Size",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--font color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
return {Details.realtime_dps_meter.font_color[1], Details.realtime_dps_meter.font_color[2], Details.realtime_dps_meter.font_color[3], Details.realtime_dps_meter.font_color[4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.realtime_dps_meter.font_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
desc = "Font Color",
|
||||
name = "Font Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--font shadow
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.realtime_dps_meter.font_shadow end,
|
||||
values = function() return fontShadowTable end,
|
||||
name = "Font Shadow"
|
||||
},
|
||||
--font face
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.realtime_dps_meter.font_face end,
|
||||
values = function() return DF:BuildDropDownFontList (on_select_text_font) end,
|
||||
name = "Font Face",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.realtime_dps_meter.text_offset end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.realtime_dps_meter.text_offset = value
|
||||
Details:UpdateTheRealCurrentDPSFrame(testUsing)
|
||||
end,
|
||||
min = 0,
|
||||
max = 150,
|
||||
step = 1,
|
||||
name = "Text Position",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
}
|
||||
|
||||
DF:BuildMenu (f, options, 7, -50, 500, true, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
|
||||
f:SetScript("OnHide" , function()
|
||||
if (DetailsCurrentDpsMeter) then
|
||||
--check if can hide the main frame as well
|
||||
--we force show the main frame for the user see the frame while editing the options
|
||||
local zoneName, instanceType, difficultyID, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID, instanceGroupSize = GetInstanceInfo()
|
||||
if ((instanceType ~= "party" and difficultyID ~= 8) and instanceType ~= "arena") then
|
||||
DetailsCurrentDpsMeter:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
--reopen the options panel
|
||||
if (f.FromOptionsPanel) then
|
||||
C_Timer.After(0.2, function()
|
||||
Details:OpenOptionsWindow(Details:GetInstance(1))
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
C_Timer.After(1, lockCallback)
|
||||
end
|
||||
|
||||
--check if the frame was been created
|
||||
if (not DetailsCurrentDpsMeter) then
|
||||
Details:CreateCurrentDpsFrame(UIParent, "DetailsCurrentDpsMeter")
|
||||
end
|
||||
|
||||
--show the options
|
||||
DetailsCurrentRealDPSOptions:Show()
|
||||
DetailsCurrentRealDPSOptions:RefreshOptions()
|
||||
DetailsCurrentRealDPSOptions.FromOptionsPanel = from_options_panel
|
||||
|
||||
--start the frame for viewing while editing the options
|
||||
DetailsCurrentDpsMeter:StartForArenaMatch()
|
||||
end
|
||||
|
||||
|
||||
function Details:CreateCurrentDpsFrame(parent, name)
|
||||
|
||||
local DF = Details.gump
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
|
||||
green_team_color = Details.class_colors.ARENA_GREEN --{.5, 1, .5, 1}
|
||||
yellow_team_color = Details.class_colors.ARENA_YELLOW --{1, 1, .5, 1}
|
||||
|
||||
--some constants
|
||||
local header_size = 12 --title bar size
|
||||
local spacing_vertical = -6 --vertical space between the group anchor and the group dps
|
||||
|
||||
--main farame
|
||||
local f = CreateFrame("frame", name, parent or UIParent, "BackdropTemplate")
|
||||
f:SetPoint("top", UIParent, "top", 0, -110)
|
||||
f:SetSize(Details.realtime_dps_meter.frame_settings.width, Details.realtime_dps_meter.frame_settings.height)
|
||||
|
||||
f:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tile = true, tileSize = 16, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
f:SetBackdropColor(unpack(Details.realtime_dps_meter.frame_settings.backdrop_color))
|
||||
f:EnableMouse(true)
|
||||
f:SetMovable(true)
|
||||
f:SetClampedToScreen(true)
|
||||
|
||||
f.movemeLabel = f:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
f.movemeLabel:SetText("Move-Me")
|
||||
|
||||
f.lockButton = DetailsFramework:CreateButton(f, function()
|
||||
Details.realtime_dps_meter.frame_settings.locked = not Details.realtime_dps_meter.frame_settings.locked
|
||||
Details:UpdateTheRealCurrentDPSFrame()
|
||||
f.movemeLabel:Hide()
|
||||
f.lockButton:Hide()
|
||||
end, 80, 20)
|
||||
f.lockButton:SetPoint("center", f, "center", 0, -20)
|
||||
f.lockButton.text = "Lock"
|
||||
|
||||
if (Details.realtime_dps_meter.frame_settings.locked) then
|
||||
f.movemeLabel:Hide()
|
||||
f.lockButton:Hide()
|
||||
end
|
||||
|
||||
f.PlayerTeam = 0
|
||||
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(f, Details.realtime_dps_meter.frame_settings)
|
||||
LibWindow.MakeDraggable(f)
|
||||
LibWindow.RestorePosition(f)
|
||||
|
||||
local lockCallback = function()
|
||||
local f = _G.DetailsCurrentDpsMeter
|
||||
if (Details.realtime_dps_meter.frame_settings.locked) then
|
||||
f.movemeLabel:Hide()
|
||||
f.lockButton:Hide()
|
||||
f:SetBackdropColor(.2, .2, .2, 0)
|
||||
else
|
||||
f.movemeLabel:Show()
|
||||
f.lockButton:Show()
|
||||
f:SetBackdropColor(.2, .2, .2, 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
--arena dps bars
|
||||
--code for the dps bars shown in arenas
|
||||
|
||||
--frame to support the two bars, one for the dps and another for heal
|
||||
--the dps bar is wider and taller, hps is below it and smaller
|
||||
local barFrame = CreateFrame("frame", "DetailsArenaDpsBars", f, "BackdropTemplate")
|
||||
f.dpsBarFrame = barFrame
|
||||
barFrame:SetSize(400, 80)
|
||||
barFrame:SetPoint("center", f, "center", 0, 0)
|
||||
barFrame:EnableMouse(false)
|
||||
|
||||
barFrame.splitBar = DF:CreateSplitBar(barFrame, 400, 20)
|
||||
barFrame.splitBar:SetSize(400, 20)
|
||||
barFrame.splitBar:SetPoint("center", barFrame, "center", 0, 0)
|
||||
barFrame.splitBar.fontsize = 10
|
||||
barFrame.splitBar:SetTexture(SharedMedia:Fetch("statusbar", "Details Flat"))
|
||||
barFrame.splitBar:SetBackgroundTexture([[Interface/AddOns/Details/images/bar_textures/chess]])
|
||||
barFrame.splitBar:SetBackgroundColor(1, 0, 0, 1)
|
||||
barFrame.splitBar.SparkAlwaysShow = true
|
||||
|
||||
|
||||
--barFrame.splitBar.widget.righttext:SetPoint("RIGHT", barFrame.splitBar.widget.righticon, "LEFT", -15, 0)
|
||||
--barFrame.splitBar.widget.righttext:ClearAllPoints()
|
||||
|
||||
barFrame.borderFrame = CreateFrame("frame", "DetailsArenaDpsBarsBorderFrame", barFrame.splitBar.widget, "BackdropTemplate")
|
||||
barFrame.borderFrame:SetFrameLevel(barFrame.splitBar:GetFrameLevel()-1)
|
||||
barFrame.borderFrame:SetPoint("topleft", barFrame.splitBar.widget, "topleft", -1, 1)
|
||||
barFrame.borderFrame:SetPoint("bottomright", barFrame.splitBar.widget, "bottomright", 1, -1)
|
||||
|
||||
f.movemeLabel:SetParent(barFrame.splitBar.widget)
|
||||
f.movemeLabel:SetPoint("center", barFrame.splitBar.widget, "center", 0, 0)
|
||||
|
||||
local backgroundText = barFrame.borderFrame:CreateTexture(nil, "background")
|
||||
backgroundText:SetTexture(0, 0, 0, 0.5)
|
||||
backgroundText:SetAllPoints()
|
||||
|
||||
local fff = CreateFrame("frame", "nopnopnopnopnop", barFrame.splitBar.widget, "BackdropTemplate")
|
||||
fff:SetSize(300, 20)
|
||||
fff:SetPoint("topleft", barFrame.splitBar.widget, "topleft", -1, 1)
|
||||
fff:SetPoint("bottomright", barFrame.splitBar.widget, "bottomright", 1, -1)
|
||||
fff:SetBackdrop({edgeFile = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]], edgeSize = 10}) --, insets = {left = 1, right = 1, top = -10, bottom = -10}
|
||||
fff:SetBackdropBorderColor(1, 1, 1, 1)
|
||||
--fff:Hide()
|
||||
|
||||
|
||||
local leftOrnamentTexture = fff:CreateTexture(nil, "overlay")
|
||||
leftOrnamentTexture:SetTexture([[Interface\PETBATTLES\PETJOURNAL]])
|
||||
leftOrnamentTexture:SetTexCoord(124/512, 161/512, 71/1024, 99/1024)
|
||||
leftOrnamentTexture:SetPoint("right", fff, "left", 11, 0)
|
||||
leftOrnamentTexture:SetSize(32, 32)
|
||||
leftOrnamentTexture:SetAlpha(0.6)
|
||||
|
||||
local rightOrnamentTexture = fff:CreateTexture(nil, "overlay")
|
||||
rightOrnamentTexture:SetTexture([[Interface\PETBATTLES\PETJOURNAL]])
|
||||
rightOrnamentTexture:SetTexCoord(119/512, 156/512, 29/1024, 57/1024)
|
||||
rightOrnamentTexture:SetPoint("left", fff, "right", -11, 0)
|
||||
rightOrnamentTexture:SetSize(32, 32)
|
||||
rightOrnamentTexture:SetAlpha(0.6)
|
||||
|
||||
--title bar
|
||||
local TitleString = f:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
TitleString:SetPoint("top", f, "top", 0, -5)
|
||||
TitleString:SetText("Details! Arena Real Time DPS Tracker")
|
||||
DF:SetFontSize(TitleString, 9)
|
||||
local TitleBackground = f:CreateTexture(nil, "artwork")
|
||||
TitleBackground:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
|
||||
TitleBackground:SetVertexColor(.1, .1, .1, .9)
|
||||
TitleBackground:SetVertexColor(.1, .1, .1, 0)
|
||||
TitleBackground:SetPoint("topleft", f, "topleft")
|
||||
TitleBackground:SetPoint("topright", f, "topright")
|
||||
TitleBackground:SetHeight(header_size)
|
||||
|
||||
--labels for arena
|
||||
local labelPlayerTeam_DPS = barFrame.splitBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
local labelYellowTeam_DPS = barFrame.splitBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
labelPlayerTeam_DPS:SetText("0")
|
||||
labelYellowTeam_DPS:SetText("0")
|
||||
labelPlayerTeam_DPS:SetPoint("left", barFrame.splitBar.widget, "left", 4, 0)
|
||||
labelYellowTeam_DPS:SetPoint("right", barFrame.splitBar.widget, "right", -4, 0)
|
||||
|
||||
function f.SwapArenaTeamColors()
|
||||
green_team_color = Details.class_colors.ARENA_GREEN
|
||||
yellow_team_color = Details.class_colors.ARENA_YELLOW
|
||||
|
||||
if (f.PlayerTeam == 0) then
|
||||
labelPlayerTeam:SetTextColor(unpack(yellow_team_color))
|
||||
labelYellowTeam:SetTextColor(unpack(green_team_color))
|
||||
else
|
||||
labelPlayerTeam:SetTextColor(unpack(green_team_color))
|
||||
labelYellowTeam:SetTextColor(unpack(yellow_team_color))
|
||||
end
|
||||
end
|
||||
|
||||
--labels for mythic dungeon / group party
|
||||
local labelGroupDamage = f:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
labelGroupDamage:SetText("Real Time Group DPS")
|
||||
DF:SetFontSize(labelGroupDamage, 14)
|
||||
DF:SetFontOutline (labelGroupDamage, "NONE")
|
||||
|
||||
local labelGroupDamage_DPS = f:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
labelGroupDamage_DPS:SetText("0")
|
||||
|
||||
labelGroupDamage:SetPoint("center", f, "center", 0, 10)
|
||||
labelGroupDamage_DPS:SetPoint("center", labelGroupDamage, "center")
|
||||
labelGroupDamage_DPS:SetPoint("top", labelGroupDamage, "bottom", 0, spacing_vertical)
|
||||
|
||||
--frame update function
|
||||
|
||||
--update
|
||||
local time_fraction = 100/1000 --one tick per 100ms
|
||||
f.NextUpdate = time_fraction --when the next tick occur
|
||||
f.NextScreenUpdate = Details.realtime_dps_meter.update_interval --when the labels on the frame receive update
|
||||
|
||||
--arena
|
||||
f.PlayerTeamBuffer = {}
|
||||
f.YellowTeamBuffer = {}
|
||||
f.PlayerTeamDamage = 0
|
||||
f.YellowDamage = 0
|
||||
f.LastPlayerTeamDamage = 0
|
||||
f.LastYellowDamage = 0
|
||||
|
||||
--mythic dungeon / party group
|
||||
f.GroupBuffer = {}
|
||||
f.GroupTotalDamage = 0
|
||||
f.LastTickGroupDamage = 0
|
||||
|
||||
--general
|
||||
f.SampleSize = Details.realtime_dps_meter.sample_size
|
||||
f.MaxBufferIndex = 1
|
||||
f.ShowingArena = false
|
||||
|
||||
function Details:UpdateTheRealCurrentDPSFrame(scenario)
|
||||
--don't run if the featured hasn't loaded
|
||||
if (not f) then
|
||||
return
|
||||
end
|
||||
|
||||
if (not Details.realtime_dps_meter.enabled) then
|
||||
f:Hide()
|
||||
--print("D! debug currentdps.lua > !realtime_dps_meter.enabled")
|
||||
return
|
||||
end
|
||||
|
||||
if (not Details.realtime_dps_meter.arena_enabled and not Details.realtime_dps_meter.mythic_dungeon_enabled) then
|
||||
f:Hide()
|
||||
print("D! debug currentdps.lua > not _detalhes.realtime_dps_meter.arena_enabled and not _detalhes.realtime_dps_meter.mythic_dungeon_enabled")
|
||||
return
|
||||
end
|
||||
|
||||
--where the player are
|
||||
if (scenario == "arena") then
|
||||
|
||||
f.SampleSize = Details.realtime_dps_meter.sample_size
|
||||
|
||||
labelPlayerTeam_DPS:Show()
|
||||
labelYellowTeam_DPS:Show()
|
||||
|
||||
--update arena labels
|
||||
DF:SetFontColor(labelPlayerTeam_DPS, Details.realtime_dps_meter.font_color)
|
||||
DF:SetFontFace (labelPlayerTeam_DPS, Details.realtime_dps_meter.font_face)
|
||||
DF:SetFontSize(labelPlayerTeam_DPS, Details.realtime_dps_meter.font_size)
|
||||
DF:SetFontOutline (labelPlayerTeam_DPS, Details.realtime_dps_meter.font_shadow)
|
||||
|
||||
DF:SetFontColor(labelYellowTeam_DPS, Details.realtime_dps_meter.font_color)
|
||||
DF:SetFontFace (labelYellowTeam_DPS, Details.realtime_dps_meter.font_face)
|
||||
DF:SetFontSize(labelYellowTeam_DPS, Details.realtime_dps_meter.font_size)
|
||||
DF:SetFontOutline (labelYellowTeam_DPS, Details.realtime_dps_meter.font_shadow)
|
||||
|
||||
--wipe current data for arena
|
||||
Details:Destroy(f.PlayerTeamBuffer)
|
||||
Details:Destroy(f.YellowTeamBuffer)
|
||||
|
||||
--reset damage
|
||||
f.PlayerTeamDamage = 0
|
||||
f.YellowDamage = 0
|
||||
|
||||
--reset last tick damage
|
||||
f.LastPlayerTeamDamage = 0
|
||||
f.LastYellowDamage = 0
|
||||
|
||||
f:Show()
|
||||
DetailsArenaDpsBars:Show()
|
||||
DetailsArenaDpsBars.splitBar:Show()
|
||||
barFrame.splitBar:EnableAnimations()
|
||||
|
||||
DetailsArenaDpsBars.splitBar:SetSize(Details.realtime_dps_meter.frame_settings.width, Details.realtime_dps_meter.frame_settings.height)
|
||||
DetailsArenaDpsBars:EnableMouse(false)
|
||||
DetailsArenaDpsBars.splitBar:EnableMouse(false)
|
||||
|
||||
TitleString:SetPoint("bottom", DetailsArenaDpsBars.splitBar.widget, "top", 0, 15)
|
||||
TitleBackground:SetPoint("bottomleft", DetailsArenaDpsBars.splitBar.widget, "topleft", 0, 15)
|
||||
TitleBackground:SetPoint("bottomright", DetailsArenaDpsBars.splitBar.widget, "topright", 0, 15)
|
||||
|
||||
--hide group widgets
|
||||
labelGroupDamage:Hide()
|
||||
labelGroupDamage_DPS:Hide()
|
||||
f.dpsBarFrame:Hide()
|
||||
|
||||
elseif (scenario == "mythicdungeon") then
|
||||
labelGroupDamage:Show()
|
||||
labelGroupDamage_DPS:Show()
|
||||
|
||||
DF:SetFontColor(labelGroupDamage_DPS, Details.realtime_dps_meter.font_color)
|
||||
DF:SetFontFace (labelGroupDamage_DPS, Details.realtime_dps_meter.font_face)
|
||||
DF:SetFontSize(labelGroupDamage_DPS, Details.realtime_dps_meter.font_size)
|
||||
DF:SetFontOutline (labelGroupDamage_DPS, Details.realtime_dps_meter.font_shadow)
|
||||
|
||||
--wipe current data for mythic dungeon
|
||||
f.GroupBuffer = {}
|
||||
|
||||
--reset damage
|
||||
f.GroupTotalDamage = 0
|
||||
|
||||
--reset last tick damage
|
||||
f.LastTickGroupDamage = 0
|
||||
|
||||
--show the frame
|
||||
f:Show()
|
||||
|
||||
--hide arena widgets
|
||||
DetailsArenaDpsBars:Hide()
|
||||
DetailsArenaDpsBars.splitBar:Hide()
|
||||
labelPlayerTeam_DPS:Hide()
|
||||
labelYellowTeam_DPS:Hide()
|
||||
end
|
||||
|
||||
--frame position
|
||||
f:SetSize(Details.realtime_dps_meter.frame_settings.width, Details.realtime_dps_meter.frame_settings.height)
|
||||
LibWindow.RegisterConfig(f, Details.realtime_dps_meter.frame_settings)
|
||||
LibWindow.RestorePosition(f)
|
||||
|
||||
--backdrop color
|
||||
f:SetBackdropColor(unpack(Details.realtime_dps_meter.frame_settings.backdrop_color))
|
||||
|
||||
--set frame size
|
||||
f:SetSize(Details.realtime_dps_meter.frame_settings.width, Details.realtime_dps_meter.frame_settings.height)
|
||||
|
||||
--frame is locked
|
||||
if (Details.realtime_dps_meter.frame_settings.locked) then
|
||||
f:EnableMouse(false)
|
||||
else
|
||||
f:EnableMouse(true)
|
||||
end
|
||||
|
||||
--frame can show title
|
||||
if (Details.realtime_dps_meter.frame_settings.show_title) then
|
||||
TitleString:Show()
|
||||
TitleBackground:Show()
|
||||
else
|
||||
TitleString:Hide()
|
||||
TitleBackground:Hide()
|
||||
end
|
||||
|
||||
--frame strata
|
||||
f:SetFrameStrata(Details.realtime_dps_meter.frame_settings.strata)
|
||||
|
||||
--calcule buffer size
|
||||
f.MaxBufferIndex = f.SampleSize * time_fraction * 100 --sample size in seconds * fraction * tick milliseconds
|
||||
|
||||
--interval to update the frame
|
||||
f.NextScreenUpdate = Details.realtime_dps_meter.update_interval
|
||||
|
||||
|
||||
labelPlayerTeam_DPS:SetPoint("left", barFrame.splitBar.widget, "left", 4 + Details.realtime_dps_meter.text_offset, 0)
|
||||
labelYellowTeam_DPS:SetPoint("right", barFrame.splitBar.widget, "right", -4 - Details.realtime_dps_meter.text_offset, 0)
|
||||
end
|
||||
|
||||
Details:UpdateTheRealCurrentDPSFrame()
|
||||
|
||||
local on_tick = function(self, deltaTime)
|
||||
self.NextUpdate = self.NextUpdate - deltaTime
|
||||
|
||||
if (self.NextUpdate <= 0) then
|
||||
--update string
|
||||
local currentCombat = Details:GetCombat()
|
||||
local damageContainer = currentCombat:GetContainer (DETAILS_ATTRIBUTE_DAMAGE)
|
||||
|
||||
--show the current dps during an arena match
|
||||
if (self.ShowingArena) then
|
||||
--the team damage done at this tick
|
||||
local thisTickPlayerTeamDamage = 0
|
||||
local thisTickYellowDamage = 0
|
||||
|
||||
for i, actor in damageContainer:ListActors() do
|
||||
--actor.arena_team = actor.arena_team or 0 --debug
|
||||
if (actor:IsPlayer() and actor.arena_team) then
|
||||
if (actor.arena_team == 0) then
|
||||
--green team / player team
|
||||
thisTickPlayerTeamDamage = thisTickPlayerTeamDamage + actor.total
|
||||
else
|
||||
--yellow
|
||||
thisTickYellowDamage = thisTickYellowDamage + actor.total
|
||||
end
|
||||
|
||||
if (actor.nome == Details.playername) then
|
||||
--if player isn't in green team > swap colors
|
||||
if (f.PlayerTeam ~= actor.arena_team) then
|
||||
f.SwapArenaTeamColors()
|
||||
f.PlayerTeam = actor.arena_team
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--calculate how much damage the team made on this tick
|
||||
local playerTeamDamageDone = thisTickPlayerTeamDamage - f.LastPlayerTeamDamage
|
||||
local yellowDamageDone = thisTickYellowDamage - f.LastYellowDamage
|
||||
|
||||
--add the damage to buffer
|
||||
table.insert(f.PlayerTeamBuffer, 1, playerTeamDamageDone)
|
||||
table.insert(f.YellowTeamBuffer, 1, yellowDamageDone)
|
||||
|
||||
--save the current damage amount
|
||||
f.LastPlayerTeamDamage = thisTickPlayerTeamDamage
|
||||
f.LastYellowDamage = thisTickYellowDamage
|
||||
|
||||
--add the damage to current total damage
|
||||
f.PlayerTeamDamage = f.PlayerTeamDamage + playerTeamDamageDone
|
||||
f.YellowDamage = f.YellowDamage + yellowDamageDone
|
||||
|
||||
--remove player team damage
|
||||
local removedDamage = tremove(f.PlayerTeamBuffer, f.MaxBufferIndex+1)
|
||||
if (removedDamage) then
|
||||
f.PlayerTeamDamage = f.PlayerTeamDamage - removedDamage
|
||||
--be save
|
||||
f.PlayerTeamDamage = max(0, f.PlayerTeamDamage)
|
||||
end
|
||||
|
||||
--remove yellow damage
|
||||
local removedDamage = tremove(f.YellowTeamBuffer, f.MaxBufferIndex+1)
|
||||
if (removedDamage) then
|
||||
f.YellowDamage = f.YellowDamage - removedDamage
|
||||
--be save
|
||||
f.YellowDamage = max(0, f.YellowDamage)
|
||||
end
|
||||
|
||||
self.NextScreenUpdate = self.NextScreenUpdate - time_fraction --always 0.1
|
||||
|
||||
--update double bar
|
||||
local teamGreenDps = self.PlayerTeamDamage / self.SampleSize
|
||||
local teamYellowDps = self.YellowDamage / self.SampleSize
|
||||
local totalDamage = teamGreenDps + teamYellowDps
|
||||
local dpsBarFrame = DetailsArenaDpsBars.splitBar
|
||||
|
||||
--a percenntagem na barra esta sendo setada corretamente, porem a animação não esta funcrtionando ainda
|
||||
local percentValue = 0
|
||||
if (totalDamage > 0) then
|
||||
percentValue = teamGreenDps / totalDamage
|
||||
end
|
||||
percentValue = Saturate(percentValue)
|
||||
|
||||
--print(percentValue)
|
||||
DetailsArenaDpsBars.splitBar:SetValueWithAnimation(percentValue)
|
||||
DetailsArenaDpsBars:Show()
|
||||
|
||||
if (f.PlayerTeam == 0) then
|
||||
local team1Alpha = DF:MapRangeClamped(.5, 1, 1, .7, percentValue)
|
||||
local team2Alpha = DF:MapRangeClamped(0, .5, .7, 1, percentValue)
|
||||
|
||||
do
|
||||
local cR, cG, cB, cA = dpsBarFrame:GetLeftColor()
|
||||
local alphaTeam1Value = DF:LerpLinearColor(deltaTime, 1, cA, 0, 0, team1Alpha, 0, 0)
|
||||
local r, g, b = unpack(green_team_color)
|
||||
dpsBarFrame:SetLeftColor(r, g, b, alphaTeam1Value)
|
||||
end
|
||||
|
||||
do
|
||||
local cR, cG, cB, cA = dpsBarFrame:GetRightColor()
|
||||
local alphaTeam2Value = DF:LerpLinearColor(deltaTime, 1, cA, 0, 0, team2Alpha, 0, 0)
|
||||
local r, g, b = unpack(yellow_team_color)
|
||||
dpsBarFrame:SetRightColor(r, g, b, alphaTeam2Value)
|
||||
end
|
||||
else
|
||||
--not in use, player team is forced to 0
|
||||
dpsBarFrame:SetLeftColor(unpack(yellow_team_color))
|
||||
dpsBarFrame:SetRightColor(unpack(green_team_color))
|
||||
end
|
||||
|
||||
if (Details.realtime_dps_meter.frame_settings.locked) then
|
||||
f.movemeLabel:Hide()
|
||||
f.lockButton:Hide()
|
||||
f:SetBackdropColor(.2, .2, .2, 0)
|
||||
end
|
||||
|
||||
if (self.NextScreenUpdate <= 0) then
|
||||
if (f.PlayerTeam == 0) then
|
||||
labelPlayerTeam_DPS:SetText(Details:ToK2 (self.PlayerTeamDamage / self.SampleSize))
|
||||
labelYellowTeam_DPS:SetText(Details:ToK2 (self.YellowDamage / self.SampleSize))
|
||||
else
|
||||
labelPlayerTeam_DPS:SetText(Details:ToK2 (self.YellowDamage / self.SampleSize))
|
||||
labelYellowTeam_DPS:SetText(Details:ToK2 (self.PlayerTeamDamage / self.SampleSize))
|
||||
end
|
||||
f.NextScreenUpdate = Details.realtime_dps_meter.update_interval
|
||||
end
|
||||
|
||||
elseif (self.ShowingMythicDungeon) then
|
||||
|
||||
--iniciava um novo combate e tinha o buffer do combate anterior
|
||||
--ent�o dava o total de dano do combate recente menos o que tinha no buffer do round anterior
|
||||
|
||||
--the party damage done at this tick
|
||||
local thisTickGroupDamage = 0
|
||||
|
||||
for i, actor in damageContainer:ListActors() do
|
||||
if (actor:IsPlayer() and actor:IsGroupPlayer()) then
|
||||
thisTickGroupDamage = thisTickGroupDamage + actor.total
|
||||
end
|
||||
end
|
||||
|
||||
--calculate how much damage the team made on this tick
|
||||
local groupDamageDoneOnThisTick = thisTickGroupDamage - f.LastTickGroupDamage
|
||||
|
||||
--add the damage to buffer
|
||||
table.insert(f.GroupBuffer, 1, groupDamageDoneOnThisTick)
|
||||
|
||||
--save the current damage amount
|
||||
f.LastTickGroupDamage = thisTickGroupDamage
|
||||
|
||||
--add the damage to current total damage
|
||||
f.GroupTotalDamage = f.GroupTotalDamage + groupDamageDoneOnThisTick
|
||||
|
||||
--cicle buffer removing the last index and subtract its damage
|
||||
local removedDamage = tremove(f.GroupBuffer, f.MaxBufferIndex+1)
|
||||
if (removedDamage) then
|
||||
--remove the value from the total damage
|
||||
f.GroupTotalDamage = f.GroupTotalDamage - removedDamage
|
||||
--be save
|
||||
f.GroupTotalDamage = max(0, f.GroupTotalDamage)
|
||||
end
|
||||
|
||||
self.NextScreenUpdate = self.NextScreenUpdate - time_fraction
|
||||
if (self.NextScreenUpdate <= 0) then
|
||||
labelGroupDamage_DPS:SetText(Details:ToK2 (f.GroupTotalDamage / self.SampleSize))
|
||||
f.NextScreenUpdate = Details.realtime_dps_meter.update_interval
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--set next update time
|
||||
self.NextUpdate = time_fraction
|
||||
end
|
||||
end
|
||||
|
||||
f:SetScript("OnHide", function()
|
||||
f.ShowingArena = false
|
||||
f.ShowingMythicDungeon = false
|
||||
f:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
|
||||
function f:StartForArenaMatch()
|
||||
--seems not to call any show()
|
||||
if (not f.ShowingArena) then
|
||||
Details:UpdateTheRealCurrentDPSFrame("arena")
|
||||
|
||||
f.ShowingArena = true
|
||||
f:SetScript("OnUpdate", on_tick)
|
||||
end
|
||||
end
|
||||
|
||||
function f:StartForMythicDungeon()
|
||||
if (not f.ShowingMythicDungeon) then
|
||||
f.ShowingMythicDungeon = true
|
||||
f:SetScript("OnUpdate", on_tick)
|
||||
end
|
||||
end
|
||||
|
||||
local eventListener = Details:CreateEventListener()
|
||||
|
||||
function eventListener:ArenaStarted()
|
||||
if (Details.realtime_dps_meter.arena_enabled) then
|
||||
--it is working here, f:StartForArenaMatch() is called but the frame is still now shown.
|
||||
f:StartForArenaMatch()
|
||||
end
|
||||
end
|
||||
|
||||
function eventListener:MythicDungeonStarted()
|
||||
if (Details.realtime_dps_meter.mythic_dungeon_enabled) then
|
||||
f:StartForMythicDungeon()
|
||||
end
|
||||
end
|
||||
|
||||
function eventListener:ArenaEnded()
|
||||
f:Hide()
|
||||
end
|
||||
|
||||
function eventListener:MythicDungeonEnded()
|
||||
f:Hide()
|
||||
end
|
||||
|
||||
function eventListener:ResetBuffer()
|
||||
if (f:IsShown()) then
|
||||
Details:Destroy(f.PlayerTeamBuffer)
|
||||
Details:Destroy(f.YellowTeamBuffer)
|
||||
Details:Destroy(f.GroupBuffer)
|
||||
f.GroupTotalDamage = 0
|
||||
f.PlayerTeamDamage = 0
|
||||
f.YellowDamage = 0
|
||||
f.LastTickGroupDamage = 0
|
||||
f.LastPlayerTeamDamage = 0
|
||||
f.LastYellowDamage = 0
|
||||
end
|
||||
end
|
||||
|
||||
eventListener:RegisterEvent("COMBAT_ARENA_START", "ArenaStarted")
|
||||
eventListener:RegisterEvent("COMBAT_ARENA_END", "ArenaEnded")
|
||||
eventListener:RegisterEvent("COMBAT_MYTHICDUNGEON_START", "MythicDungeonStarted")
|
||||
eventListener:RegisterEvent("COMBAT_MYTHICDUNGEON_END", "MythicDungeonEnded")
|
||||
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", "ResetBuffer")
|
||||
|
||||
Details.Broadcaster_CurrentDpsLoaded = true
|
||||
Details.Broadcaster_CurrentDpsFrame = f
|
||||
C_Timer.After(1, lockCallback)
|
||||
f:Hide()
|
||||
end
|
||||
|
||||
function DetailsTestSplitBar()
|
||||
|
||||
--create the frame
|
||||
local f = CreateFrame("frame", "DetailsTestSplitBarFrame", UIParent)
|
||||
f:SetSize(400, 200)
|
||||
f:SetPoint("center")
|
||||
local backgroundTexture = f:CreateTexture(nil, "overlay")
|
||||
backgroundTexture:SetAllPoints()
|
||||
backgroundTexture:SetTexture(.1, .1, .1, .7)
|
||||
|
||||
local barFrame = CreateFrame("frame", "DetailsArenaDpsBars", f, "BackdropTemplate")
|
||||
f.dpsBarFrame = barFrame
|
||||
barFrame:SetSize(400, 80)
|
||||
barFrame:SetPoint("center", f, "center", 0, 50)
|
||||
DF:ApplyStandardBackdrop(barFrame)
|
||||
|
||||
barFrame.splitBar = DF:CreateSplitBar(barFrame, 400, 50)
|
||||
barFrame.splitBar:SetSize(400, 50)
|
||||
barFrame.splitBar:SetPoint("center", barFrame, "center", 0, 0)
|
||||
barFrame.splitBar.fontsize = 10
|
||||
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
barFrame.splitBar:SetTexture(SharedMedia:Fetch("statusbar", "Details Flat"))
|
||||
|
||||
barFrame.splitBar:SetLeftColor(unpack(green_team_color))
|
||||
barFrame.splitBar:SetRightColor(unpack(yellow_team_color))
|
||||
|
||||
--test the splitbar
|
||||
local loopTime = 0.1
|
||||
f:SetScript("OnUpdate", function(self, deltaTime)
|
||||
loopTime = loopTime - deltaTime
|
||||
if (loopTime <= 0) then
|
||||
local value = abs(1.0 * math.sin((math.pi*2) * (GetTime() * 0.1)))
|
||||
local value = math.random()
|
||||
barFrame.splitBar:SetValueWithAnimation(value)
|
||||
loopTime = 0.1
|
||||
end
|
||||
end)
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local _
|
||||
|
||||
--local AceComm = LibStub("AceComm-3.0")
|
||||
--local AceSerializer = LibStub("AceSerializer-3.0")
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
local CONST_MENU_X_POSITION = 10
|
||||
local CONST_MENU_Y_POSITION = -40
|
||||
local CONST_MENU_WIDTH = 160
|
||||
local CONST_MENU_HEIGHT = 20
|
||||
|
||||
local CONST_INFOBOX_X_POSITION = 220
|
||||
local CONST_EDITBUTTONS_X_POSITION = 560
|
||||
|
||||
local CONST_EDITBOX_Y_POSITION = -200
|
||||
local CONST_EDITBOX_WIDTH = 900
|
||||
local CONST_EDITBOX_HEIGHT = 370
|
||||
|
||||
local CONST_EDITBOX_BUTTON_WIDTH = 80
|
||||
local CONST_EDITBOX_BUTTON_HEIGHT = 20
|
||||
|
||||
local CONST_BUTTON_TEMPLATE = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
local CONST_TEXTENTRY_TEMPLATE = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
DF:InstallTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BUTTONS",
|
||||
{
|
||||
icon = {texture = [[Interface\BUTTONS\UI-GuildButton-PublicNote-Up]]},
|
||||
width = 160,
|
||||
},
|
||||
"DETAILS_PLUGIN_BUTTON_TEMPLATE"
|
||||
)
|
||||
|
||||
DF:InstallTemplate("button", "DETAILS_CUSTOMDISPLAY_REGULAR_BUTTON",
|
||||
{
|
||||
width = 130,
|
||||
},
|
||||
"DETAILS_PLUGIN_BUTTON_TEMPLATE"
|
||||
)
|
||||
|
||||
DF:InstallTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX", {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.2, .2, .2, 0.6},
|
||||
backdropbordercolor = {0, 0, 0, 1},
|
||||
})
|
||||
DF:InstallTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX_EXPANDED", {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.2, .2, .2, 1},
|
||||
backdropbordercolor = {0, 0, 0, 1},
|
||||
})
|
||||
DF:InstallTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX_BUTTON", {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.2, .2, .2, 1},
|
||||
backdropbordercolor = {0, 0, 0, 1},
|
||||
})
|
||||
|
||||
DF:NewColor("DETAILS_CUSTOMDISPLAY_ICON", .7, .6, .5, 1)
|
||||
|
||||
local CONST_CODETEXTENTRY_TEMPLATE = DF:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX")
|
||||
local CONST_CODETEXTENTRYEXPANDED_TEMPLATE = DF:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX_EXPANDED")
|
||||
local CONST_CODETEXTENTRYBUTTON_TEMPLATE = DF:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BOX_BUTTON")
|
||||
local CONST_CODETEXTENTRY_OPENCODEBUTTONS_TEMPLATE = DF:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_CODE_BUTTONS")
|
||||
local CONST_REGULAR_BUTTON_TEMPLATE = DF:GetTemplate("button", "DETAILS_CUSTOMDISPLAY_REGULAR_BUTTON")
|
||||
|
||||
|
||||
--new script button
|
||||
|
||||
|
||||
--search script box
|
||||
|
||||
|
||||
--control buttons like import, export, delete, restore
|
||||
|
||||
|
||||
--build the left menu, this menu has all scripts to edit
|
||||
|
||||
|
||||
--build the script properties panel with name, icon, etc
|
||||
|
||||
|
||||
--
|
||||
@@ -0,0 +1,455 @@
|
||||
|
||||
local Details = Details
|
||||
local addonName, Details222 = ...
|
||||
---@type detailsframework
|
||||
local detailsFramework = DetailsFramework
|
||||
local _
|
||||
|
||||
--frame options
|
||||
local windowWidth = 1024
|
||||
local windowHeight = 670
|
||||
local scrollWidth = 990
|
||||
local scrollHeightBuff = 400
|
||||
local scrollHeightDebuff = 200
|
||||
local scrollLineAmountBuff = 20
|
||||
local scrollLineAmountDebuff = 10
|
||||
local scrollLineHeight = 20
|
||||
local amountOfLines = 26
|
||||
local lineHeight = 19
|
||||
|
||||
local createDebugOptionsFrame = function()
|
||||
--create a panel
|
||||
--parent, width, height, title, frameName, panelOptions
|
||||
local debugOptionsPanel = DetailsFramework:CreateSimplePanel(UIParent, windowWidth/2, windowHeight, "Details! Debug Options", "DetailsDebugOptionsPanel", {})
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(debugOptionsPanel)
|
||||
|
||||
--disable the buil-in mouse integration of the simple panel, doing this to use LibWindow-1.1 as the window management
|
||||
debugOptionsPanel:SetScript("OnMouseDown", nil)
|
||||
debugOptionsPanel:SetScript("OnMouseUp", nil)
|
||||
|
||||
--need to create a window frame button that only accepts right clicks and when clicked it'll hide the panel
|
||||
|
||||
--register in the libWindow
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(debugOptionsPanel, Details.debug_options_panel.position)
|
||||
LibWindow.MakeDraggable(debugOptionsPanel)
|
||||
LibWindow.RestorePosition(debugOptionsPanel)
|
||||
|
||||
--scale bar
|
||||
local scaleBar = DetailsFramework:CreateScaleBar(debugOptionsPanel, Details.debug_options_panel.scaletable)
|
||||
debugOptionsPanel:SetScale(Details.debug_options_panel.scaletable.scale)
|
||||
|
||||
--status bar
|
||||
local statusBar = DetailsFramework:CreateStatusBar(debugOptionsPanel)
|
||||
statusBar.text = statusBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
statusBar.text:SetPoint("left", statusBar, "left", 5, 0)
|
||||
statusBar.text:SetText("By Terciob | Part of Details! Damage Meter")
|
||||
DetailsFramework:SetFontSize(statusBar.text, 11)
|
||||
DetailsFramework:SetFontColor(statusBar.text, "gray")
|
||||
|
||||
local options = {
|
||||
{--general debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details.debug
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.debug = value
|
||||
if (not value) then
|
||||
Details:Msg("diagnostic mode has been turned off.")
|
||||
else
|
||||
Details:Msg("diagnostic mode has been turned on.")
|
||||
end
|
||||
end,
|
||||
name = "General Details! Debug",
|
||||
desc = "General Details! Debug",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{--debug net
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details.debugnet
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.debugnet = value
|
||||
if (not value) then
|
||||
Details:Msg("net diagnostic mode has been turned off.")
|
||||
else
|
||||
Details:Msg("net diagnostic mode has been turned on.")
|
||||
end
|
||||
end,
|
||||
name = "Net Diagnostic Debug",
|
||||
desc = "Net Diagnostic Debug",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{--mythic+ debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
local debugState = Details222.Debug.GetMythicPlusDebugState()
|
||||
return debugState
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.Debug.SetMythicPlusDebugState()
|
||||
end,
|
||||
name = "End of Mythic+ Panel Debug",
|
||||
desc = "Panel shown at the end of a Mythic+ dungeon",
|
||||
},
|
||||
|
||||
{--mythic+ loot debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
local _, lootDebugState = Details222.Debug.GetMythicPlusDebugState()
|
||||
return lootDebugState
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.Debug.SetMythicPlusLootDebugState()
|
||||
end,
|
||||
name = "Loot Shown in the End of Mythic+ Panel Debug",
|
||||
desc = "Loot shown in the Panel shown at the end of a Mythic+ dungeon",
|
||||
},
|
||||
|
||||
{--mythic+ chart debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details222.Debug.MythicPlusChartWindowDebug
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.Debug.MythicPlusChartWindowDebug = value
|
||||
end,
|
||||
name = "Mythic+ Chart Save and Use The Same Chart Data",
|
||||
desc = "When enabled, Details! will save the chart data from the next m+ run and use it when showing the chart panel. This save persist on saved variables and I don't think it is deleted, never.",
|
||||
--/run Details.mythic_plus.last_mythicrun_chart = {}
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{--storage debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details222.storage.IsDebug
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.storage.IsDebug = value
|
||||
if (Details222.storage.IsDebug) then
|
||||
Details:Msg("Storage Debug is ON.")
|
||||
else
|
||||
Details:Msg("Storage Debug is OFF.")
|
||||
end
|
||||
end,
|
||||
name = "Encounter Storage Debug",
|
||||
desc = "Internal tests of the storage feature.",
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{--pet debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details222.Debug.DebugPets
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.Debug.DebugPets = value
|
||||
if (Details222.Debug.DebugPets) then
|
||||
Details:Msg("Pet Debug is ON.")
|
||||
Details:ShowCleuDebugWindow(function(token, who_serial, who_name, who_flags, target_serial, target_name, target_flags, A1, A2, A3)
|
||||
if (token == "SPELL_SUMMON") then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
else
|
||||
Details:Msg("Pet Debug is OFF.")
|
||||
end
|
||||
end,
|
||||
name = "General Pet Debug",
|
||||
desc = "General Pet Debug",
|
||||
},
|
||||
|
||||
{--pet debug
|
||||
type = "toggle",
|
||||
get = function()
|
||||
return Details222.Debug.DebugPlayerPets
|
||||
end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details222.Debug.DebugPlayerPets = value
|
||||
if (Details222.Debug.DebugPlayerPets) then
|
||||
Details:Msg("Player Pet Debug is ON.")
|
||||
Details:ShowCleuDebugWindow(function(token, who_serial, sourceName, who_flags, target_serial, target_name, target_flags, A1, A2, A3)
|
||||
if (token == "SPELL_SUMMON") then
|
||||
if (sourceName == Details.playername) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
Details:Msg("Player Pet Debug is OFF.")
|
||||
end
|
||||
end,
|
||||
name = "Player Pets Debug",
|
||||
desc = "Player Pets Debug",
|
||||
},
|
||||
}
|
||||
|
||||
--/run Details:GetWindow(1):GetActorInfoFromLineIndex(3)
|
||||
|
||||
--create a label with the text "actor info from window and line index"
|
||||
local actorInfoLabel = detailsFramework:CreateLabel(debugOptionsPanel, "Get Actor Info From Window 'X' and Line Index 'X'", 12)
|
||||
actorInfoLabel:SetPoint("bottomleft", debugOptionsPanel, "bottomleft", 5, 50)
|
||||
|
||||
local instanceIdEntry = detailsFramework:CreateTextEntry(debugOptionsPanel, function()end, 20, 20, _, _, _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
instanceIdEntry:SetPoint("topleft", actorInfoLabel, "bottomleft", 0, -5)
|
||||
instanceIdEntry:SetText("1")
|
||||
|
||||
local lineIndexEntry = detailsFramework:CreateTextEntry(debugOptionsPanel, function()end, 20, 20, _, _, _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
lineIndexEntry:SetPoint("left", instanceIdEntry, "right", 5, 0)
|
||||
lineIndexEntry:SetText("1")
|
||||
|
||||
--create a button with the get "Get", when the button is pressed, it get the text in the instanceIdEntry and lineIndexEntry and call the function GetActorInfoFromWindowAndLineIndex
|
||||
local getButton = detailsFramework:CreateButton(debugOptionsPanel, function()
|
||||
local instanceId = tonumber(instanceIdEntry:GetText())
|
||||
local lineIndex = tonumber(lineIndexEntry:GetText())
|
||||
Details:GetWindow(instanceId):GetActorInfoFromLineIndex(lineIndex)
|
||||
end, 50, 20, "Get")
|
||||
getButton:SetPoint("left", lineIndexEntry, "right", 5, 0)
|
||||
getButton:SetTemplate(detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
|
||||
options.always_boxfirst = true
|
||||
options.align_as_pairs = true
|
||||
options.align_as_pairs_string_space = 260
|
||||
|
||||
--templates
|
||||
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
detailsFramework:BuildMenu(debugOptionsPanel, options, 5, -40, windowHeight - 50, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
end
|
||||
|
||||
function Details.ShowDebugOptionsPanel()
|
||||
if (DetailsDebugOptionsPanel) then
|
||||
DetailsDebugOptionsPanel:Show()
|
||||
else
|
||||
createDebugOptionsFrame()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Details:ShowCleuDebugWindow(filterFunction)
|
||||
if (not DetailsCleuDebugWindow) then
|
||||
--create a simple panel from the framework with size of 400 x 800
|
||||
--this panel will have a scrollbox with 20 lines, these lines will show data
|
||||
--each line will have an icon, 6 text entries and 3 labels
|
||||
--the scrollbox is attached to a header frame from the framework for organization
|
||||
|
||||
--create a panel
|
||||
--parent, width, height, title, frameName, panelOptions
|
||||
local cleuDebugPanel = detailsFramework:CreateSimplePanel(UIParent, windowWidth, windowHeight, "Details! Cleu Debug", "DetailsCleuDebugWindow", {})
|
||||
detailsFramework:ApplyStandardBackdrop(cleuDebugPanel)
|
||||
|
||||
cleuDebugPanel:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
|
||||
cleuDebugPanel:SetScript("OnShow", function()
|
||||
cleuDebugPanel:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
end)
|
||||
|
||||
cleuDebugPanel:SetScript("OnHide", function()
|
||||
cleuDebugPanel:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
end)
|
||||
|
||||
--disable the buil-in mouse integration of the simple panel, doing this to use LibWindow-1.1 as the window management
|
||||
cleuDebugPanel:SetScript("OnMouseDown", nil)
|
||||
cleuDebugPanel:SetScript("OnMouseUp", nil)
|
||||
|
||||
--need to create a window frame button that only accepts right clicks and when clicked it'll hide the panel
|
||||
|
||||
--register in the libWindow
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(cleuDebugPanel, Details.cleu_debug_panel.position)
|
||||
LibWindow.MakeDraggable(cleuDebugPanel)
|
||||
LibWindow.RestorePosition(cleuDebugPanel)
|
||||
|
||||
--scale bar
|
||||
local scaleBar = detailsFramework:CreateScaleBar(cleuDebugPanel, Details.cleu_debug_panel.scaletable)
|
||||
cleuDebugPanel:SetScale(Details.cleu_debug_panel.scaletable.scale)
|
||||
|
||||
--status bar
|
||||
local statusBar = detailsFramework:CreateStatusBar(cleuDebugPanel)
|
||||
statusBar.text = statusBar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
statusBar.text:SetPoint("left", statusBar, "left", 5, 0)
|
||||
statusBar.text:SetText("By Terciob | Part of Details! Damage Meter")
|
||||
detailsFramework:SetFontSize(statusBar.text, 11)
|
||||
detailsFramework:SetFontColor(statusBar.text, "gray")
|
||||
|
||||
---@type df_headercolumndata[]
|
||||
local headerTable = {
|
||||
{text = "", width = 20},
|
||||
{text = "Source Name", width = 150},
|
||||
{text = "Spell Name", width = 150},
|
||||
{text = "Pet Name", width = 150},
|
||||
{text = "Spell ID", width = 50},
|
||||
{text = "Data 1", width = 150},
|
||||
{text = "Data 2", width = 150},
|
||||
{text = "Data 3", width = 150},
|
||||
}
|
||||
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
---@type df_headerframe
|
||||
local headerFrame = detailsFramework:CreateHeader(cleuDebugPanel, headerTable, headerOptions)
|
||||
cleuDebugPanel.Header = headerFrame
|
||||
|
||||
local onRefreshScroll = function(self, data, offSet, totalLines)
|
||||
for i = 1, totalLines do
|
||||
local index = i + offSet
|
||||
local spellData = data[index]
|
||||
if (spellData) then
|
||||
local time, token, sourceGUID, sourceName, sourceFlags, targetGUID, targetName, targetFlags, A1, A2, A3 = unpack(spellData)
|
||||
|
||||
local line = self:GetLine(i)
|
||||
if (line) then
|
||||
line.Icon:SetTexture(select(3, Details222.GetSpellInfo(A1)))
|
||||
line.casterNameText:SetText(sourceName)
|
||||
line.spellNameText:SetText(A2)
|
||||
line.targetNameText:SetText(targetName)
|
||||
line.spellIdText:SetText(A1)
|
||||
|
||||
if (Details222.Debug.DebugPets or Details222.Debug.DebugPlayerPets) then
|
||||
local petContainer = Details222.PetContainer
|
||||
---@type petdata?
|
||||
local petData = petContainer.GetPetInfo(targetGUID)
|
||||
if (petData) then
|
||||
--print(targetGUID, petData.ownerName, petData.petName, petData.petFlags)
|
||||
line.data1Text:SetText(petData.ownerName)
|
||||
line.data2Text:SetText(petData.petName)
|
||||
line.data3Text:SetText(petData.petFlags)
|
||||
else
|
||||
line.data1Text:SetText("Pet not found")
|
||||
line.data2Text:SetText("")
|
||||
line.data3Text:SetText("")
|
||||
end
|
||||
else
|
||||
line.data1Text:SetText("")
|
||||
line.data2Text:SetText("")
|
||||
line.data3Text:SetText("")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local dropdownTemplate = DetailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWNDARK_TEMPLATE")
|
||||
|
||||
local createLineFunc = function(self, index)
|
||||
--create the line for a scrollbox
|
||||
local line = CreateFrame("frame", "$parentLine" .. index, self, "BackdropTemplate")
|
||||
--set the point using the line index, line height and scrollbox width
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(lineHeight+1)) - 1)
|
||||
line:SetSize(scrollWidth - 2, lineHeight)
|
||||
|
||||
--import functions from the header feature
|
||||
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||||
|
||||
--create the spell icon texture
|
||||
local icon = line:CreateTexture(nil, "overlay")
|
||||
icon:SetSize(lineHeight-2, lineHeight-2)
|
||||
|
||||
--create the caster name text entry
|
||||
local casterNameText = DetailsFramework:CreateTextEntry(line, function()end, headerTable[2].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
|
||||
--create the spell name text entry
|
||||
local spellNameText = DetailsFramework:CreateTextEntry(line, function()end, headerTable[3].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
|
||||
--create the target name text entry
|
||||
local targetNameText = DetailsFramework:CreateTextEntry(line, function()end, headerTable[4].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
|
||||
--create the spell id text entry
|
||||
local spellIdText = DetailsFramework:CreateTextEntry(line, function()end, headerTable[5].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
|
||||
--create a negeric text entry
|
||||
local data1Text = DetailsFramework:CreateTextEntry(line, function()end, headerTable[6].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
--create a negeric text entry
|
||||
local data2Text = DetailsFramework:CreateTextEntry(line, function()end, headerTable[7].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
--create a negeric text entry
|
||||
local data3Text = DetailsFramework:CreateTextEntry(line, function()end, headerTable[8].width, lineHeight, _, _, _, dropdownTemplate)
|
||||
|
||||
line:AddFrameToHeaderAlignment(icon)
|
||||
line:AddFrameToHeaderAlignment(casterNameText)
|
||||
line:AddFrameToHeaderAlignment(spellNameText)
|
||||
line:AddFrameToHeaderAlignment(targetNameText)
|
||||
line:AddFrameToHeaderAlignment(spellIdText)
|
||||
line:AddFrameToHeaderAlignment(data1Text)
|
||||
line:AddFrameToHeaderAlignment(data2Text)
|
||||
line:AddFrameToHeaderAlignment(data3Text)
|
||||
|
||||
line:AlignWithHeader(headerFrame, "left")
|
||||
|
||||
line.Icon = icon
|
||||
line.casterNameText = casterNameText
|
||||
line.spellNameText = spellNameText
|
||||
line.targetNameText = targetNameText
|
||||
line.spellIdText = spellIdText
|
||||
line.data1Text = data1Text
|
||||
line.data2Text = data2Text
|
||||
line.data3Text = data3Text
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
cleuDebugPanel.ScrollBoxData = {}
|
||||
--create a scrollbox
|
||||
---@type df_scrollbox
|
||||
local scrollBox = detailsFramework:CreateScrollBox(cleuDebugPanel, "$parentScrollBox", onRefreshScroll, cleuDebugPanel.ScrollBoxData, scrollWidth, windowHeight - 60, amountOfLines, lineHeight)
|
||||
scrollBox:SetPoint("topleft", cleuDebugPanel, "topleft", 5, -46)
|
||||
cleuDebugPanel.ScrollBox = scrollBox
|
||||
|
||||
cleuDebugPanel.Header:SetPoint("bottomleft", scrollBox, "topleft", 0, 2)
|
||||
|
||||
for i = 1, amountOfLines do
|
||||
--just call the line creation function with the scrollbox as the parent argument and the line index
|
||||
scrollBox:CreateLine(createLineFunc)
|
||||
end
|
||||
|
||||
local bHasScheduled = false
|
||||
|
||||
cleuDebugPanel:SetScript("OnEvent", function()
|
||||
local time, token, hidding, who_serial, who_name, who_flags, who_flags2, target_serial, target_name, target_flags, target_flags2, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12 = CombatLogGetCurrentEventInfo()
|
||||
local addLine = filterFunction(token, who_serial, who_name, who_flags, target_serial, target_name, target_flags, A1, A2, A3)
|
||||
if (addLine) then
|
||||
table.insert(cleuDebugPanel.ScrollBoxData, {
|
||||
GetTime() - cleuDebugPanel.Time,
|
||||
token,
|
||||
who_serial,
|
||||
who_name,
|
||||
who_flags,
|
||||
target_serial,
|
||||
target_name,
|
||||
target_flags,
|
||||
A1,
|
||||
A2,
|
||||
A3
|
||||
})
|
||||
|
||||
if (not bHasScheduled) then
|
||||
bHasScheduled = true
|
||||
C_Timer.After(0.1, function()
|
||||
bHasScheduled = false
|
||||
scrollBox:Refresh()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
DetailsCleuDebugWindow:Show()
|
||||
table.wipe(DetailsCleuDebugWindow.ScrollBoxData) --clear the data
|
||||
DetailsCleuDebugWindow.ScrollBox:Refresh()
|
||||
DetailsCleuDebugWindow.Time = GetTime()
|
||||
end
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DetailsFramework = _G.DetailsFramework
|
||||
local C_Timer = _G.C_Timer
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--dump table frame
|
||||
|
||||
function Details:DumpTable (t)
|
||||
return Details:Dump (t)
|
||||
end
|
||||
|
||||
function Details:DumpInline(t)
|
||||
for key, value in pairs(t) do
|
||||
print(key, value)
|
||||
end
|
||||
end
|
||||
|
||||
function Details:Dump (...)
|
||||
if (not DetailsDumpFrame) then
|
||||
DetailsDumpFrame = DetailsFramework:CreateSimplePanel(_G.UIParent)
|
||||
DetailsDumpFrame:SetSize(700, 800)
|
||||
DetailsDumpFrame:SetTitle("Details! Dump Table [|cFFFF3333Ready Only|r]")
|
||||
|
||||
local text_editor = DetailsFramework:NewSpecialLuaEditorEntry(DetailsDumpFrame, 680, 760, "Editbox", "$parentEntry", true)
|
||||
text_editor:SetPoint("topleft", DetailsDumpFrame, "topleft", 10, -30)
|
||||
|
||||
text_editor.scroll:SetBackdrop(nil)
|
||||
text_editor.editbox:SetBackdrop(nil)
|
||||
text_editor:SetBackdrop(nil)
|
||||
|
||||
DetailsFramework:ReskinSlider(text_editor.scroll)
|
||||
|
||||
if (not text_editor.__background) then
|
||||
text_editor.__background = text_editor:CreateTexture(nil, "background")
|
||||
end
|
||||
|
||||
text_editor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
text_editor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
text_editor.__background:SetTexture(0.2317647, 0.2317647, 0.2317647)
|
||||
text_editor.__background:SetVertexColor(0.27, 0.27, 0.27)
|
||||
text_editor.__background:SetAlpha(0.8)
|
||||
text_editor.__background:SetVertTile(true)
|
||||
text_editor.__background:SetHorizTile(true)
|
||||
text_editor.__background:SetAllPoints()
|
||||
end
|
||||
|
||||
local t = select(1, ...)
|
||||
if (not t) then
|
||||
Details:Msg("nothing to show on Dump.")
|
||||
return
|
||||
else
|
||||
if (type(t) == "table") then
|
||||
local s = DetailsFramework.table.dump(t)
|
||||
DetailsDumpFrame.Editbox:SetText(s)
|
||||
else
|
||||
t = {...}
|
||||
local s = DetailsFramework.table.dump(t)
|
||||
DetailsDumpFrame.Editbox:SetText(s)
|
||||
end
|
||||
end
|
||||
|
||||
DetailsDumpFrame:Show()
|
||||
end
|
||||
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------
|
||||
--import export window
|
||||
--show a window with a big text editor and 2 buttons: okay and cancel.
|
||||
--cancel button always closes the window and okay calls the comfirm function passed in the argument
|
||||
--default text is the text shown show the window is show()
|
||||
|
||||
function Details:DumpString (text)
|
||||
Details:ShowImportWindow (text)
|
||||
end
|
||||
|
||||
function Details:ShowImportWindow (defaultText, confirmFunc, titleText)
|
||||
if (not _G.DetailsExportWindow) then
|
||||
local importWindow = DetailsFramework:CreateSimplePanel(_G.UIParent, 800, 610, "Details! Dump String", "DetailsExportWindow")
|
||||
importWindow:SetFrameStrata("FULLSCREEN")
|
||||
importWindow:SetPoint("center")
|
||||
DetailsFramework:ApplyStandardBackdrop(importWindow, false, 1.2)
|
||||
|
||||
local importTextEditor = DetailsFramework:NewSpecialLuaEditorEntry(importWindow, 780, 540, "ImportEditor", "$parentEditor", true)
|
||||
importTextEditor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
importTextEditor:SetBackdropColor(.2, .2, .2, .5)
|
||||
importTextEditor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
importTextEditor:SetPoint("topleft", importWindow, "topleft", 10, -30)
|
||||
|
||||
importTextEditor.scroll:SetBackdrop(nil)
|
||||
importTextEditor.editbox:SetBackdrop(nil)
|
||||
importTextEditor:SetBackdrop(nil)
|
||||
|
||||
DetailsFramework:ReskinSlider(importTextEditor.scroll)
|
||||
|
||||
if (not importTextEditor.__background) then
|
||||
importTextEditor.__background = importTextEditor:CreateTexture(nil, "background")
|
||||
end
|
||||
|
||||
importTextEditor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
importTextEditor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
importTextEditor.__background:SetTexture(0.2317647, 0.2317647, 0.2317647)
|
||||
importTextEditor.__background:SetVertexColor(0.27, 0.27, 0.27)
|
||||
importTextEditor.__background:SetAlpha(0.8)
|
||||
importTextEditor.__background:SetVertTile(true)
|
||||
importTextEditor.__background:SetHorizTile(true)
|
||||
importTextEditor.__background:SetAllPoints()
|
||||
|
||||
--import button
|
||||
local onClickImportButton = function()
|
||||
if (_G.DetailsExportWindow.ConfirmFunction) then
|
||||
DetailsFramework:Dispatch (_G.DetailsExportWindow.ConfirmFunction, importTextEditor:GetText())
|
||||
end
|
||||
importWindow:Hide()
|
||||
end
|
||||
local okayButton = DetailsFramework:CreateButton(importTextEditor, onClickImportButton, 120, 20, "Okay", -1, nil, nil, nil, nil, nil, Details.gump:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"), Details.gump:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")) --localize-me
|
||||
okayButton:SetIcon ([[Interface\BUTTONS\UI-Panel-BiggerButton-Up]], 20, 20, "overlay", {0.1, .9, 0.1, .9})
|
||||
importTextEditor.OkayButton = okayButton
|
||||
|
||||
--cancel button
|
||||
local cancelButton = DetailsFramework:CreateButton(importTextEditor, function() importWindow:Hide() end, 120, 20, "Cancel", -1, nil, nil, nil, nil, nil, Details.gump:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"), Details.gump:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")) --localize-me
|
||||
cancelButton:SetIcon ([[Interface\BUTTONS\UI-Panel-MinimizeButton-Up]], 20, 20, "overlay", {0.1, .9, 0.1, .9})
|
||||
|
||||
okayButton:SetPoint("topright", importTextEditor, "bottomright", 0, -10)
|
||||
cancelButton:SetPoint("right", okayButton, "left", -20, 0)
|
||||
|
||||
end
|
||||
|
||||
_G.DetailsExportWindow.ConfirmFunction = confirmFunc
|
||||
_G.DetailsExportWindow.ImportEditor:SetText(defaultText or "")
|
||||
_G.DetailsExportWindow:Show()
|
||||
|
||||
titleText = titleText or "Details! Dump String"
|
||||
_G.DetailsExportWindow.Title:SetText(titleText)
|
||||
|
||||
C_Timer.After(.2, function()
|
||||
_G.DetailsExportWindow.ImportEditor:SetFocus(true)
|
||||
_G.DetailsExportWindow.ImportEditor.editbox:HighlightText (0)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,907 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local C_Timer = _G.C_Timer
|
||||
local GetSpellInfo = Details.GetSpellInfo
|
||||
local libwindow = LibStub("LibWindow-1.1")
|
||||
local playerGUID = UnitGUID('player')
|
||||
|
||||
function Details:OpenEventTrackerOptions(bFromOptionsPanel)
|
||||
if (not _G.DetailsEventTrackerOptions) then
|
||||
|
||||
local DF = DetailsFramework
|
||||
|
||||
local optionsPanel = DF:CreateSimplePanel(UIParent, 700, 400, "Details! Event Tracker Options", "DetailsEventTrackerOptions")
|
||||
optionsPanel:SetPoint("center", _G.UIParent, "center")
|
||||
optionsPanel:SetScript("OnMouseDown", nil)
|
||||
optionsPanel:SetScript("OnMouseUp", nil)
|
||||
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(optionsPanel, Details.event_tracker.options_frame)
|
||||
LibWindow.MakeDraggable(optionsPanel)
|
||||
LibWindow.RestorePosition(optionsPanel)
|
||||
|
||||
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
--frame strata options
|
||||
local set_frame_strata = function(_, _, strata)
|
||||
Details.event_tracker.frame.strata = strata
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end
|
||||
local strataTable = {}
|
||||
strataTable [1] = {value = "BACKGROUND", label = "BACKGROUND", onclick = set_frame_strata}
|
||||
strataTable [2] = {value = "LOW", label = "LOW", onclick = set_frame_strata}
|
||||
strataTable [3] = {value = "MEDIUM", label = "MEDIUM", onclick = set_frame_strata}
|
||||
strataTable [4] = {value = "HIGH", label = "HIGH", onclick = set_frame_strata}
|
||||
strataTable [5] = {value = "DIALOG", label = "DIALOG", onclick = set_frame_strata}
|
||||
|
||||
--font options
|
||||
local set_font_shadow= function(_, _, shadow)
|
||||
Details.event_tracker.font_shadow = shadow
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end
|
||||
local fontShadowTable = {}
|
||||
fontShadowTable [1] = {value = "NONE", label = "None", onclick = set_font_shadow}
|
||||
fontShadowTable [2] = {value = "OUTLINE", label = "Outline", onclick = set_font_shadow}
|
||||
fontShadowTable [3] = {value = "THICKOUTLINE", label = "Thick Outline", onclick = set_font_shadow}
|
||||
|
||||
local on_select_text_font = function(self, fixed_value, value)
|
||||
Details.event_tracker.font_face = value
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end
|
||||
|
||||
--texture options
|
||||
local set_bar_texture = function(_, _, value)
|
||||
Details.event_tracker.line_texture = value
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end
|
||||
|
||||
local SharedMedia = _G.LibStub:GetLibrary ("LibSharedMedia-3.0")
|
||||
local textures = SharedMedia:HashTable ("statusbar")
|
||||
local texTable = {}
|
||||
for name, texturePath in pairs(textures) do
|
||||
texTable [#texTable + 1] = {value = name, label = name, statusbar = texturePath, onclick = set_bar_texture}
|
||||
end
|
||||
table.sort (texTable, function(t1, t2) return t1.label < t2.label end)
|
||||
|
||||
--options table
|
||||
local options = {
|
||||
always_boxfirst = true,
|
||||
--language_addonId = addonId,
|
||||
|
||||
{type = "label", get = function() return "Frame Settings:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
--enabled
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.enabled = not Details.event_tracker.enabled
|
||||
Details:LoadFramesForBroadcastTools()
|
||||
end,
|
||||
desc = "Enabled",
|
||||
name = "Enabled",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--locked
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.frame.locked end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.frame.locked = not Details.event_tracker.frame.locked
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Locked",
|
||||
name = "Locked",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--showtitle
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.frame.show_title end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.frame.show_title = not Details.event_tracker.frame.show_title
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Show Title",
|
||||
name = "Show Title",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--backdrop color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
return {Details.event_tracker.frame.backdrop_color[1], Details.event_tracker.frame.backdrop_color[2], Details.event_tracker.frame.backdrop_color[3], Details.event_tracker.frame.backdrop_color[4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.event_tracker.frame.backdrop_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Backdrop Color",
|
||||
name = "Backdrop Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--statra
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.event_tracker.frame.strata end,
|
||||
values = function() return strataTable end,
|
||||
name = "Frame Strata"
|
||||
},
|
||||
--anonymize names
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.anonymize_names end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.anonymize_names = not Details.event_tracker.anonymize_names
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Sets all player names as the last digits of their GUID when displaying in the event tracker.",
|
||||
name = "Anonymize Player Names",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--anonymize self
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.anonymize_self end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.anonymize_self = not Details.event_tracker.anonymize_self
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Anonymize the current player's name from the event tracker.",
|
||||
name = "Anonymize Self",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Line Settings:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
--line height
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.event_tracker.line_height end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.line_height = value
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
min = 4,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Line Height",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--line texture
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.event_tracker.line_texture end,
|
||||
values = function() return texTable end,
|
||||
name = "Line Texture",
|
||||
},
|
||||
--line color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
return {Details.event_tracker.line_color[1], Details.event_tracker.line_color[2], Details.event_tracker.line_color[3], Details.event_tracker.line_color[4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.event_tracker.line_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Line Color",
|
||||
name = "Line Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--font size
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.event_tracker.font_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.font_size = value
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
min = 4,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Font Size",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--font color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
return {Details.event_tracker.font_color[1], Details.event_tracker.font_color[2], Details.event_tracker.font_color[3], Details.event_tracker.font_color[4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.event_tracker.font_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
Details:UpdateEventTrackerFrame()
|
||||
end,
|
||||
desc = "Font Color",
|
||||
name = "Font Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--font shadow
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.event_tracker.font_shadow end,
|
||||
values = function() return fontShadowTable end,
|
||||
name = "Font Shadow"
|
||||
},
|
||||
--font face
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.event_tracker.font_face end,
|
||||
values = function() return DF:BuildDropDownFontList (on_select_text_font) end,
|
||||
name = "Font Face",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
|
||||
{type = "blank"},
|
||||
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.show_crowdcontrol_pvp end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.show_crowdcontrol_pvp = value
|
||||
end,
|
||||
desc = "Show Crowd Control (Arena & BG)",
|
||||
name = "Show Crowd Control when inside a PvP zone",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.event_tracker.show_crowdcontrol_pvm end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.event_tracker.show_crowdcontrol_pvm = value
|
||||
end,
|
||||
desc = "Show Crowd Control (Dungeon & Raid)",
|
||||
name = "Show Crowd Control when inside a PvE zone",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
}
|
||||
|
||||
DF:BuildMenu(optionsPanel, options, 7, -30, 500, true, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
|
||||
optionsPanel:SetScript("OnHide", function()
|
||||
--reopen the options panel
|
||||
if (optionsPanel.FromOptionsPanel) then
|
||||
C_Timer.After(0.2, function()
|
||||
Details:OpenOptionsWindow(Details:GetInstance(1))
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
_G.DetailsEventTrackerOptions:RefreshOptions()
|
||||
_G.DetailsEventTrackerOptions:Show()
|
||||
_G.DetailsEventTrackerOptions.FromOptionsPanel = bFromOptionsPanel
|
||||
end
|
||||
|
||||
|
||||
function Details:CreateEventTrackerFrame(parentObject, name)
|
||||
local DF = Details.gump
|
||||
local SharedMedia = LibStub:GetLibrary ("LibSharedMedia-3.0")
|
||||
|
||||
--> screen frame
|
||||
local screenFrame = CreateFrame("frame", name, parentObject or UIParent,"BackdropTemplate")
|
||||
screenFrame:SetPoint("center", UIParent, "center")
|
||||
|
||||
screenFrame:SetResizeBounds(150, 40, 800, 1024)
|
||||
|
||||
screenFrame:SetSize(Details.event_tracker.frame.width, Details.event_tracker.frame.height)
|
||||
|
||||
screenFrame:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tile = true, tileSize = 16, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
screenFrame:SetBackdropColor(unpack(Details.event_tracker.frame.backdrop_color))
|
||||
screenFrame:EnableMouse(true)
|
||||
screenFrame:SetMovable(true)
|
||||
screenFrame:SetResizable(true)
|
||||
screenFrame:SetClampedToScreen(true)
|
||||
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(screenFrame, Details.event_tracker.frame)
|
||||
LibWindow.MakeDraggable(screenFrame)
|
||||
LibWindow.RestorePosition(screenFrame)
|
||||
|
||||
--> two resizers
|
||||
local leftResize, rightResize = DF:CreateResizeGrips(screenFrame)
|
||||
|
||||
leftResize:SetScript("OnMouseDown", function(self)
|
||||
if (not screenFrame.resizing and not Details.event_tracker.frame.locked) then
|
||||
screenFrame.resizing = true
|
||||
screenFrame:StartSizing("bottomleft")
|
||||
end
|
||||
end)
|
||||
leftResize:SetScript("OnMouseUp", function(self)
|
||||
if (screenFrame.resizing) then
|
||||
screenFrame.resizing = false
|
||||
screenFrame:StopMovingOrSizing()
|
||||
Details.event_tracker.frame.width = screenFrame:GetWidth()
|
||||
Details.event_tracker.frame.height = screenFrame:GetHeight()
|
||||
end
|
||||
end)
|
||||
rightResize:SetScript("OnMouseDown", function(self)
|
||||
if (not screenFrame.resizing and not Details.event_tracker.frame.locked) then
|
||||
screenFrame.resizing = true
|
||||
screenFrame:StartSizing("bottomright")
|
||||
end
|
||||
end)
|
||||
rightResize:SetScript("OnMouseUp", function(self)
|
||||
if (screenFrame.resizing) then
|
||||
screenFrame.resizing = false
|
||||
screenFrame:StopMovingOrSizing()
|
||||
Details.event_tracker.frame.width = screenFrame:GetWidth()
|
||||
Details.event_tracker.frame.height = screenFrame:GetHeight()
|
||||
end
|
||||
end)
|
||||
|
||||
screenFrame:SetScript("OnSizeChanged", function(self)
|
||||
--on size changed code
|
||||
end)
|
||||
|
||||
--> scroll frame
|
||||
--frame config
|
||||
local scroll_line_amount = 1
|
||||
local scroll_width = 195
|
||||
local header_size = 20
|
||||
|
||||
--on tick script
|
||||
local lineOnTick = function(self, deltaTime)
|
||||
--when this event occured on combat log
|
||||
local gameTime = self.GameTime
|
||||
|
||||
--calculate how much time elapsed since the event got triggered
|
||||
local elapsedTime = GetTime() - gameTime
|
||||
|
||||
--set the bar animation
|
||||
local animationPercent = min (elapsedTime, 1)
|
||||
self.Statusbar:SetValue(animationPercent)
|
||||
|
||||
--set the spark location
|
||||
if (animationPercent < 1) then
|
||||
self.Spark:SetPoint("left", self, "left", (self:GetWidth() * animationPercent) - 10, 0)
|
||||
if (not self.Spark:IsShown()) then
|
||||
self.Spark:Show()
|
||||
end
|
||||
else
|
||||
if (self.Spark:IsShown()) then
|
||||
self.Spark:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--create a line on the scroll frame
|
||||
local scroll_createline = function(self, index)
|
||||
local line = CreateFrame("frame", "$parentLine" .. index, self,"BackdropTemplate")
|
||||
line:EnableMouse(false)
|
||||
line.Index = index --hack to not trigger error on UpdateWorldTrackerLines since Index is set after this function is ran
|
||||
|
||||
--set its backdrop
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tile = true, tileSize = 16, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
--line:SetBackdropColor(1, 1, 1, 0.75)
|
||||
|
||||
--statusbar
|
||||
local statusbar = CreateFrame("statusbar", "$parentStatusBar", line,"BackdropTemplate")
|
||||
statusbar:SetAllPoints()
|
||||
local statusbartexture = statusbar:CreateTexture(nil, "border")
|
||||
statusbar:SetStatusBarTexture(statusbartexture)
|
||||
statusbar:SetMinMaxValues(0, 1)
|
||||
statusbar:SetValue(0)
|
||||
|
||||
local statusbarspark = statusbar:CreateTexture(nil, "artwork")
|
||||
statusbarspark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
statusbarspark:SetSize(16, 30)
|
||||
statusbarspark:SetBlendMode("ADD")
|
||||
statusbarspark:Hide()
|
||||
|
||||
--create the icon textures and texts - they are all statusbar childs
|
||||
local lefticon = statusbar:CreateTexture("$parentLeftIcon", "overlay")
|
||||
lefticon:SetPoint("left", line, "left", 0, 0)
|
||||
|
||||
local righticon = statusbar:CreateTexture("$parentRightIcon", "overlay")
|
||||
righticon:SetPoint("right", line, "right", 0, 0)
|
||||
|
||||
local lefttext = statusbar:CreateFontString("$parentLeftText", "overlay", "GameFontNormal")
|
||||
DF:SetFontSize(lefttext, 9)
|
||||
lefttext:SetPoint("left", lefticon, "right", 2, 0)
|
||||
lefttext.__languageId = "enUS"
|
||||
|
||||
local righttext = statusbar:CreateFontString("$parentRightText", "overlay", "GameFontNormal")
|
||||
DF:SetFontSize(righttext, 9)
|
||||
righttext:SetPoint("right", righticon, "left", -2, 0)
|
||||
|
||||
lefttext:SetJustifyH("left")
|
||||
righttext:SetJustifyH("right")
|
||||
|
||||
local actionicon = statusbar:CreateTexture("$parentRightIcon", "overlay")
|
||||
actionicon:SetPoint("center", line, "center")
|
||||
|
||||
--set members
|
||||
line.LeftIcon = lefticon
|
||||
line.RightIcon = righticon
|
||||
line.LeftText = lefttext
|
||||
line.RightText = righttext
|
||||
line.Statusbar = statusbar
|
||||
line.StatusbarTexture = statusbartexture
|
||||
line.Spark = statusbarspark
|
||||
line.ActionIcon = actionicon
|
||||
|
||||
--set some parameters
|
||||
Details:UpdateWorldTrackerLines (line)
|
||||
|
||||
--set scripts
|
||||
line:SetScript("OnUpdate", lineOnTick)
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
--some consts to help work with indexes
|
||||
local SPELLTYPE_COOLDOWN = "cooldown"
|
||||
local SPELLTYPE_INTERRUPT = "interrupt"
|
||||
local SPELLTYPE_OFFENSIVE = "offensive"
|
||||
local SPELLTYPE_CROWDCONTROL = "crowdcontrol"
|
||||
|
||||
local ABILITYTABLE_SPELLTYPE = 1
|
||||
local ABILITYTABLE_SPELLID = 2
|
||||
local ABILITYTABLE_CASTERNAME = 3
|
||||
local ABILITYTABLE_TARGETNAME = 4
|
||||
local ABILITYTABLE_TIME = 5
|
||||
local ABILITYTABLE_EXTRASPELLID = 6
|
||||
local ABILITYTABLE_GAMETIME = 7
|
||||
local ABILITYTABLE_CASTERSERIAL = 8
|
||||
local ABILITYTABLE_ISENEMY = 9
|
||||
local ABILITYTABLE_TARGETSERIAL = 10
|
||||
|
||||
local get_spec_or_class = function(serial, unitName)
|
||||
local class
|
||||
local spec = Details.cached_specs [serial]
|
||||
if (not spec) then
|
||||
local _, engClass = UnitClass(unitName)
|
||||
if (engClass) then
|
||||
class = engClass
|
||||
else
|
||||
local locClass, engClass, locRace, engRace, gender = GetPlayerInfoByGUID (serial)
|
||||
if (engClass) then
|
||||
class = engClass
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return spec, class
|
||||
end
|
||||
|
||||
local get_player_icon = function(spec, class)
|
||||
if (spec) then
|
||||
return [[Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES-SPECS]], unpack(Details.class_specs_coords [spec])
|
||||
elseif (class) then
|
||||
return [[Interface\AddOns\Details\images\classes_small]], unpack(Details.class_coords [class])
|
||||
else
|
||||
return [[Interface\AddOns\Details\images\classes_plus]], 0.50390625, 0.62890625, 0, 0.125
|
||||
end
|
||||
end
|
||||
|
||||
local anonymize_name = function(name, guid)
|
||||
if not Details.event_tracker.anonymize_names then
|
||||
return name
|
||||
end
|
||||
|
||||
if not GUIDIsPlayer(guid) then
|
||||
return name
|
||||
end
|
||||
|
||||
if not Details.event_tracker.anonymize_self and guid == playerGUID then
|
||||
return name
|
||||
end
|
||||
|
||||
-- Example GUID: 0xAABCCCDDDDEEEEEE
|
||||
-- We only care about the EEEEEE
|
||||
local guid_end = guid:sub(-6)
|
||||
|
||||
return guid_end
|
||||
end
|
||||
|
||||
local add_role_and_class_color = function(unitName, unitSerial)
|
||||
--get the actor object
|
||||
local actor = Details.tabela_vigente[1]:GetActor(unitName)
|
||||
|
||||
if (actor) then
|
||||
--remove realm name
|
||||
unitName = Details:GetOnlyName(unitName)
|
||||
|
||||
local class, spec, role = actor.classe, actor.spec, actor.role
|
||||
if (not class) then
|
||||
spec, class = get_spec_or_class (unitSerial, unitName)
|
||||
end
|
||||
|
||||
unitName = anonymize_name(unitName, unitSerial)
|
||||
|
||||
--add the class color
|
||||
if (Details.player_class [class]) then
|
||||
--is a player, add the class color
|
||||
unitName = Details:AddColorString (unitName, class)
|
||||
end
|
||||
|
||||
--add the role icon
|
||||
if (role ~= "NONE") then
|
||||
--have a role
|
||||
unitName = Details:AddRoleIcon (unitName, role, Details.event_tracker.line_height)
|
||||
end
|
||||
|
||||
else
|
||||
local spec, class = get_spec_or_class (unitSerial, unitName)
|
||||
unitName = Details:GetOnlyName(unitName)
|
||||
|
||||
unitName = anonymize_name(unitName, unitSerial)
|
||||
|
||||
if (class) then
|
||||
--add the class color
|
||||
if (Details.player_class [class]) then
|
||||
--is a player, add the class color
|
||||
unitName = Details:AddColorString (unitName, class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unitName
|
||||
end
|
||||
|
||||
local get_text_size = function()
|
||||
local iconsSpace = Details.event_tracker.line_height * 3
|
||||
local textSpace = 4
|
||||
local saveSpace = 14
|
||||
|
||||
local availableSpace = (screenFrame:GetWidth() - iconsSpace - textSpace - saveSpace) / 2
|
||||
|
||||
return availableSpace
|
||||
end
|
||||
|
||||
local shrink_string = function(fontstring, size)
|
||||
local text = fontstring:GetText()
|
||||
local loops = 20
|
||||
while (fontstring:GetStringWidth() > size and loops > 0) do
|
||||
text = strsub (text, 1, #text-1)
|
||||
fontstring:SetText(text)
|
||||
loops = loops - 1
|
||||
end
|
||||
|
||||
return fontstring
|
||||
end
|
||||
|
||||
--refresh the scroll frame
|
||||
local scroll_refresh = function(self, data, offset, total_lines)
|
||||
|
||||
local textSize = get_text_size()
|
||||
|
||||
for i = 1, total_lines do
|
||||
local index = i + offset
|
||||
local ability = data [index]
|
||||
|
||||
if (ability) then
|
||||
local line = self:GetLine (i)
|
||||
|
||||
local spec, class = get_spec_or_class (ability [ABILITYTABLE_CASTERSERIAL], ability [ABILITYTABLE_CASTERNAME])
|
||||
local texture, L, R, T, B = get_player_icon (spec, class)
|
||||
line.LeftIcon:SetTexture(texture)
|
||||
line.LeftIcon:SetTexCoord(L, R, T, B)
|
||||
|
||||
local sourceName = ability[ABILITYTABLE_CASTERNAME]
|
||||
--[=[language system test
|
||||
if (math.random(3) == 2) then
|
||||
sourceName = "Снизуслева"
|
||||
|
||||
elseif (math.random(3) == 3) then
|
||||
sourceName = "質下方的材質"
|
||||
|
||||
elseif (math.random(4) == 1) then
|
||||
sourceName = "주문 별 받은 피해"
|
||||
end
|
||||
--]=]
|
||||
|
||||
local sourceNameNoRealm = Details:GetOnlyName(sourceName)
|
||||
|
||||
sourceNameNoRealm = anonymize_name(sourceNameNoRealm, ability[ABILITYTABLE_CASTERSERIAL])
|
||||
|
||||
--need to use the language system from details framework to detect which language is being used
|
||||
local languageId = DF.Language.DetectLanguageId(sourceNameNoRealm)
|
||||
--print("lenaguage detected:", languageId, sourceNameNoRealm)
|
||||
|
||||
if (languageId ~= line.LeftText.__languageId) then
|
||||
--get a font to use with this language
|
||||
local fontPath = DF.Language.GetFontForLanguageID(languageId)
|
||||
if (fontPath) then
|
||||
if (languageId == "enUS") then
|
||||
DF:SetFontFace(line.LeftText, Details.event_tracker.font_face)
|
||||
else
|
||||
DF:SetFontFace(line.LeftText, fontPath)
|
||||
end
|
||||
line.LeftText.__languageId = languageId
|
||||
end
|
||||
end
|
||||
|
||||
line.LeftText:SetText(sourceNameNoRealm)
|
||||
|
||||
if (ability [ABILITYTABLE_ISENEMY]) then
|
||||
line:SetBackdropColor(1, .3, .3, 0.5)
|
||||
else
|
||||
line:SetBackdropColor(1, 1, 1, 0.5)
|
||||
end
|
||||
|
||||
if (ability [ABILITYTABLE_SPELLTYPE] == SPELLTYPE_COOLDOWN) then
|
||||
local spellName, _, spellIcon = GetSpellInfo(ability [ABILITYTABLE_SPELLID])
|
||||
line.RightIcon:SetTexture(spellIcon)
|
||||
line.RightIcon:SetTexCoord(.06, .94, .06, .94)
|
||||
|
||||
local targetName = ability [ABILITYTABLE_TARGETNAME]
|
||||
if (targetName) then
|
||||
local targetSerial = ability [ABILITYTABLE_TARGETSERIAL]
|
||||
targetName = add_role_and_class_color (targetName, targetSerial)
|
||||
end
|
||||
|
||||
line.RightText:SetText(targetName or spellName)
|
||||
|
||||
line.ActionIcon:SetTexture([[Interface\AddOns\Details\images\event_tracker_icons]])
|
||||
line.ActionIcon:SetTexCoord(0, 0.125, 0, 1)
|
||||
|
||||
elseif (ability [ABILITYTABLE_SPELLTYPE] == SPELLTYPE_OFFENSIVE) then
|
||||
local spellName, _, spellIcon = GetSpellInfo(ability [ABILITYTABLE_SPELLID])
|
||||
line.RightIcon:SetTexture(spellIcon)
|
||||
line.RightIcon:SetTexCoord(.06, .94, .06, .94)
|
||||
line.RightText:SetText(spellName)
|
||||
|
||||
line.ActionIcon:SetTexture([[Interface\AddOns\Details\images\event_tracker_icons]])
|
||||
line.ActionIcon:SetTexCoord(0.127, 0.25, 0, 1)
|
||||
|
||||
elseif (ability [ABILITYTABLE_SPELLTYPE] == SPELLTYPE_INTERRUPT) then
|
||||
local spellNameInterrupted, _, spellIconInterrupted = GetSpellInfo(ability [ABILITYTABLE_EXTRASPELLID])
|
||||
line.RightIcon:SetTexture(spellIconInterrupted)
|
||||
line.RightIcon:SetTexCoord(.06, .94, .06, .94)
|
||||
line.RightText:SetText(spellNameInterrupted)
|
||||
|
||||
line.ActionIcon:SetTexture([[Interface\AddOns\Details\images\event_tracker_icons]])
|
||||
line.ActionIcon:SetTexCoord(0.251, 0.375, 0, 1)
|
||||
|
||||
elseif (ability [ABILITYTABLE_SPELLTYPE] == SPELLTYPE_CROWDCONTROL) then
|
||||
local spellName, _, spellIcon = GetSpellInfo(ability [ABILITYTABLE_SPELLID])
|
||||
line.RightIcon:SetTexture(spellIcon)
|
||||
line.RightIcon:SetTexCoord(.06, .94, .06, .94)
|
||||
|
||||
local targetName = ability [ABILITYTABLE_TARGETNAME]
|
||||
if (targetName) then
|
||||
local targetSerial = ability [ABILITYTABLE_TARGETSERIAL]
|
||||
targetName = add_role_and_class_color (targetName, targetSerial)
|
||||
end
|
||||
|
||||
line.RightText:SetText(targetName or spellName or "")
|
||||
|
||||
line.ActionIcon:SetTexture([[Interface\AddOns\Details\images\event_tracker_icons]])
|
||||
line.ActionIcon:SetTexCoord(0.376, 0.5, 0, 1)
|
||||
|
||||
end
|
||||
|
||||
shrink_string (line.LeftText, textSize)
|
||||
shrink_string (line.RightText, textSize)
|
||||
|
||||
--set when the ability was registered on combat log
|
||||
line.GameTime = ability [ABILITYTABLE_GAMETIME]
|
||||
line:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--title text
|
||||
local TitleString = screenFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
TitleString:SetPoint("top", screenFrame, "top", 0, -3)
|
||||
TitleString:SetText("Details!: Event Tracker")
|
||||
local TitleBackground = screenFrame:CreateTexture(nil, "artwork")
|
||||
TitleBackground:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
|
||||
TitleBackground:SetVertexColor(.1, .1, .1, .9)
|
||||
TitleBackground:SetPoint("topleft", screenFrame, "topleft")
|
||||
TitleBackground:SetPoint("topright", screenFrame, "topright")
|
||||
TitleBackground:SetHeight(header_size)
|
||||
|
||||
--table with spells showing on the scroll frame
|
||||
local CurrentShowing = {}
|
||||
|
||||
--scrollframe
|
||||
local scrollframe = DF:CreateScrollBox (screenFrame, "$parentScrollFrame", scroll_refresh, CurrentShowing, scroll_width, 400, scroll_line_amount, Details.event_tracker.line_height, scroll_createline, true, true)
|
||||
scrollframe:SetPoint("topleft", screenFrame, "topleft", 0, -header_size)
|
||||
scrollframe:SetPoint("topright", screenFrame, "topright", 0, -header_size)
|
||||
scrollframe:SetPoint("bottomleft", screenFrame, "bottomleft", 0, 0)
|
||||
scrollframe:SetPoint("bottomright", screenFrame, "bottomright", 0, 0)
|
||||
|
||||
--update line - used by 'UpdateWorldTrackerLines' function
|
||||
local update_line = function(line)
|
||||
|
||||
--get the line index
|
||||
local index = line.Index
|
||||
|
||||
--update left text
|
||||
DF:SetFontColor(line.LeftText, Details.event_tracker.font_color)
|
||||
DF:SetFontFace (line.LeftText, Details.event_tracker.font_face)
|
||||
DF:SetFontSize(line.LeftText, Details.event_tracker.font_size)
|
||||
DF:SetFontOutline (line.LeftText, Details.event_tracker.font_shadow)
|
||||
|
||||
--update right text
|
||||
DF:SetFontColor(line.RightText, Details.event_tracker.font_color)
|
||||
DF:SetFontFace (line.RightText, Details.event_tracker.font_face)
|
||||
DF:SetFontSize(line.RightText, Details.event_tracker.font_size)
|
||||
DF:SetFontOutline (line.RightText, Details.event_tracker.font_shadow)
|
||||
|
||||
--adjust where the line is anchored
|
||||
line:SetPoint("topleft", line:GetParent(), "topleft", 1, -0.5 -((index-1)*(Details.event_tracker.line_height+1)))
|
||||
line:SetPoint("topright", line:GetParent(), "topright", -1, -0.5 -((index-1)*(Details.event_tracker.line_height+1)))
|
||||
|
||||
--set its height
|
||||
line:SetHeight(Details.event_tracker.line_height)
|
||||
|
||||
--set texture
|
||||
local texture = SharedMedia:Fetch ("statusbar", Details.event_tracker.line_texture)
|
||||
line.StatusbarTexture:SetTexture(texture)
|
||||
line.StatusbarTexture:SetVertexColor(unpack(Details.event_tracker.line_color))
|
||||
|
||||
--set icon size
|
||||
line.LeftIcon:SetSize(Details.event_tracker.line_height, Details.event_tracker.line_height)
|
||||
line.RightIcon:SetSize(Details.event_tracker.line_height, Details.event_tracker.line_height)
|
||||
line.ActionIcon:SetSize(Details.event_tracker.line_height-4, Details.event_tracker.line_height-4)
|
||||
line.ActionIcon:SetAlpha(0.65)
|
||||
end
|
||||
|
||||
-- /run _detalhes.event_tracker.font_shadow = 24
|
||||
-- /run _detalhes:UpdateWorldTrackerLines()
|
||||
|
||||
function Details:UpdateWorldTrackerLines (line)
|
||||
--don't run if the featured hasn't loaded
|
||||
if (not screenFrame) then
|
||||
return
|
||||
end
|
||||
|
||||
if (line) then
|
||||
update_line (line)
|
||||
else
|
||||
--update all lines
|
||||
for index, line in ipairs(scrollframe:GetFrames()) do
|
||||
update_line (line)
|
||||
end
|
||||
scrollframe:SetFramesHeight (Details.event_tracker.line_height)
|
||||
scrollframe:Refresh()
|
||||
end
|
||||
end
|
||||
|
||||
function Details:UpdateEventTrackerFrame()
|
||||
--don't run if the featured hasn't loaded
|
||||
if (not screenFrame) then
|
||||
return
|
||||
end
|
||||
|
||||
screenFrame:SetSize(Details.event_tracker.frame.width, Details.event_tracker.frame.height)
|
||||
LibWindow.RegisterConfig(screenFrame, Details.event_tracker.frame)
|
||||
LibWindow.RestorePosition(screenFrame)
|
||||
scrollframe:OnSizeChanged()
|
||||
|
||||
if (Details.event_tracker.frame.locked) then
|
||||
screenFrame:EnableMouse(false)
|
||||
leftResize:Hide()
|
||||
rightResize:Hide()
|
||||
else
|
||||
screenFrame:EnableMouse(true)
|
||||
leftResize:Show()
|
||||
rightResize:Show()
|
||||
end
|
||||
|
||||
if (Details.event_tracker.frame.show_title) then
|
||||
TitleString:Show()
|
||||
TitleBackground:Show()
|
||||
scrollframe:SetPoint("topleft", screenFrame, "topleft", 0, -header_size)
|
||||
scrollframe:SetPoint("topright", screenFrame, "topright", 0, -header_size)
|
||||
else
|
||||
TitleString:Hide()
|
||||
TitleBackground:Hide()
|
||||
scrollframe:SetPoint("topleft", screenFrame, "topleft", 0, 0)
|
||||
scrollframe:SetPoint("topright", screenFrame, "topright", 0, 0)
|
||||
end
|
||||
|
||||
screenFrame:SetBackdropColor(unpack(Details.event_tracker.frame.backdrop_color))
|
||||
scrollframe.__background:SetVertexColor(unpack(Details.event_tracker.frame.backdrop_color))
|
||||
|
||||
screenFrame:SetFrameStrata(Details.event_tracker.frame.strata)
|
||||
|
||||
Details:UpdateWorldTrackerLines()
|
||||
scrollframe:Refresh()
|
||||
end
|
||||
|
||||
--create the first line
|
||||
for i = 1, 1 do
|
||||
scrollframe:CreateLine (scroll_createline)
|
||||
end
|
||||
screenFrame.scrollframe = scrollframe
|
||||
scrollframe:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16})
|
||||
scrollframe:SetBackdropColor(0, 0, 0, 0)
|
||||
|
||||
local combatLog = CreateFrame("frame")
|
||||
combatLog:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
local OBJECT_TYPE_PLAYER = 0x00000400
|
||||
local OBJECT_TYPE_ENEMY = 0x00000040
|
||||
|
||||
--combat parser
|
||||
local is_player = function(flag)
|
||||
if (not flag) then
|
||||
return false
|
||||
end
|
||||
return bit.band(flag, OBJECT_TYPE_PLAYER) ~= 0
|
||||
end
|
||||
local is_enemy = function(flag)
|
||||
if (not flag) then
|
||||
return false
|
||||
end
|
||||
return bit.band(flag, OBJECT_TYPE_ENEMY) ~= 0
|
||||
end
|
||||
|
||||
local defensiveCDType = {
|
||||
[2] = true,
|
||||
[3] = true,
|
||||
[4] = true,
|
||||
}
|
||||
|
||||
combatLog:SetScript("OnEvent", function(self, event, ...)
|
||||
|
||||
local time, token, hidding, caster_serial, caster_name, caster_flags, caster_flags2, target_serial, target_name, target_flags, target_flags2, spellid, spellname, spelltype, extraSpellID, extraSpellName, extraSchool = CombatLogGetCurrentEventInfo(...)
|
||||
local added = false
|
||||
|
||||
--get the spell info from the Open Raid Lib
|
||||
local spellInfo = LIB_OPEN_RAID_COOLDOWNS_INFO[spellid]
|
||||
|
||||
--defensive cooldown
|
||||
if (token == "SPELL_CAST_SUCCESS" and (spellInfo and defensiveCDType[spellInfo.type]) and is_player (caster_flags)) then
|
||||
table.insert(CurrentShowing, 1, {SPELLTYPE_COOLDOWN, spellid, caster_name, target_name, time, false, GetTime(), caster_serial, is_enemy (caster_flags), target_serial})
|
||||
added = true
|
||||
|
||||
--offensive cooldown
|
||||
elseif (token == "SPELL_CAST_SUCCESS" and (spellInfo and spellInfo.type == 1 and spellInfo.cooldown and spellInfo.cooldown >= 90) and is_player (caster_flags)) then
|
||||
table.insert(CurrentShowing, 1, {SPELLTYPE_OFFENSIVE, spellid, caster_name, target_name, time, false, GetTime(), caster_serial, is_enemy (caster_flags), target_serial})
|
||||
added = true
|
||||
|
||||
--crowd control
|
||||
elseif (token == "SPELL_CAST_SUCCESS" and spellInfo and spellInfo.type == 8) then
|
||||
--check if isnt a pet
|
||||
if (caster_flags and is_player(caster_flags)) then
|
||||
--the target is a player
|
||||
if (Details.event_tracker.show_crowdcontrol_pvp) then
|
||||
if (Details.zone_type == "arena" or Details.zone_type == "pvp" or Details.zone_type == "none") then
|
||||
table.insert(CurrentShowing, 1, {SPELLTYPE_CROWDCONTROL, spellid, caster_name, target_name, time, false, GetTime(), caster_serial, is_enemy (caster_flags), target_serial})
|
||||
added = true
|
||||
end
|
||||
end
|
||||
|
||||
if (Details.event_tracker.show_crowdcontrol_pvm) then
|
||||
if (Details.zone_type == "party" or Details.zone_type == "raid") then
|
||||
table.insert(CurrentShowing, 1, {SPELLTYPE_CROWDCONTROL, spellid, caster_name, target_name, time, false, GetTime(), caster_serial, is_enemy (caster_flags), target_serial})
|
||||
added = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--spell interrupt
|
||||
elseif (token == "SPELL_INTERRUPT") then
|
||||
if (caster_flags and is_player (caster_flags)) then
|
||||
table.insert(CurrentShowing, 1, {SPELLTYPE_INTERRUPT, spellid, caster_name, target_name, time, extraSpellID, GetTime(), caster_serial, is_enemy (caster_flags), target_serial})
|
||||
added = true
|
||||
end
|
||||
end
|
||||
|
||||
if (added) then
|
||||
local amountOfLines = scrollframe:GetNumFramesShown()
|
||||
local amountToShow = #CurrentShowing
|
||||
|
||||
if (amountToShow > amountOfLines) then
|
||||
tremove(CurrentShowing, amountToShow)
|
||||
end
|
||||
scrollframe:Refresh()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
Details.Broadcaster_EventTrackerLoaded = true
|
||||
Details.Broadcaster_EventTrackerFrame = screenFrame
|
||||
screenFrame:Hide()
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
|
||||
local _
|
||||
|
||||
function Details:InitializeMacrosWindow()
|
||||
local DetailsMacrosPanel = DF:CreateSimplePanel(UIParent, 700, 480, "Details! Useful Macros", "DetailsMacrosPanel")
|
||||
DetailsMacrosPanel.Frame = DetailsMacrosPanel
|
||||
DetailsMacrosPanel.__name = "Macros"
|
||||
DetailsMacrosPanel.real_name = "DETAILS_MACROSWINDOW"
|
||||
DetailsMacrosPanel.__icon = [[Interface\MacroFrame\MacroFrame-Icon]]
|
||||
DetailsMacrosPanel.__iconcoords = {0, 1, 0, 1}
|
||||
DetailsMacrosPanel.__iconcolor = "white"
|
||||
DetailsPluginContainerWindow.EmbedPlugin (DetailsMacrosPanel, DetailsMacrosPanel, true)
|
||||
|
||||
function DetailsMacrosPanel.RefreshWindow()
|
||||
Details.OpenMacrosWindow()
|
||||
end
|
||||
|
||||
DetailsMacrosPanel:Hide()
|
||||
end
|
||||
|
||||
function Details.OpenMacrosWindow()
|
||||
|
||||
if (not DetailsMacrosPanel or not DetailsMacrosPanel.Initialized) then
|
||||
|
||||
DetailsMacrosPanel.Initialized = true
|
||||
local f = DetailsMacrosPanel or DF:CreateSimplePanel(UIParent, 700, 480, "Details! Useful Macros", "DetailsMacrosPanel")
|
||||
|
||||
local scrollbox_line_backdrop_color = {0, 0, 0, 0.2}
|
||||
local scrollbox_line_backdrop_color_onenter = {.3, .3, .3, 0.5}
|
||||
local scrollbox_lines = 7
|
||||
local scrollbox_line_height = 79.5
|
||||
local scrollbox_size = {890, 563}
|
||||
|
||||
f.bg1 = f:CreateTexture(nil, "background")
|
||||
f.bg1:SetTexture([[Interface\AddOns\Details\images\background]], true)
|
||||
f.bg1:SetAlpha(0.8)
|
||||
f.bg1:SetVertexColor(0.27, 0.27, 0.27)
|
||||
f.bg1:SetVertTile(true)
|
||||
f.bg1:SetHorizTile(true)
|
||||
f.bg1:SetSize(790, 454)
|
||||
f.bg1:SetAllPoints()
|
||||
f:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
f:SetBackdropColor(.5, .5, .5, .7)
|
||||
f:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
local macrosAvailable = Details.MacroList
|
||||
|
||||
local OnEnterMacroButton = function(self)
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_onenter))
|
||||
end
|
||||
|
||||
local onLeaveMacroButton = function(self)
|
||||
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
end
|
||||
|
||||
local updateMacroLine = function(self, index, title, desc, macroText)
|
||||
self.Title:SetText(title)
|
||||
self.Desc:SetText(desc)
|
||||
self.MacroTextEntry:SetText(macroText)
|
||||
end
|
||||
|
||||
local textEntryOnFocusGained = function(self)
|
||||
self:HighlightText()
|
||||
end
|
||||
|
||||
local textEntryOnFocusLost = function(self)
|
||||
self:HighlightText (0, 0)
|
||||
end
|
||||
|
||||
local refreshMacroScrollbox = function(self, data, offset, totalLines)
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local macro = macrosAvailable [index]
|
||||
if (macro) then
|
||||
local line = self:GetLine (i)
|
||||
line:UpdateLine (index, macro.Name, macro.Desc, macro.MacroText)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local macroListCreateLine = function(self, index)
|
||||
--create a new line
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self,"BackdropTemplate")
|
||||
|
||||
--set its parameters
|
||||
line:SetPoint("topleft", self, "topleft", 0, -((index-1) * (scrollbox_line_height+1)))
|
||||
line:SetSize(scrollbox_size[1], scrollbox_line_height)
|
||||
line:SetScript("OnEnter", OnEnterMacroButton)
|
||||
line:SetScript("OnLeave", onLeaveMacroButton)
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true, edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
line:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
|
||||
line:SetBackdropBorderColor(0, 0, 0, 0.3)
|
||||
|
||||
local titleLabel = DF:CreateLabel(line, "", DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
titleLabel.textsize = 14
|
||||
titleLabel.textcolor = "yellow"
|
||||
local descLabel = DF:CreateLabel(line, "", DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
descLabel.textsize = 12
|
||||
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
options_dropdown_template = DF.table.copy({}, options_dropdown_template)
|
||||
options_dropdown_template.backdropcolor = {.51, .51, .51, .3}
|
||||
options_dropdown_template.onenterbordercolor = {.51, .51, .51, .2}
|
||||
|
||||
local textEntry = DF:CreateTextEntry(line, function()end, scrollbox_size[1] - 10, 40, "MacroTextEntry", _, _, options_dropdown_template)
|
||||
textEntry:SetHook("OnEditFocusGained", textEntryOnFocusGained)
|
||||
textEntry:SetHook("OnEditFocusLost", textEntryOnFocusLost)
|
||||
textEntry:SetJustifyH("left")
|
||||
textEntry:SetTextInsets(8, 8, 0, 0)
|
||||
|
||||
titleLabel:SetPoint("topleft", line, "topleft", 5, -5)
|
||||
descLabel:SetPoint("topleft", titleLabel, "bottomleft", 0, -2)
|
||||
textEntry:SetPoint("topleft", descLabel, "bottomleft", 0, -4)
|
||||
|
||||
line.Title = titleLabel
|
||||
line.Desc = descLabel
|
||||
line.MacroTextEntry = textEntry
|
||||
|
||||
line.UpdateLine = updateMacroLine
|
||||
line:Hide()
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
local macroScrollbox = DF:CreateScrollBox (f, "$parentMacroScrollbox", refreshMacroScrollbox, macrosAvailable, scrollbox_size[1], scrollbox_size[2], scrollbox_lines, scrollbox_line_height)
|
||||
macroScrollbox:SetPoint("topleft", f, "topleft", 5, -30)
|
||||
macroScrollbox:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
macroScrollbox:SetBackdropColor(0, 0, 0, 0)
|
||||
macroScrollbox:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
f.MacroScrollbox = macroScrollbox
|
||||
DF:ReskinSlider(macroScrollbox)
|
||||
|
||||
macroScrollbox.__background:Hide()
|
||||
|
||||
--create the scrollbox lines
|
||||
for i = 1, scrollbox_lines do
|
||||
macroScrollbox:CreateLine (macroListCreateLine)
|
||||
end
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin (DetailsMacrosPanel)
|
||||
DetailsMacrosPanel.MacroScrollbox:Refresh()
|
||||
DetailsMacrosPanel:Show()
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,462 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local addonName, Details222 = ...
|
||||
local _
|
||||
|
||||
Details222.Debug.MythicPlusChartWindowDebug = false
|
||||
local verbosemode = false
|
||||
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local UIParent = UIParent
|
||||
|
||||
---@type detailsframework
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
local mythicDungeonCharts = Details222.MythicPlus.Charts.Listener
|
||||
|
||||
local UISpecialFrames = UISpecialFrames
|
||||
|
||||
-- /run _G.DetailsMythicDungeonChartHandler.ShowEndOfMythicPlusPanel()
|
||||
-- /run _G.DetailsMythicDungeonChartHandler.ShowChart()
|
||||
|
||||
function mythicDungeonCharts.ShowChart()
|
||||
if (not mythicDungeonCharts.Frame) then
|
||||
mythicDungeonCharts.Frame = CreateFrame("frame", "DetailsMythicDungeonChartFrame", UIParent, "BackdropTemplate")
|
||||
local dungeonChartFrame = mythicDungeonCharts.Frame
|
||||
|
||||
--get the screen width
|
||||
local screenWidth = GetScreenWidth()
|
||||
|
||||
dungeonChartFrame:SetSize(screenWidth - 200, 400)
|
||||
dungeonChartFrame:SetPoint("center", UIParent, "center", 0, 200)
|
||||
dungeonChartFrame:SetFrameStrata("DIALOG")
|
||||
dungeonChartFrame:EnableMouse(true)
|
||||
dungeonChartFrame:SetMovable(true)
|
||||
detailsFramework:ApplyStandardBackdrop(dungeonChartFrame)
|
||||
dungeonChartFrame.__background:SetAlpha(0.834)
|
||||
|
||||
--minimized frame
|
||||
mythicDungeonCharts.FrameMinimized = CreateFrame("frame", "DetailsMythicDungeonChartFrameminimized", UIParent, "BackdropTemplate")
|
||||
local fMinimized = mythicDungeonCharts.FrameMinimized
|
||||
fMinimized:SetSize(160, 24)
|
||||
fMinimized:SetPoint("center", UIParent, "center", 0, 0)
|
||||
fMinimized:SetFrameStrata("LOW")
|
||||
fMinimized:EnableMouse(true)
|
||||
fMinimized:SetMovable(true)
|
||||
fMinimized:Hide()
|
||||
detailsFramework:ApplyStandardBackdrop(fMinimized)
|
||||
|
||||
dungeonChartFrame.IsMinimized = false
|
||||
|
||||
--titlebar
|
||||
local titlebar = CreateFrame("frame", nil, dungeonChartFrame, "BackdropTemplate")
|
||||
titlebar:SetPoint("topleft", dungeonChartFrame, "topleft", 2, -3)
|
||||
titlebar:SetPoint("topright", dungeonChartFrame, "topright", -2, -3)
|
||||
titlebar:SetHeight(20)
|
||||
titlebar:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
titlebar:SetBackdropColor(.5, .5, .5, 1)
|
||||
titlebar:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--title
|
||||
local titleLabel = detailsFramework:NewLabel(titlebar, titlebar, nil, "titulo", "Plugins", "GameFontHighlightLeft", 12, {227/255, 186/255, 4/255})
|
||||
titleLabel:SetPoint("center", titlebar , "center")
|
||||
titleLabel:SetPoint("top", titlebar , "top", 0, -5)
|
||||
dungeonChartFrame.TitleText = titleLabel
|
||||
|
||||
--titlebar when minimized
|
||||
local titlebarMinimized = CreateFrame("frame", nil, fMinimized, "BackdropTemplate")
|
||||
titlebarMinimized:SetPoint("topleft", fMinimized, "topleft", 2, -3)
|
||||
titlebarMinimized:SetPoint("topright", fMinimized, "topright", -2, -3)
|
||||
titlebarMinimized:SetHeight(20)
|
||||
titlebarMinimized:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
titlebarMinimized:SetBackdropColor(.5, .5, .5, 1)
|
||||
titlebarMinimized:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--title
|
||||
local titleLabelMinimized = detailsFramework:NewLabel(titlebarMinimized, titlebarMinimized, nil, "titulo", "Dungeon Run Chart", "GameFontHighlightLeft", 10, {227/255, 186/255, 4/255})
|
||||
titleLabelMinimized:SetPoint("left", titlebarMinimized , "left", 4, 0)
|
||||
--titleLabelMinimized:SetPoint("top", titlebarMinimized , "top", 0, -5)
|
||||
dungeonChartFrame.TitleTextMinimized = titleLabelMinimized
|
||||
|
||||
table.insert(UISpecialFrames, "DetailsMythicDungeonChartFrame")
|
||||
|
||||
--register to libwindow
|
||||
local LibWindow = LibStub("LibWindow-1.1")
|
||||
LibWindow.RegisterConfig(dungeonChartFrame, Details.mythic_plus.mythicrun_chart_frame)
|
||||
LibWindow.RestorePosition(dungeonChartFrame)
|
||||
LibWindow.MakeDraggable(dungeonChartFrame)
|
||||
LibWindow.SavePosition(dungeonChartFrame)
|
||||
|
||||
LibWindow.RegisterConfig(fMinimized, Details.mythic_plus.mythicrun_chart_frame_minimized)
|
||||
LibWindow.RestorePosition(fMinimized)
|
||||
LibWindow.MakeDraggable(fMinimized)
|
||||
LibWindow.SavePosition(fMinimized)
|
||||
|
||||
local chartFrame = detailsFramework:CreateGraphicMultiLineFrame(dungeonChartFrame, "DetailsMythicDungeonChartGraphicFrame")
|
||||
chartFrame:SetPoint("topleft", dungeonChartFrame, "topleft", 1, -20)
|
||||
chartFrame:SetSize(dungeonChartFrame:GetWidth(), dungeonChartFrame:GetHeight() - 20)
|
||||
chartFrame:EnableMouse(false)
|
||||
dungeonChartFrame:Hide()
|
||||
dungeonChartFrame.ChartFrame = chartFrame
|
||||
|
||||
local red, green, blue, opacity = 1, 1, 1, 1
|
||||
chartFrame:CreateAxesLines(48, 20, "left", 1, 10, 10, red, green, blue, opacity)
|
||||
chartFrame:SetXAxisDataType("time")
|
||||
chartFrame:SetLineThickness(2)
|
||||
|
||||
function dungeonChartFrame.ShowChartFrame()
|
||||
if (dungeonChartFrame.IsMinimized) then
|
||||
dungeonChartFrame.IsMinimized = false
|
||||
fMinimized:Hide()
|
||||
dungeonChartFrame:Show()
|
||||
else
|
||||
dungeonChartFrame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
mythicDungeonCharts.CreateCloseMinimizeButtons(dungeonChartFrame)
|
||||
mythicDungeonCharts.CreateBossWidgets(dungeonChartFrame)
|
||||
end --finished created the chart frame
|
||||
|
||||
local dungeonChartFrame = mythicDungeonCharts.Frame
|
||||
|
||||
---@type df_chartmulti
|
||||
local chartFrame = dungeonChartFrame.ChartFrame
|
||||
|
||||
chartFrame:Reset()
|
||||
|
||||
--check if there is a valid chart table
|
||||
if (not mythicDungeonCharts.ChartTable) then
|
||||
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
||||
--development
|
||||
if (Details.mythic_plus.last_mythicrun_chart) then
|
||||
--load the last mythic dungeon run chart
|
||||
local t = {}
|
||||
detailsFramework.table.copy(t, Details.mythic_plus.last_mythicrun_chart)
|
||||
mythicDungeonCharts.ChartTable = t
|
||||
mythicDungeonCharts:Debug("no valid data, saved data loaded")
|
||||
|
||||
else
|
||||
mythicDungeonCharts:Debug("no valid data and no saved data, canceling")
|
||||
dungeonChartFrame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
else
|
||||
dungeonChartFrame:Hide()
|
||||
mythicDungeonCharts:Debug("no data found, canceling")
|
||||
|
||||
if (verbosemode) then
|
||||
mythicDungeonCharts:Debug("mythicDungeonCharts.ShowChart() failed: no chart table")
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local charts = mythicDungeonCharts.ChartTable.Players
|
||||
local classDuplicated = {}
|
||||
|
||||
mythicDungeonCharts.PlayerGraphIndex = {}
|
||||
|
||||
--add the lines to the chart (one line per player)
|
||||
for playerName, playerTable in pairs(charts) do
|
||||
local chartData = playerTable.ChartData
|
||||
|
||||
classDuplicated[playerTable.Class] = (classDuplicated[playerTable.Class] or 0) + 1
|
||||
|
||||
local lineColor
|
||||
if (playerTable.Class) then
|
||||
local classColor = mythicDungeonCharts.ClassColors[playerTable.Class .. classDuplicated[playerTable.Class]]
|
||||
if (classColor) then
|
||||
lineColor = {classColor.r, classColor.g, classColor.b}
|
||||
else
|
||||
lineColor = {1, 1, 1}
|
||||
end
|
||||
else
|
||||
lineColor = {1, 1, 1}
|
||||
end
|
||||
|
||||
local combatTime = mythicDungeonCharts.ChartTable.ElapsedTime
|
||||
|
||||
local opacity = 1
|
||||
--local smoothnessLevel = 50
|
||||
--local smoothMethod = "loess"
|
||||
local smoothnessLevel = 20
|
||||
local smoothMethod = "sma"
|
||||
|
||||
local chartSize = #chartData
|
||||
|
||||
local shrinkBy = 1
|
||||
if (chartSize >= 800) then
|
||||
shrinkBy = math.max(2, math.floor(chartSize/800))
|
||||
end
|
||||
|
||||
local reducedData = chartFrame:ShrinkData(chartData, shrinkBy)
|
||||
|
||||
chartFrame:SetFillChart(true, 5)
|
||||
chartFrame:AddData(reducedData, smoothMethod, smoothnessLevel, playerName, lineColor[1], lineColor[2], lineColor[3], opacity)
|
||||
chartFrame:SetXAxisData(combatTime)
|
||||
table.insert(mythicDungeonCharts.PlayerGraphIndex, playerName)
|
||||
end
|
||||
|
||||
mythicDungeonCharts.RefreshBossTimeline(dungeonChartFrame, mythicDungeonCharts.ChartTable.ElapsedTime)
|
||||
|
||||
--generate boss time table
|
||||
local bossTimeTable = {}
|
||||
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
||||
local combatTime = bossTable [3] or math.random(10, 30)
|
||||
table.insert(bossTimeTable, bossTable[1])
|
||||
table.insert(bossTimeTable, bossTable[1] - combatTime)
|
||||
end
|
||||
|
||||
--chartFrame:AddOverlay(bossTimeTable, {1, 1, 1, 0.05}, "Show Boss", "")
|
||||
|
||||
--local phrase = " Average Dps (under development)\npress Escape to hide, Details! Alpha Build." .. _detalhes.build_counter .. "." .. _detalhes.realversion
|
||||
local phrase = "Details!: Average Dps for "
|
||||
|
||||
--chartFrame:SetTitle("")
|
||||
--detailsFramework:SetFontSize(chartFrame.chart_title, 14)
|
||||
|
||||
dungeonChartFrame.TitleText:SetText(mythicDungeonCharts.ChartTable.DungeonName and phrase .. mythicDungeonCharts.ChartTable.DungeonName or phrase)
|
||||
|
||||
dungeonChartFrame.ShowChartFrame()
|
||||
|
||||
chartFrame:Plot()
|
||||
|
||||
if (verbosemode) then
|
||||
mythicDungeonCharts:Debug("mythicDungeonCharts.ShowChart() success")
|
||||
end
|
||||
end
|
||||
|
||||
local showID = 0
|
||||
local HideTooltip = function(ticker)
|
||||
if (showID == ticker.ShowID) then
|
||||
GameCooltip2:Hide()
|
||||
mythicDungeonCharts.Frame.BossWidgetsFrame.GraphPin:Hide()
|
||||
mythicDungeonCharts.Frame.BossWidgetsFrame.GraphPinGlow:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local PixelFrameOnEnter = function(self)
|
||||
local playerName = self.PlayerName
|
||||
--get the percent from the pixel height relative to the chart window
|
||||
local dps = self.Height / mythicDungeonCharts.Frame.ChartFrame:GetHeight()
|
||||
--multiply the max dps with the percent
|
||||
dps = mythicDungeonCharts.Frame.ChartFrame.Graphic.max_value * dps
|
||||
|
||||
mythicDungeonCharts.Frame.BossWidgetsFrame.GraphPin:SetPoint("center", self, "center", 0, 0)
|
||||
mythicDungeonCharts.Frame.BossWidgetsFrame.GraphPin:Show()
|
||||
mythicDungeonCharts.Frame.BossWidgetsFrame.GraphPinGlow:Show()
|
||||
|
||||
GameCooltip2:Preset(2)
|
||||
GameCooltip2:SetOption("FixedWidth", 100)
|
||||
GameCooltip2:SetOption("TextSize", 10)
|
||||
local onlyName = Details:GetOnlyName(playerName)
|
||||
GameCooltip2:AddLine(onlyName)
|
||||
|
||||
local classIcon, L, R, B, T = Details:GetClassIcon(mythicDungeonCharts.ChartTable.Players [playerName] and mythicDungeonCharts.ChartTable.Players [playerName].Class)
|
||||
GameCooltip2:AddIcon (classIcon, 1, 1, 16, 16, L, R, B, T)
|
||||
|
||||
GameCooltip2:AddLine(Details:GetCurrentToKFunction()(nil, floor(dps)))
|
||||
|
||||
GameCooltip2:SetOwner(self)
|
||||
GameCooltip2:Show()
|
||||
showID = showID + 1
|
||||
end
|
||||
|
||||
local PixelFrameOnLeave = function(self)
|
||||
local timer = C_Timer.NewTimer(1, HideTooltip)
|
||||
timer.ShowID = showID
|
||||
end
|
||||
|
||||
|
||||
mythicDungeonCharts.ClassColors = {
|
||||
["HUNTER1"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffabd473" },
|
||||
["HUNTER2"] = { r = 0.47, g = 0.63, b = 0.25, colorStr = "ffabd473" },
|
||||
["HUNTER3"] = { r = 0.27, g = 0.43, b = 0.05, colorStr = "ffabd473" },
|
||||
|
||||
["WARLOCK1"] = { r = 0.53, g = 0.53, b = 0.93, colorStr = "ff8788ee" },
|
||||
["WARLOCK2"] = { r = 0.33, g = 0.33, b = 0.73, colorStr = "ff8788ee" },
|
||||
["WARLOCK3"] = { r = 0.13, g = 0.13, b = 0.53, colorStr = "ff8788ee" },
|
||||
|
||||
["PRIEST1"] = { r = 1.0, g = 1.0, b = 1.0, colorStr = "ffffffff" },
|
||||
["PRIEST2"] = { r = 0.8, g = 0.8, b = 0.8, colorStr = "ffffffff" },
|
||||
["PRIEST3"] = { r = 0.6, g = 0.6, b = 0.6, colorStr = "ffffffff" },
|
||||
|
||||
["PALADIN1"] = { r = 0.96, g = 0.55, b = 0.73, colorStr = "fff58cba" },
|
||||
["PALADIN2"] = { r = 0.76, g = 0.35, b = 0.53, colorStr = "fff58cba" },
|
||||
["PALADIN3"] = { r = 0.56, g = 0.15, b = 0.33, colorStr = "fff58cba" },
|
||||
|
||||
["MAGE1"] = { r = 0.25, g = 0.78, b = 0.92, colorStr = "ff3fc7eb" },
|
||||
["MAGE2"] = { r = 0.05, g = 0.58, b = 0.72, colorStr = "ff3fc7eb" },
|
||||
["MAGE3"] = { r = 0.0, g = 0.38, b = 0.52, colorStr = "ff3fc7eb" },
|
||||
|
||||
["ROGUE1"] = { r = 1.0, g = 0.96, b = 0.41, colorStr = "fffff569" },
|
||||
["ROGUE2"] = { r = 0.8, g = 0.76, b = 0.21, colorStr = "fffff569" },
|
||||
["ROGUE3"] = { r = 0.6, g = 0.56, b = 0.01, colorStr = "fffff569" },
|
||||
|
||||
["DRUID1"] = { r = 1.0, g = 0.49, b = 0.04, colorStr = "ffff7d0a" },
|
||||
["DRUID2"] = { r = 0.8, g = 0.29, b = 0.04, colorStr = "ffff7d0a" },
|
||||
["DRUID3"] = { r = 0.6, g = 0.09, b = 0.04, colorStr = "ffff7d0a" },
|
||||
|
||||
["SHAMAN1"] = { r = 0.0, g = 0.44, b = 0.87, colorStr = "ff0070de" },
|
||||
["SHAMAN2"] = { r = 0.0, g = 0.24, b = 0.67, colorStr = "ff0070de" },
|
||||
["SHAMAN3"] = { r = 0.0, g = 0.04, b = 0.47, colorStr = "ff0070de" },
|
||||
|
||||
["WARRIOR1"] = { r = 0.78, g = 0.61, b = 0.43, colorStr = "ffc79c6e" },
|
||||
["WARRIOR2"] = { r = 0.58, g = 0.41, b = 0.23, colorStr = "ffc79c6e" },
|
||||
["WARRIOR3"] = { r = 0.38, g = 0.21, b = 0.03, colorStr = "ffc79c6e" },
|
||||
|
||||
["DEATHKNIGHT1"] = { r = 0.77, g = 0.12 , b = 0.23, colorStr = "ffc41f3b" },
|
||||
["DEATHKNIGHT2"] = { r = 0.57, g = 0.02 , b = 0.03, colorStr = "ffc41f3b" },
|
||||
["DEATHKNIGHT3"] = { r = 0.37, g = 0.02 , b = 0.03, colorStr = "ffc41f3b" },
|
||||
|
||||
["MONK1"] = { r = 0.0, g = 1.00 , b = 0.59, colorStr = "ff00ff96" },
|
||||
["MONK2"] = { r = 0.0, g = 0.8 , b = 0.39, colorStr = "ff00ff96" },
|
||||
["MONK3"] = { r = 0.0, g = 0.6 , b = 0.19, colorStr = "ff00ff96" },
|
||||
|
||||
["DEMONHUNTER1"] = { r = 0.64, g = 0.19, b = 0.79, colorStr = "ffa330c9" },
|
||||
["DEMONHUNTER2"] = { r = 0.44, g = 0.09, b = 0.59, colorStr = "ffa330c9" },
|
||||
["DEMONHUNTER3"] = { r = 0.24, g = 0.09, b = 0.39, colorStr = "ffa330c9" },
|
||||
};
|
||||
|
||||
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
||||
--C_Timer.After(1, mythicDungeonCharts.ShowChart)
|
||||
end
|
||||
|
||||
function mythicDungeonCharts.RefreshBossTimeline(dungeonChartFrame, elapsedTime)
|
||||
---@type df_chartmulti
|
||||
local chartFrame = dungeonChartFrame.ChartFrame
|
||||
|
||||
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
||||
local bossWidget = dungeonChartFrame.BossWidgetsFrame.Widgets[i]
|
||||
|
||||
if (not bossWidget) then
|
||||
local newBossWidget = CreateFrame("frame", "$parentBossWidget" .. i, dungeonChartFrame.BossWidgetsFrame, "BackdropTemplate")
|
||||
newBossWidget:SetSize(64, 32)
|
||||
newBossWidget:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
newBossWidget:SetBackdropColor(0, 0, 0, 0.1)
|
||||
newBossWidget:SetBackdropBorderColor(0, 0, 0, 0)
|
||||
|
||||
local bossAvatar = detailsFramework:CreateImage(newBossWidget, "", 64, 32, "border")
|
||||
bossAvatar:SetPoint("bottomleft", newBossWidget, "bottomleft", 0, 0)
|
||||
bossAvatar:SetScale(1.0)
|
||||
newBossWidget.AvatarTexture = bossAvatar
|
||||
|
||||
local verticalLine = detailsFramework:CreateImage(newBossWidget, "", 1, chartFrame:GetHeight() - 25, "overlay")
|
||||
verticalLine:SetColorTexture(1, 1, 1, 0.3)
|
||||
verticalLine:SetPoint("bottomleft", newBossWidget, "bottomright", 0, 0)
|
||||
|
||||
local timeText = detailsFramework:CreateLabel(newBossWidget)
|
||||
timeText:SetPoint("bottomright", newBossWidget, "bottomright", 0, 0)
|
||||
newBossWidget.TimeText = timeText
|
||||
|
||||
local timeBackground = detailsFramework:CreateImage(newBossWidget, "", 30, 12, "artwork")
|
||||
timeBackground:SetColorTexture(0, 0, 0, 0.8)
|
||||
timeBackground:SetPoint("topleft", timeText, "topleft", -2, 2)
|
||||
timeBackground:SetPoint("bottomright", timeText, "bottomright", 2, 0)
|
||||
|
||||
dungeonChartFrame.BossWidgetsFrame.Widgets[i] = newBossWidget
|
||||
bossWidget = newBossWidget
|
||||
end
|
||||
|
||||
local chartLength = chartFrame:GetWidth()
|
||||
local secondsPerPixel = chartLength / elapsedTime
|
||||
local xPosition = bossTable[1] * secondsPerPixel
|
||||
|
||||
bossWidget:SetPoint("bottomright", chartFrame, "bottomleft", xPosition, 22)
|
||||
|
||||
bossWidget.TimeText:SetText(detailsFramework:IntegerToTimer(bossTable[1]))
|
||||
|
||||
if (bossTable[2].bossimage) then
|
||||
bossWidget.AvatarTexture:SetTexture(bossTable[2].bossimage)
|
||||
else
|
||||
local bossAvatar = Details:GetBossPortrait(nil, nil, bossTable[2].name, bossTable[2].ej_instance_id)
|
||||
bossWidget.AvatarTexture:SetTexture(bossAvatar)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mythicDungeonCharts.CreateCloseMinimizeButtons(dungeonChartFrame)
|
||||
local fMinimized = mythicDungeonCharts.FrameMinimized
|
||||
|
||||
local closeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
||||
closeButton:GetNormalTexture():SetDesaturated(true)
|
||||
closeButton:SetWidth(24)
|
||||
closeButton:SetHeight(24)
|
||||
closeButton:SetPoint("topright", dungeonChartFrame, "topright", 0, -1)
|
||||
closeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
||||
|
||||
local minimizeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
||||
minimizeButton:GetNormalTexture():SetDesaturated(true)
|
||||
minimizeButton:SetWidth(24)
|
||||
minimizeButton:SetHeight(24)
|
||||
minimizeButton:SetPoint("right", closeButton, "left", 2, 0)
|
||||
minimizeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
||||
minimizeButton:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||
minimizeButton:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||
minimizeButton:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
||||
|
||||
local closeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
||||
closeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
||||
closeButtonWhenMinimized:SetWidth(24)
|
||||
closeButtonWhenMinimized:SetHeight(24)
|
||||
closeButtonWhenMinimized:SetPoint("topright", fMinimized, "topright", 0, -1)
|
||||
closeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
||||
|
||||
local minimizeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
||||
minimizeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
||||
minimizeButtonWhenMinimized:SetWidth(24)
|
||||
minimizeButtonWhenMinimized:SetHeight(24)
|
||||
minimizeButtonWhenMinimized:SetPoint("right", closeButtonWhenMinimized, "left", 2, 0)
|
||||
minimizeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||
minimizeButtonWhenMinimized:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
||||
|
||||
closeButtonWhenMinimized:SetScript("OnClick", function()
|
||||
dungeonChartFrame.IsMinimized = false
|
||||
fMinimized:Hide()
|
||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||
end)
|
||||
|
||||
--replace the default click function
|
||||
local minimize_func = function(self)
|
||||
if (dungeonChartFrame.IsMinimized) then
|
||||
dungeonChartFrame.IsMinimized = false
|
||||
fMinimized:Hide()
|
||||
dungeonChartFrame:Show()
|
||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||
else
|
||||
dungeonChartFrame.IsMinimized = true
|
||||
dungeonChartFrame:Hide()
|
||||
fMinimized:Show()
|
||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
||||
end
|
||||
end
|
||||
|
||||
minimizeButton:SetScript("OnClick", minimize_func)
|
||||
minimizeButtonWhenMinimized:SetScript("OnClick", minimize_func)
|
||||
end
|
||||
|
||||
function mythicDungeonCharts.CreateBossWidgets(dungeonChartFrame)
|
||||
dungeonChartFrame.BossWidgetsFrame = CreateFrame("frame", "$parentBossFrames", dungeonChartFrame, "BackdropTemplate")
|
||||
dungeonChartFrame.BossWidgetsFrame:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+10)
|
||||
dungeonChartFrame.BossWidgetsFrame.Widgets = {}
|
||||
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPin = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "overlay")
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexture([[Interface\BUTTONS\UI-RadioButton]])
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexCoord(17/64, 32/64, 0, 1)
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetSize(16, 16)
|
||||
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "artwork")
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexture([[Interface\Calendar\EventNotificationGlow]])
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexCoord(0, 1, 0, 1)
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetSize(14, 14)
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetBlendMode("ADD")
|
||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetPoint("center", dungeonChartFrame.BossWidgetsFrame.GraphPin, "center", 0, 0)
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local Loc = _G.LibStub("AceLocale-3.0"):GetLocale( "Details" )
|
||||
local SharedMedia = _G.LibStub:GetLibrary("LibSharedMedia-3.0")
|
||||
local UIParent = UIParent
|
||||
local addonName, Details222 = ...
|
||||
local detailsFramework = DetailsFramework
|
||||
local _
|
||||
|
||||
local mPlus = Details222.MythicPlusBreakdown
|
||||
|
||||
function mPlus.ShowSummary()
|
||||
if (not mPlus.MainFrame) then
|
||||
mPlus.CreateMainFrame()
|
||||
end
|
||||
end
|
||||
|
||||
function mPlus.CreateMainFrame()
|
||||
local mPlusFrame = CreateFrame("frame", "DetailsMythicPlusBreakdownFrame", UIParent, "BackdropTemplate")
|
||||
detailsFramework:AddRoundedCornersToFrame(mPlusFrame, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
mPlus.MainFrame = mPlusFrame
|
||||
|
||||
PixelUtil.SetPoint(mPlusFrame, "center", UIParent, "center", 0, 0)
|
||||
PixelUtil.SetSize(mPlusFrame, Details222.BreakdownWindow.width, Details222.BreakdownWindow.height)
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale( "Details" )
|
||||
local gump = Details.gump
|
||||
local _, Details222 = ...
|
||||
_ = nil
|
||||
|
||||
function Details:OpenNewsWindow(textToShow, dumpValues, keeptext)
|
||||
Details.latest_news_saw = Details.userversion
|
||||
|
||||
local newsFrame = Details:CreateOrOpenNewsWindow()
|
||||
local animationHub = DetailsFramework:CreateAnimationHub(newsFrame)
|
||||
local fadeInAnim1 = DetailsFramework:CreateAnimation(animationHub, "alpha", 1, 0.2, 0, 0.2)
|
||||
local fadeInAnim2 = DetailsFramework:CreateAnimation(animationHub, "alpha", 2, 1.5, 0.5, 1)
|
||||
fadeInAnim2:SetStartDelay(1.3)
|
||||
|
||||
if (dumpValues == "change_log" or textToShow == "LeftButton") then
|
||||
newsFrame:Text (Loc ["STRING_VERSION_LOG"])
|
||||
newsFrame:Show()
|
||||
return
|
||||
end
|
||||
|
||||
if (textToShow and type(textToShow) == "table") then
|
||||
DetailsNewsWindowLower:SetSize(450, 5000)
|
||||
DetailsNewsWindowSlider:SetMinMaxValues(0, 5000)
|
||||
DetailsNewsWindowText:SetHeight(5000)
|
||||
|
||||
local returnString = ""
|
||||
for _, text in ipairs(textToShow) do
|
||||
if (type(text) == "string" or type(text) == "number") then
|
||||
returnString = returnString .. text .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
if (dumpValues) then
|
||||
returnString = Details.table.dump(textToShow)
|
||||
end
|
||||
|
||||
if (keeptext) then
|
||||
newsFrame:Text((DetailsNewsWindowText:GetText() or "") .. "\n\n" .. returnString)
|
||||
else
|
||||
if (dumpValues) then
|
||||
newsFrame.DumpTableFrame:SetText(returnString)
|
||||
else
|
||||
newsFrame:Text (returnString)
|
||||
end
|
||||
end
|
||||
else
|
||||
if (keeptext) then
|
||||
newsFrame:Text ((DetailsNewsWindowText:GetText() or "") .. "\n\n" .. (textToShow or Loc ["STRING_VERSION_LOG"]))
|
||||
else
|
||||
--show news
|
||||
newsFrame:Text (textToShow or Loc["STRING_VERSION_LOG"])
|
||||
--show textures
|
||||
if (Details.build_counter == 8154) then
|
||||
newsFrame.imageFrame:Show()
|
||||
newsFrame.imageFrame.texture:SetTexture([[interface/addons/details/images/news_images]])
|
||||
newsFrame.imageFrame.texture:SetSize(279, 452)
|
||||
newsFrame.imageFrame.texture:SetTexCoord(0, 279/512, 0, 452/512)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newsFrame:Show()
|
||||
animationHub:Play()
|
||||
end
|
||||
|
||||
function Details:CreateOrOpenNewsWindow()
|
||||
local frame = _G.DetailsNewsWindow
|
||||
|
||||
if (not frame) then
|
||||
frame = DetailsFramework:CreateSimplePanel(UIParent, 480, 560, "Details! Damage Meter " .. Details.version, "DetailsNewsWindow", panel_options, db)
|
||||
table.insert(UISpecialFrames, "DetailsNewsWindow")
|
||||
frame:SetPoint("left", UIParent, "left", 10, 0)
|
||||
frame:SetFrameStrata("FULLSCREEN")
|
||||
frame:SetMovable(true)
|
||||
frame:Hide()
|
||||
DetailsFramework:ApplyStandardBackdrop(frame)
|
||||
|
||||
frame.imageFrame = CreateFrame("frame", "DetailsNewsWindowImageFrame", frame, "BackdropTemplate")
|
||||
frame.imageFrame:SetPoint("topleft", frame, "topright", 2, 0)
|
||||
frame.imageFrame:SetPoint("bottomleft", frame, "bottomright", 2, 0)
|
||||
frame.imageFrame:SetWidth(256)
|
||||
DetailsFramework:ApplyStandardBackdrop(frame.imageFrame)
|
||||
frame.imageFrame:Hide()
|
||||
frame.imageFrame.texture = frame.imageFrame:CreateTexture(nil, "overlay")
|
||||
frame.imageFrame.texture:SetPoint("topleft", frame.imageFrame, "topleft")
|
||||
|
||||
local dumpFrame = gump:CreateTextEntry(frame, function()end, 500, 612, "DumpTable", "$parentDumpTable")
|
||||
dumpFrame.editbox:SetMultiLine(true)
|
||||
|
||||
dumpFrame:SetPoint("topleft", frame, "topleft", 8, -68)
|
||||
dumpFrame:SetBackdrop(nil)
|
||||
dumpFrame.editbox:SetBackdrop(nil)
|
||||
dumpFrame.editbox:SetJustifyH("left")
|
||||
dumpFrame.editbox:SetJustifyV("top")
|
||||
|
||||
frame.DumpTableFrame = dumpFrame
|
||||
|
||||
local frameUpper = CreateFrame("scrollframe", nil, frame, "BackdropTemplate")
|
||||
local frameLower = CreateFrame("frame", "DetailsNewsWindowLower", frameUpper, "BackdropTemplate")
|
||||
|
||||
frameLower:SetSize(450, 2000)
|
||||
frameUpper:SetPoint("topleft", frame, "topleft", 10, -30)
|
||||
frameUpper:SetWidth(445)
|
||||
frameUpper:SetHeight(500)
|
||||
frameUpper:SetBackdrop({
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
tile = true, tileSize = 16,
|
||||
insets = {left = 1, right = 1, top = 0, bottom = 1},})
|
||||
frameUpper:SetBackdropColor(.1, .1, .1, .3)
|
||||
frameUpper:SetScrollChild(frameLower)
|
||||
|
||||
local slider = CreateFrame("slider", "DetailsNewsWindowSlider", frame, "BackdropTemplate")
|
||||
slider.bg = slider:CreateTexture(nil, "background")
|
||||
slider.bg:SetAllPoints(true)
|
||||
slider.bg:SetTexture(0, 0, 0, 0.5)
|
||||
|
||||
slider.thumb = slider:CreateTexture(nil, "OVERLAY")
|
||||
slider.thumb:SetTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
|
||||
slider.thumb:SetSize(25, 25)
|
||||
|
||||
slider:SetThumbTexture (slider.thumb)
|
||||
slider:SetOrientation("vertical");
|
||||
slider:SetSize(16, 499)
|
||||
slider:SetPoint("topleft", frameUpper, "topright")
|
||||
slider:SetMinMaxValues(0, 2000)
|
||||
slider:SetValue(0)
|
||||
slider:SetScript("OnValueChanged", function(self)
|
||||
frameUpper:SetVerticalScroll (self:GetValue())
|
||||
end)
|
||||
|
||||
frameUpper:EnableMouseWheel(true)
|
||||
frameUpper:SetScript("OnMouseWheel", function(self, delta)
|
||||
local current = slider:GetValue()
|
||||
if (IsShiftKeyDown() and (delta > 0)) then
|
||||
slider:SetValue(0)
|
||||
elseif (IsShiftKeyDown() and (delta < 0)) then
|
||||
slider:SetValue(2000)
|
||||
elseif ((delta < 0) and (current < 2000)) then
|
||||
slider:SetValue(current + 20)
|
||||
elseif ((delta > 0) and (current > 1)) then
|
||||
slider:SetValue(current - 20)
|
||||
end
|
||||
end)
|
||||
|
||||
--text box
|
||||
local texto = frameLower:CreateFontString("DetailsNewsWindowText", "overlay", "GameFontNormal")
|
||||
texto:SetPoint("topleft", frameLower, "topleft")
|
||||
texto:SetJustifyH("left")
|
||||
texto:SetJustifyV("top")
|
||||
texto:SetTextColor(1, 1, 1)
|
||||
texto:SetWidth(450)
|
||||
texto:SetHeight(2500)
|
||||
|
||||
local statusBar = CreateFrame("frame", nil, frame, "BackdropTemplate")
|
||||
statusBar:SetPoint("bottomleft", frame, "bottomleft")
|
||||
statusBar:SetPoint("bottomright", frame, "bottomright")
|
||||
statusBar:SetHeight(20)
|
||||
|
||||
local onToggleAutoOpen = function(_, _, state)
|
||||
Details.auto_open_news_window = state
|
||||
end
|
||||
local autoOpenCheckbox = DetailsFramework:CreateSwitch(statusBar, onToggleAutoOpen, Details.auto_open_news_window, _, _, _, _, "AutoOpenCheckbox", _, _, _, _, _, DetailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
|
||||
autoOpenCheckbox:SetAsCheckBox()
|
||||
autoOpenCheckbox:SetPoint("left", statusBar, "left", 2, 0)
|
||||
|
||||
local autoOpenText = DetailsFramework:CreateLabel(statusBar, "Auto Open on New Changes")
|
||||
autoOpenText:SetPoint("left", autoOpenCheckbox, "right", 2, 0)
|
||||
|
||||
DetailsFramework:ApplyStandardBackdrop(statusBar)
|
||||
statusBar:SetAlpha(0.8)
|
||||
DetailsFramework:BuildStatusbarAuthorInfo(statusBar, "", "")
|
||||
statusBar.authorName:SetPoint("left", statusBar, "left", 207, 0)
|
||||
|
||||
|
||||
function frame:Title (title)
|
||||
frame:SetTitle(title or "")
|
||||
end
|
||||
|
||||
function frame:Text (text)
|
||||
texto:SetText(text or "")
|
||||
end
|
||||
|
||||
frame:Hide()
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
@@ -0,0 +1,464 @@
|
||||
if (true) then
|
||||
--return
|
||||
end
|
||||
|
||||
local addonName, Details222 = ...
|
||||
local Details = _G.Details
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local Loc = _G.LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
--options panel namespace
|
||||
Details222.OptionsPanel = {}
|
||||
|
||||
--local tinsert = _G.tinsert
|
||||
local unpack = _G.unpack
|
||||
local CreateFrame = _G.CreateFrame
|
||||
local UIParent = _G.UIParent
|
||||
local _
|
||||
local preset_version = 3
|
||||
Details.preset_version = preset_version
|
||||
|
||||
--templates
|
||||
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
local options_button_template_selected = detailsFramework.table.copy({}, detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"))
|
||||
options_button_template_selected.backdropbordercolor = {1, .8, .2}
|
||||
|
||||
--options
|
||||
local section_menu_button_width = 135
|
||||
local section_menu_button_height = 20
|
||||
|
||||
local startX = 160
|
||||
|
||||
--build the options window
|
||||
function Details:InitializeOptionsWindow(instance)
|
||||
return Details222.OptionsPanel.InitializeOptionsWindow(instance)
|
||||
end
|
||||
|
||||
--C_Timer.After(2, function()
|
||||
-- Details:OpenOptionsWindow(Details:GetInstance(1), false, 1)
|
||||
--end)
|
||||
|
||||
function Details222.OptionsPanel.InitializeOptionsWindow(instance)
|
||||
local DetailsOptionsWindow = detailsFramework:NewPanel(UIParent, _, "DetailsOptionsWindow", _, 897, 592)
|
||||
local optionsFrame = DetailsOptionsWindow.frame
|
||||
optionsFrame:Hide()
|
||||
|
||||
DetailsOptionsWindow:SetBackdrop({})
|
||||
detailsFramework:AddRoundedCornersToFrame(optionsFrame, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
optionsFrame:SetColor(unpack(Details.frame_background_color))
|
||||
|
||||
optionsFrame.Frame = optionsFrame
|
||||
optionsFrame.__name = "Options"
|
||||
optionsFrame.real_name = "DETAILS_OPTIONS"
|
||||
optionsFrame.__icon = [[Interface\Scenarios\ScenarioIcon-Interact]]
|
||||
_G.DetailsPluginContainerWindow.EmbedPlugin(optionsFrame, optionsFrame, true)
|
||||
optionsFrame.sectionFramesContainer = {}
|
||||
|
||||
local closeButton = detailsFramework:CreateCloseButton(optionsFrame, "$parentCloseButton")
|
||||
closeButton:SetScript("OnClick", function()
|
||||
DetailsPluginContainerWindow:Hide()
|
||||
end)
|
||||
closeButton:SetPoint("topright", optionsFrame, "topright", -5, -5)
|
||||
|
||||
local titleText = detailsFramework:NewLabel(optionsFrame, nil, "$parentTitleLabel", "title", "Details! " .. Loc ["STRING_OPTIONS_WINDOW"], "GameFontHighlightLeft", 12, {227/255, 186/255, 4/255})
|
||||
titleText:SetPoint("top", optionsFrame, "top", 0, -5)
|
||||
|
||||
--[=[
|
||||
local gradientBelowTheLine = DetailsFramework:CreateTexture(optionsFrame, {gradient = "vertical", fromColor = {0, 0, 0, 0.25}, toColor = "transparent"}, 1, 90, "artwork", {0, 1, 0, 1}, "dogGradient")
|
||||
gradientBelowTheLine:SetPoint("bottoms")
|
||||
gradientBelowTheLine:Hide()
|
||||
|
||||
local OTTFrame = CreateFrame("frame", "$parentOverTheTopFrame", optionsFrame)
|
||||
OTTFrame:SetSize(1, 1)
|
||||
OTTFrame:SetFrameLevel(999)
|
||||
OTTFrame:SetPoint("topleft", optionsFrame, "topleft", 0, 0)
|
||||
OTTFrame:Hide()
|
||||
|
||||
--divisor shown above the tab options area
|
||||
local frameBackgroundTextureTopLine = OTTFrame:CreateTexture("$parentHeaderDivisorTopLine", "artwork")
|
||||
local divisorYPosition = -60
|
||||
frameBackgroundTextureTopLine:SetPoint("topleft", optionsFrame, "topleft", startX-9, divisorYPosition)
|
||||
frameBackgroundTextureTopLine:SetPoint("topright", optionsFrame, "topright", -1, divisorYPosition)
|
||||
frameBackgroundTextureTopLine:SetHeight(1)
|
||||
frameBackgroundTextureTopLine:SetTexture(0.1215, 0.1176, 0.1294)
|
||||
frameBackgroundTextureTopLine:Hide()
|
||||
|
||||
--divisor shown in the left side of the tab options area
|
||||
local frameBackgroundTextureLeftLine = OTTFrame:CreateTexture("$parentHeaderDivisorLeftLine", "artwork")
|
||||
frameBackgroundTextureLeftLine:SetPoint("topleft", frameBackgroundTextureTopLine, "topleft", 0, 0)
|
||||
frameBackgroundTextureLeftLine:SetPoint("bottomleft", optionsFrame, "bottomleft", startX-9, 1)
|
||||
frameBackgroundTextureLeftLine:SetHeight(1)
|
||||
frameBackgroundTextureLeftLine:SetTexture(0.1215, 0.1176, 0.1294)
|
||||
frameBackgroundTextureLeftLine:Hide()
|
||||
|
||||
local frameBackgroundTexture = optionsFrame:CreateTexture(nil, "artwork")
|
||||
frameBackgroundTexture:SetPoint("topleft", optionsFrame, "topleft", startX-9, divisorYPosition-1)
|
||||
frameBackgroundTexture:SetPoint("bottomright", optionsFrame, "bottomright", -1, 0)
|
||||
frameBackgroundTexture:SetTexture (0.2317647, 0.2317647, 0.2317647)
|
||||
frameBackgroundTexture:SetVertexColor (0.27, 0.27, 0.27)
|
||||
frameBackgroundTexture:SetAlpha (0.3)
|
||||
frameBackgroundTexture:Hide()
|
||||
--]=]
|
||||
|
||||
--select the instance to edit
|
||||
local onSelectInstance = function(_, _, instanceId)
|
||||
---@type instance
|
||||
local instanceObject = Details.tabela_instancias[instanceId]
|
||||
if (not instanceObject:IsEnabled() or not instanceObject:IsStarted()) then
|
||||
Details.CriarInstancia (_, _, instanceObject.meu_id)
|
||||
end
|
||||
|
||||
Details222.OptionsPanel.SetCurrentInstanceAndRefresh(instanceObject)
|
||||
optionsFrame.updateMicroFrames()
|
||||
end
|
||||
|
||||
local buildInstanceMenu = function()
|
||||
local instanceList = {}
|
||||
for index = 1, math.min (#Details.tabela_instancias, Details.instances_amount) do
|
||||
local instanceObject = Details.tabela_instancias[index]
|
||||
|
||||
--what the window is showing
|
||||
local atributo = instanceObject.atributo
|
||||
local sub_atributo = instanceObject.sub_atributo
|
||||
|
||||
if (atributo == 5) then --custom
|
||||
local CustomObject = Details.custom[sub_atributo]
|
||||
if (not CustomObject) then
|
||||
instanceObject:ResetAttribute()
|
||||
atributo = instanceObject.atributo
|
||||
sub_atributo = instanceObject.sub_atributo
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " " .. Details.atributos.lista[atributo] .. " - " .. Details.sub_atributos[atributo].lista[sub_atributo], onclick = onSelectInstance, icon = Details.sub_atributos[atributo].icones[sub_atributo][1], texcoord = Details.sub_atributos[atributo].icones[sub_atributo][2]}
|
||||
else
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " " .. CustomObject.name, onclick = onSelectInstance, icon = CustomObject.icon}
|
||||
end
|
||||
else
|
||||
local modo = instanceObject.modo
|
||||
|
||||
if (modo == 1) then --solo plugin
|
||||
atributo = Details.SoloTables.Mode or 1
|
||||
local SoloInfo = Details.SoloTables.Menu[atributo]
|
||||
if (SoloInfo) then
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " " .. SoloInfo[1], onclick = onSelectInstance, icon = SoloInfo [2]}
|
||||
else
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " unknown", onclick = onSelectInstance, icon = ""}
|
||||
end
|
||||
|
||||
elseif (modo == 4) then --raid plugin
|
||||
local plugin_name = instanceObject.current_raid_plugin or instanceObject.last_raid_plugin
|
||||
if (plugin_name) then
|
||||
local plugin_object = Details:GetPlugin(plugin_name)
|
||||
if (plugin_object) then
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " " .. plugin_object.__name, onclick = onSelectInstance, icon = plugin_object.__icon}
|
||||
else
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " unknown", onclick = onSelectInstance, icon = ""}
|
||||
end
|
||||
else
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " unknown", onclick = onSelectInstance, icon = ""}
|
||||
end
|
||||
else
|
||||
instanceList[#instanceList+1] = {value = index, label = "#".. index .. " " .. Details.atributos.lista[atributo] .. " - " .. Details.sub_atributos [atributo].lista [sub_atributo], onclick = onSelectInstance, icon = Details.sub_atributos [atributo].icones[sub_atributo] [1], texcoord = Details.sub_atributos [atributo].icones[sub_atributo] [2]}
|
||||
end
|
||||
end
|
||||
end
|
||||
return instanceList
|
||||
end
|
||||
|
||||
local instanceSelection = detailsFramework:NewDropDown(optionsFrame, _, "$parentInstanceSelectDropdown", "instanceDropdown", 200, 18, buildInstanceMenu) --, nil, options_dropdown_template
|
||||
optionsFrame.instanceDropdown = instanceSelection
|
||||
instanceSelection:SetPoint("topright", optionsFrame, "topright", -7, -39)
|
||||
instanceSelection:SetTemplate(options_dropdown_template)
|
||||
instanceSelection:SetHook("OnEnter", function()
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:Preset(2)
|
||||
GameCooltip:AddLine(Loc ["STRING_MINITUTORIAL_OPTIONS_PANEL1"])
|
||||
GameCooltip:ShowCooltip(instanceSelection.widget, "tooltip")
|
||||
end)
|
||||
instanceSelection:SetHook("OnLeave", function()
|
||||
GameCooltip:Hide()
|
||||
end)
|
||||
|
||||
local formatFooterText = function(object)
|
||||
object.fontface = "GameFontNormal"
|
||||
object.fontsize = 10
|
||||
object.fontcolor = {1, 0.82, 0}
|
||||
end
|
||||
|
||||
local instancesFontString = detailsFramework:NewLabel(optionsFrame, nil, "$parentInstanceDropdownLabel", "instancetext", Loc ["STRING_OPTIONS_EDITINSTANCE"], "GameFontNormal", 12)
|
||||
instancesFontString:SetPoint("right", instanceSelection, "left", -2, 1)
|
||||
formatFooterText(instancesFontString)
|
||||
|
||||
local bigdogImage = detailsFramework:NewImage(optionsFrame, [[Interface\MainMenuBar\UI-MainMenuBar-EndCap-Human]], 180*0.9, 200*0.9, nil, {1, 0, 0, 1}, "backgroundBigDog", "$parentBackgroundBigDog")
|
||||
bigdogImage:SetPoint("bottomright", optionsFrame, "bottomright", 0, 0)
|
||||
bigdogImage:SetAlpha(.25)
|
||||
|
||||
--editing group checkbox
|
||||
local onToggleEditingGroup = function(self, fixparam, value)
|
||||
Details.options_group_edit = value
|
||||
end
|
||||
local editingGroupCheckBox = detailsFramework:CreateSwitch(optionsFrame, onToggleEditingGroup, Details.options_group_edit, _, _, _, _, _, "$parentEditGroupCheckbox", _, _, _, _, detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
|
||||
editingGroupCheckBox:SetAsCheckBox()
|
||||
editingGroupCheckBox.tooltip = Loc ["STRING_MINITUTORIAL_OPTIONS_PANEL2"]
|
||||
|
||||
local editingGroupLabel = detailsFramework:NewLabel(optionsFrame, nil, "$parentEditingGroupLabel", "editingGroupLabel", "Editing Group:", "GameFontNormal", 12) --localize-me
|
||||
editingGroupLabel:SetPoint("bottomleft", instancesFontString, "topleft", 0, 5)
|
||||
editingGroupCheckBox:SetPoint("left", editingGroupLabel, "right", 2, 0)
|
||||
formatFooterText(editingGroupLabel)
|
||||
|
||||
--create test bars ~test
|
||||
detailsFramework:NewColor("C_OptionsButtonOrange", 0.9999, 0.8196, 0, 1)
|
||||
local create_test_bars_func = function()
|
||||
Details.CreateTestBars()
|
||||
if (not Details.test_bar_update) then
|
||||
Details:StartTestBarUpdate()
|
||||
else
|
||||
Details:StopTestBarUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
local fillbars = detailsFramework:NewButton(optionsFrame, _, "$parentCreateExampleBarsButton", nil, 140, 20, create_test_bars_func, nil, nil, nil, Loc ["STRING_OPTIONS_TESTBARS"], 1)
|
||||
PixelUtil.SetPoint(fillbars, "topleft", optionsFrame.widget, "topleft", startX-8, -30)
|
||||
fillbars:SetTemplate(options_button_template)
|
||||
fillbars:SetIcon ("Interface\\AddOns\\Details\\images\\icons", nil, nil, nil, {323/512, 365/512, 42/512, 78/512}, {1, 1, 1, 0.6}, 4, 2)
|
||||
|
||||
--change log
|
||||
local changelog = detailsFramework:NewButton(optionsFrame, _, "$parentOpenChangeLogButton", nil, 140, 20, Details.OpenNewsWindow, "change_log", nil, nil, Loc ["STRING_OPTIONS_CHANGELOG"], 1)
|
||||
changelog:SetPoint("left", fillbars, "right", 10, 0)
|
||||
changelog:SetTemplate(options_button_template)
|
||||
changelog:SetIcon ("Interface\\AddOns\\Details\\images\\icons", nil, nil, nil, {367/512, 399/512, 43/512, 76/512}, {1, 1, 1, 0.8}, 4, 2)
|
||||
|
||||
--search field
|
||||
local searchBox = detailsFramework:CreateTextEntry(optionsFrame, function()end, 140, 20, _, _, _, options_dropdown_template)
|
||||
searchBox:SetPoint("left", changelog, "right", 10, 0)
|
||||
searchBox:SetAsSearchBox()
|
||||
|
||||
searchBox:SetHook("OnChar", function()
|
||||
if (searchBox.text ~= "") then
|
||||
local searchSection = optionsFrame.sectionFramesContainer[19]
|
||||
searchSection.sectionButton:Enable()
|
||||
searchSection.sectionButton:Click()
|
||||
|
||||
local searchingFor = searchBox.text
|
||||
local allSectionFrames = optionsFrame.sectionFramesContainer
|
||||
|
||||
local allSectionNames = {}
|
||||
local allSectionOptions = {}
|
||||
|
||||
for i = 1, #allSectionFrames do
|
||||
local sectionFrame = allSectionFrames[i]
|
||||
local sectionOptionsTable = sectionFrame.sectionOptions
|
||||
|
||||
allSectionNames[#allSectionNames+1] = sectionFrame.name
|
||||
allSectionOptions[#allSectionOptions+1] = sectionOptionsTable
|
||||
end
|
||||
|
||||
--this table will hold all options
|
||||
local allOptions = {}
|
||||
--start the fill process filling 'allOptions' with each individual option from each tab
|
||||
for i = 1, #allSectionOptions do
|
||||
local sectionOptions = allSectionOptions[i]
|
||||
local lastLabel = nil
|
||||
for k, setting in pairs(sectionOptions) do
|
||||
if (type(setting) == "table") then
|
||||
if (setting.type == "label") then
|
||||
lastLabel = setting
|
||||
end
|
||||
if (setting.name) then
|
||||
allOptions[#allOptions+1] = {setting = setting, label = lastLabel, header = allSectionNames[i]}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local searchingText = string.lower(searchingFor)
|
||||
searchBox:SetFocus()
|
||||
|
||||
local options = {}
|
||||
|
||||
local lastTab = nil
|
||||
local lastLabel = nil
|
||||
for i = 1, #allOptions do
|
||||
local optionData = allOptions[i]
|
||||
local optionName = string.lower(optionData.setting.name)
|
||||
if (optionName:find(searchingText)) then
|
||||
if optionData.header ~= lastTab then
|
||||
if lastTab ~= nil then
|
||||
options[#options+1] = {type = "label", get = function() return "" end, text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")} -- blank
|
||||
end
|
||||
options[#options+1] = {type = "label", get = function() return optionData.header end, text_template = {color = "silver", size = 14, font = detailsFramework:GetBestFontForLanguage()}}
|
||||
lastTab = optionData.header
|
||||
lastLabel = nil
|
||||
end
|
||||
if optionData.label ~= lastLabel then
|
||||
options[#options+1] = optionData.label
|
||||
lastLabel = optionData.label
|
||||
end
|
||||
options[#options+1] = optionData.setting
|
||||
end
|
||||
end
|
||||
|
||||
local startX = 200
|
||||
local startY = -60
|
||||
|
||||
detailsFramework:BuildMenuVolatile(searchSection, options, startX, startY, 560, true, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template, globalCallback)
|
||||
|
||||
else
|
||||
optionsFrame.sectionFramesContainer[19].sectionButton:Disable()
|
||||
end
|
||||
end)
|
||||
|
||||
local sectionsName = { --section names
|
||||
[1] = Loc ["STRING_OPTIONSMENU_DISPLAY"],
|
||||
[3] = Loc ["STRING_OPTIONSMENU_ROWSETTINGS"],
|
||||
[4] = Loc ["STRING_OPTIONSMENU_ROWTEXTS"],
|
||||
|
||||
[5] = Loc ["STRING_OPTIONSMENU_TITLEBAR"], --titlebar
|
||||
[6] = Loc ["STRING_OPTIONSMENU_WINDOWBODY"], --window body
|
||||
[7] = Loc ["STRING_OPTIONS_INSTANCE_STATUSBAR_ANCHOR"], --statusbar
|
||||
[12] = Loc ["STRING_OPTIONSMENU_WALLPAPER"],
|
||||
[13] = Loc ["STRING_OPTIONSMENU_AUTOMATIC"],
|
||||
|
||||
[9] = Loc ["STRING_OPTIONSMENU_PROFILES"],
|
||||
[2] = Loc ["STRING_OPTIONSMENU_SKIN"],
|
||||
[8] = Loc ["STRING_OPTIONSMENU_PLUGINS"],
|
||||
[10] = Loc ["STRING_OPTIONSMENU_TOOLTIP"],
|
||||
[11] = Loc ["STRING_OPTIONSMENU_DATAFEED"],
|
||||
|
||||
[14] = Loc ["STRING_OPTIONSMENU_RAIDTOOLS"],
|
||||
[15] = "Broadcaster Tools",
|
||||
[16] = Loc ["STRING_OPTIONSMENU_SPELLS"],
|
||||
[17] = Loc ["STRING_OPTIONSMENU_DATACHART"],
|
||||
[18] = "Mythic Dungeon",
|
||||
[19] = "Search Results",
|
||||
[20] = "Combat Log",
|
||||
}
|
||||
|
||||
local optionsSectionsOrder = {
|
||||
1, 20, "", 3, 4, "", 5, 6, 7, 12, 13, "", 9, 2, 8, 10, 11, 18, "", 14, 15, 16, 17, "", 19
|
||||
}
|
||||
|
||||
local maxSectionIds = 0
|
||||
for k in pairs(sectionsName) do
|
||||
maxSectionIds = maxSectionIds + 1
|
||||
end
|
||||
|
||||
Details222.OptionsPanel.maxSectionIds = maxSectionIds
|
||||
|
||||
local buttonYPosition = -40
|
||||
|
||||
function Details222.OptionsPanel.SelectOptionsSection(sectionId)
|
||||
for i = 1, maxSectionIds do
|
||||
optionsFrame.sectionFramesContainer[i]:Hide()
|
||||
if (optionsFrame.sectionFramesContainer[i].sectionButton) then
|
||||
optionsFrame.sectionFramesContainer[i].sectionButton:SetTemplate(options_button_template)
|
||||
optionsFrame.sectionFramesContainer[i].sectionButton:SetIcon({.4, .4, .4}, 4, section_menu_button_height -4, "overlay")
|
||||
end
|
||||
end
|
||||
|
||||
optionsFrame.sectionFramesContainer[sectionId]:Show()
|
||||
if(optionsFrame.sectionFramesContainer[sectionId].RefreshOptions) then
|
||||
optionsFrame.sectionFramesContainer[sectionId]:RefreshOptions()
|
||||
end
|
||||
--hightlight the option button
|
||||
optionsFrame.sectionFramesContainer[sectionId].sectionButton:SetTemplate(options_button_template_selected)
|
||||
optionsFrame.sectionFramesContainer[sectionId].sectionButton:SetIcon({1, 1, 0}, 4, section_menu_button_height -4, "overlay")
|
||||
end
|
||||
|
||||
Details222.OptionsPanel.SetCurrentInstance(instance)
|
||||
|
||||
--create frames for sections
|
||||
for index, sectionId in ipairs(optionsSectionsOrder) do
|
||||
if (type(sectionId) == "number") then
|
||||
local sectionFrame = CreateFrame("frame", "$parentTab" .. sectionId, optionsFrame, "BackdropTemplate")
|
||||
sectionFrame:SetPoint("topleft", optionsFrame, "topleft", -40, 22)
|
||||
sectionFrame:SetSize(optionsFrame:GetSize())
|
||||
sectionFrame:EnableMouse(false)
|
||||
|
||||
sectionFrame.name = sectionsName[sectionId]
|
||||
optionsFrame.sectionFramesContainer[sectionId] = sectionFrame
|
||||
|
||||
local buildOptionSectionFunc = Details.optionsSection[sectionId]
|
||||
if (buildOptionSectionFunc) then
|
||||
--call the function to create the frame
|
||||
buildOptionSectionFunc(sectionFrame)
|
||||
|
||||
--create a button for the section
|
||||
local sectionButton = detailsFramework:CreateButton(optionsFrame, function() Details222.OptionsPanel.SelectOptionsSection(sectionId) end, section_menu_button_width, section_menu_button_height, sectionsName[sectionId], sectionId, nil, nil, nil, "$parentButtonSection" .. sectionId, nil, options_button_template, options_text_template)
|
||||
sectionButton:SetIcon({.4, .4, .4}, 4, section_menu_button_height -4, "overlay")
|
||||
sectionButton:SetPoint("topleft", optionsFrame, "topleft", 10, buttonYPosition)
|
||||
buttonYPosition = buttonYPosition - (section_menu_button_height + 1)
|
||||
sectionFrame.sectionButton = sectionButton
|
||||
|
||||
if (sectionId == 19) then --search results
|
||||
sectionButton:Disable()
|
||||
|
||||
elseif (sectionId == 1) then
|
||||
sectionButton:SetIcon({1, 1, 0}, 4, section_menu_button_height -4, "overlay")
|
||||
end
|
||||
end
|
||||
else
|
||||
buttonYPosition = buttonYPosition - 15
|
||||
end
|
||||
end
|
||||
|
||||
function Details222.OptionsPanel.GetOptionsSection(sectionId)
|
||||
return optionsFrame.sectionFramesContainer[sectionId]
|
||||
end
|
||||
|
||||
function optionsFrame.RefreshWindow()
|
||||
if (not _G.DetailsOptionsWindow.instance) then
|
||||
local lowerInstance = Details:GetLowerInstanceNumber()
|
||||
if (not lowerInstance) then
|
||||
local instance = Details:GetInstance(1)
|
||||
Details.CriarInstancia(_, _, 1)
|
||||
Details:OpenOptionsWindow(instance)
|
||||
else
|
||||
Details:OpenOptionsWindow(Details:GetInstance(lowerInstance))
|
||||
end
|
||||
else
|
||||
Details:OpenOptionsWindow(_G.DetailsOptionsWindow.instance)
|
||||
end
|
||||
end
|
||||
|
||||
Details222.OptionsPanel.SelectOptionsSection(1)
|
||||
end
|
||||
|
||||
-- ~options
|
||||
---open the options window
|
||||
---@param instance instance
|
||||
---@param bNoReopen boolean|nil
|
||||
---@param section any
|
||||
function Details:OpenOptionsWindow(instance, bNoReopen, section)
|
||||
if (not instance.GetId or not instance:GetId()) then
|
||||
instance, bNoReopen, section = unpack(instance)
|
||||
end
|
||||
|
||||
if (not bNoReopen and not instance:IsEnabled() or not instance:IsStarted()) then
|
||||
Details:CreateInstance(instance:GetId())
|
||||
end
|
||||
|
||||
GameCooltip:Close()
|
||||
|
||||
local window = _G.DetailsOptionsWindow
|
||||
if (not window) then
|
||||
Details222.OptionsPanel.InitializeOptionsWindow(instance)
|
||||
window = _G.DetailsOptionsWindow
|
||||
end
|
||||
|
||||
Details222.OptionsPanel.SetCurrentInstanceAndRefresh(instance)
|
||||
_G.DetailsPluginContainerWindow.OpenPlugin(_G.DetailsOptionsWindow)
|
||||
|
||||
if (section) then
|
||||
Details222.OptionsPanel.SelectOptionsSection(section)
|
||||
end
|
||||
|
||||
window.instanceDropdown:Refresh()
|
||||
window.instanceDropdown:Select(instance:GetId())
|
||||
|
||||
window.updateMicroFrames()
|
||||
|
||||
DetailsPluginContainerWindowMenuFrame:SetColor(unpack(Details.frame_background_color))
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,451 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
|
||||
function Details:InitializePlaterIntegrationWindow()
|
||||
local DetailsPlaterIntegrationPanel = DF:CreateSimplePanel(UIParent, 700, 480, "Details! Plater Nameplates Integration", "DetailsPlaterIntegrationPanel")
|
||||
DetailsPlaterIntegrationPanel.Frame = DetailsPlaterIntegrationPanel
|
||||
DetailsPlaterIntegrationPanel.__name = "Plater Nameplates"
|
||||
DetailsPlaterIntegrationPanel.real_name = "DETAILS_PLATERWINDOW"
|
||||
DetailsPlaterIntegrationPanel.__icon = [[Interface\AddOns\Details\images\plater_icon]]
|
||||
DetailsPlaterIntegrationPanel.__iconcoords = {0, 1, 0, 1}
|
||||
DetailsPlaterIntegrationPanel.__iconcolor = "white"
|
||||
--DetailsPluginContainerWindow.EmbedPlugin (DetailsPlaterIntegrationPanel, DetailsPlaterIntegrationPanel, true)
|
||||
|
||||
function DetailsPlaterIntegrationPanel.RefreshWindow()
|
||||
Details.OpenPlaterIntegrationWindow()
|
||||
end
|
||||
|
||||
DetailsPlaterIntegrationPanel:Hide()
|
||||
end
|
||||
|
||||
function Details.OpenPlaterIntegrationWindow()
|
||||
if (not DetailsPlaterIntegrationPanel or not DetailsPlaterIntegrationPanel.Initialized) then
|
||||
|
||||
DetailsPlaterIntegrationPanel.Initialized = true
|
||||
|
||||
local f = DetailsPlaterIntegrationPanel or DF:CreateSimplePanel(UIParent, 700, 480, "Details! Plater Nameplates Integration", "DetailsPlaterIntegrationPanel")
|
||||
|
||||
--background
|
||||
f.bg1 = f:CreateTexture(nil, "background")
|
||||
f.bg1:SetTexture([[Interface\AddOns\Details\images\background]], true)
|
||||
f.bg1:SetAlpha(0.8)
|
||||
f.bg1:SetVertexColor(0.27, 0.27, 0.27)
|
||||
f.bg1:SetVertTile(true)
|
||||
f.bg1:SetHorizTile(true)
|
||||
f.bg1:SetSize(790, 454)
|
||||
f.bg1:SetAllPoints()
|
||||
f:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
f:SetBackdropColor(.5, .5, .5, .7)
|
||||
f:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
--anchor text function
|
||||
local anchor_names = {"Top Left", "Left", "Bottom Left", "Bottom", "Bottom Right", "Right", "Top Right", "Top", "Center", "Inner Left", "Inner Right", "Inner Top", "Inner Bottom"}
|
||||
local build_anchor_side_table = function(member)
|
||||
local t = {}
|
||||
for i = 1, 13 do
|
||||
table.insert(t, {
|
||||
label = anchor_names[i],
|
||||
value = i,
|
||||
onclick = function(_, _, value)
|
||||
Details.plater [member].side = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local menu_table = {
|
||||
|
||||
{type = "label", get = function() return "Add Real Time DPS Info in the Nameplate:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
|
||||
--real time dps from all sources
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.realtime_dps_enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_enabled = value
|
||||
|
||||
Details:RefreshPlaterIntegration()
|
||||
|
||||
if (not value) then
|
||||
Details:Msg("a /reload might be needed to disable this setting.")
|
||||
else
|
||||
if (Plater) then
|
||||
Plater.RefreshDBUpvalues()
|
||||
end
|
||||
end
|
||||
end,
|
||||
name = "Show Real Time Dps",
|
||||
desc = "Show Real Time DPS on the nameplate.\n\nReal time DPS is how much damage has been inflicted to the unit in the last 5 seconds.",
|
||||
},
|
||||
--text size
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_size = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = 6,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Text Size",
|
||||
desc = "Text Size",
|
||||
},
|
||||
--text color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
local color = Details.plater.realtime_dps_color
|
||||
return {color [1], color [2], color [3], color [4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.plater.realtime_dps_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
desc = "Text Color",
|
||||
name = "Text Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--text shadow
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.realtime_dps_shadow end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_shadow = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
name = "Text Shadow",
|
||||
desc = "Text Shadow",
|
||||
},
|
||||
--text anchor
|
||||
--anchor location
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.plater.realtime_dps_anchor.side end,
|
||||
values = function() return build_anchor_side_table ("realtime_dps_anchor") end,
|
||||
name = "Anchor Point",
|
||||
desc = "Which side of the nameplate the text is attach to.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_anchor.x end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_anchor.x = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor X Offset",
|
||||
desc = "Slightly move the text horizontally.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_anchor.y end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_anchor.y = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor Y Offset",
|
||||
desc = "Slightly move the text vertically.",
|
||||
},
|
||||
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Add Real Time DPS Info Only From You in the Nameplate:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
|
||||
--real time dps from the player only
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.realtime_dps_player_enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_player_enabled = value
|
||||
|
||||
Details:RefreshPlaterIntegration()
|
||||
|
||||
if (not value) then
|
||||
Details:Msg("a /reload might be needed to disable this setting.")
|
||||
else
|
||||
if (Plater) then
|
||||
Plater.RefreshDBUpvalues()
|
||||
end
|
||||
end
|
||||
end,
|
||||
name = "Show Real Time Dps (From You)",
|
||||
desc = "Show Real Time DPS you are currently applying in the unit.\n\nReal time DPS is how much damage has been inflicted to the unit in the last 5 seconds.",
|
||||
},
|
||||
--text size
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_player_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_player_size = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = 6,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Text Size",
|
||||
desc = "Text Size",
|
||||
},
|
||||
--text color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
local color = Details.plater.realtime_dps_player_color
|
||||
return {color [1], color [2], color [3], color [4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.plater.realtime_dps_player_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
desc = "Text Color",
|
||||
name = "Text Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--text shadow
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.realtime_dps_player_shadow end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_player_shadow = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
name = "Text Shadow",
|
||||
desc = "Text Shadow",
|
||||
},
|
||||
--text anchor
|
||||
--anchor location
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.plater.realtime_dps_player_anchor.side end,
|
||||
values = function() return build_anchor_side_table ("realtime_dps_player_anchor") end,
|
||||
name = "Anchor Point",
|
||||
desc = "Which side of the nameplate the text is attach to.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_player_anchor.x end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_player_anchor.x = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor X Offset",
|
||||
desc = "Slightly move the text horizontally.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.realtime_dps_player_anchor.y end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.realtime_dps_player_anchor.y = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor Y Offset",
|
||||
desc = "Slightly move the text vertically.",
|
||||
},
|
||||
|
||||
{type = "breakline"},
|
||||
{type = "label", get = function() return "Add Total Damage Taken in the Nameplate:" end, text_template = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")},
|
||||
|
||||
--total damage taken from all sources
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.damage_taken_enabled end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.damage_taken_enabled = value
|
||||
|
||||
Details:RefreshPlaterIntegration()
|
||||
|
||||
if (not value) then
|
||||
Details:Msg("a /reload might be needed to disable this setting.")
|
||||
else
|
||||
if (Plater) then
|
||||
Plater.RefreshDBUpvalues()
|
||||
end
|
||||
end
|
||||
end,
|
||||
name = "Show Total Damage Taken",
|
||||
desc = "Show the total damage taken by the unit",
|
||||
},
|
||||
--text size
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.damage_taken_size end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.damage_taken_size = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = 6,
|
||||
max = 32,
|
||||
step = 1,
|
||||
name = "Text Size",
|
||||
desc = "Text Size",
|
||||
},
|
||||
--text color
|
||||
{
|
||||
type = "color",
|
||||
get = function()
|
||||
local color = Details.plater.damage_taken_color
|
||||
return {color [1], color [2], color [3], color [4]}
|
||||
end,
|
||||
set = function(self, r, g, b, a)
|
||||
local color = Details.plater.damage_taken_color
|
||||
color[1], color[2], color[3], color[4] = r, g, b, a
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
desc = "Text Color",
|
||||
name = "Text Color",
|
||||
text_template = options_text_template,
|
||||
},
|
||||
--text shadow
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return Details.plater.damage_taken_shadow end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.damage_taken_shadow = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
name = "Text Shadow",
|
||||
desc = "Text Shadow",
|
||||
},
|
||||
--text anchor
|
||||
--anchor location
|
||||
{
|
||||
type = "select",
|
||||
get = function() return Details.plater.damage_taken_anchor.side end,
|
||||
values = function() return build_anchor_side_table ("damage_taken_anchor") end,
|
||||
name = "Anchor Point",
|
||||
desc = "Which side of the nameplate the text is attach to.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.damage_taken_anchor.x end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.damage_taken_anchor.x = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor X Offset",
|
||||
desc = "Slightly move the text horizontally.",
|
||||
},
|
||||
--anchor x offset
|
||||
{
|
||||
type = "range",
|
||||
get = function() return Details.plater.damage_taken_anchor.y end,
|
||||
set = function(self, fixedparam, value)
|
||||
Details.plater.damage_taken_anchor.y = value
|
||||
if (Plater) then
|
||||
Plater.UpdateAllPlates()
|
||||
end
|
||||
end,
|
||||
min = -20,
|
||||
max = 20,
|
||||
step = 1,
|
||||
name = "Anchor Y Offset",
|
||||
desc = "Slightly move the text vertically.",
|
||||
},
|
||||
}
|
||||
|
||||
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
local titleBackground = CreateFrame("frame", nil, f,"BackdropTemplate")
|
||||
titleBackground:SetPoint("topleft", f, "topleft", 10, -30)
|
||||
titleBackground:SetPoint("topright", f, "topright", -10, -30)
|
||||
titleBackground:SetHeight(80)
|
||||
|
||||
--background
|
||||
titleBackground.bg1 = titleBackground:CreateTexture(nil, "background")
|
||||
titleBackground.bg1:SetTexture([[Interface\AddOns\Details\images\background]])
|
||||
titleBackground.bg1:SetAlpha(0.8)
|
||||
titleBackground.bg1:SetVertexColor(0.27, 0.27, 0.27)
|
||||
titleBackground.bg1:SetVertTile(true)
|
||||
titleBackground.bg1:SetHorizTile(true)
|
||||
titleBackground.bg1:SetSize(790, 454)
|
||||
titleBackground.bg1:SetAllPoints()
|
||||
titleBackground:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
titleBackground:SetBackdropColor(.5, .5, .5, .7)
|
||||
titleBackground:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
local platerTitle = DF:CreateLabel(titleBackground, "Plater Nameplates Integration", 16, "white")
|
||||
local platerDesc1 = DF:CreateLabel(titleBackground, "Add DPS and Damage information directly into the nameplate", 11, "silver")
|
||||
local platerDesc2 = DF:CreateLabel(titleBackground, "See how much damage the enemy is taking in real time!", 11, "silver")
|
||||
local platerImage = DF:CreateImage(titleBackground, "Interface\\AddOns\\Details\\images\\plater_image")
|
||||
platerImage:SetSize(256, 64)
|
||||
|
||||
platerImage:SetPoint("topright", f, "topright", -150, -35)
|
||||
platerTitle:SetPoint(10, -15)
|
||||
platerDesc1:SetPoint(10, -35)
|
||||
platerDesc2:SetPoint(10, -47)
|
||||
|
||||
DF:BuildMenu (f, menu_table, 10, -140, 460, true, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
|
||||
if (not Plater) then
|
||||
for _, widget in ipairs(f.widget_list) do
|
||||
if (widget.Disable) then
|
||||
widget:Disable()
|
||||
end
|
||||
end
|
||||
|
||||
local PlaterDisabled1 = DF:CreateLabel(f, "Plater isn't installed! you may download it from the Curseforge app.", 16, "red")
|
||||
PlaterDisabled1:SetPoint(10, -330)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin (DetailsPlaterIntegrationPanel)
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
local Details = Details
|
||||
local addonName, Details222 = ...
|
||||
---@type detailsframework
|
||||
local detailsFramework = DetailsFramework
|
||||
local _
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local L = _G.LibStub("AceLocale-3.0"):GetLocale( "Details" )
|
||||
|
||||
function Details:OpenProfiler()
|
||||
|
||||
--isn't first run, so just quit
|
||||
if (not Details.character_first_run) then
|
||||
return
|
||||
|
||||
elseif (Details.is_first_run) then
|
||||
return
|
||||
|
||||
elseif (Details.always_use_profile) then
|
||||
return
|
||||
|
||||
else
|
||||
--check is this is the first run of the addon (after being installed)
|
||||
local amount = 0
|
||||
for name, profile in pairs(_detalhes_global.__profiles) do
|
||||
amount = amount + 1
|
||||
end
|
||||
if (amount == 1) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local f = Details:CreateWelcomePanel (nil, nil, 250, 300, true)
|
||||
f:SetPoint("right", UIParent, "right", -5, 0)
|
||||
|
||||
local logo = f:CreateTexture(nil, "artwork")
|
||||
logo:SetTexture([[Interface\AddOns\Details\images\logotipo]])
|
||||
logo:SetSize(256*0.8, 128*0.8)
|
||||
logo:SetPoint("center", f, "center", 0, 0)
|
||||
logo:SetPoint("top", f, "top", 20, 20)
|
||||
|
||||
local string_profiler = f:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
string_profiler:SetPoint("top", logo, "bottom", -20, 10)
|
||||
string_profiler:SetText("Profiler!")
|
||||
|
||||
local string_profiler = f:CreateFontString(nil, "artwork", "GameFontNormal")
|
||||
string_profiler:SetPoint("topleft", f, "topleft", 10, -130)
|
||||
string_profiler:SetText(L["STRING_OPTIONS_PROFILE_SELECTEXISTING"])
|
||||
string_profiler:SetWidth(230)
|
||||
Details:SetFontSize(string_profiler, 11)
|
||||
Details:SetFontColor(string_profiler, "white")
|
||||
|
||||
--get the new profile name
|
||||
local current_profile = Details:GetCurrentProfileName()
|
||||
|
||||
local on_select_profile = function(_, _, profilename)
|
||||
if (profilename ~= Details:GetCurrentProfileName()) then
|
||||
Details:ApplyProfile (profilename)
|
||||
if (_G.DetailsOptionsWindow and _G.DetailsOptionsWindow:IsShown()) then
|
||||
Details:OpenOptionsWindow (_G.DetailsOptionsWindow.instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local texcoord = {5/32, 30/32, 4/32, 28/32}
|
||||
|
||||
local fill_dropdown = function()
|
||||
local t = {
|
||||
{value = current_profile, label = L["STRING_OPTIONS_PROFILE_USENEW"], onclick = on_select_profile, icon = [[Interface\FriendsFrame\UI-Toast-FriendRequestIcon]], texcoord = {4/32, 30/32, 4/32, 28/32}, iconcolor = "orange"}
|
||||
}
|
||||
for _, profilename in ipairs(Details:GetProfileList()) do
|
||||
if (profilename ~= current_profile) then
|
||||
t[#t+1] = {value = profilename, label = profilename, onclick = on_select_profile, icon = [[Interface\FriendsFrame\UI-Toast-FriendOnlineIcon]], texcoord = texcoord, iconcolor = "yellow"}
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local dropdown = Details.gump:NewDropDown (f, f, "DetailsProfilerProfileSelectorDropdown", "dropdown", 220, 20, fill_dropdown, 1)
|
||||
dropdown:SetPoint(15, -190)
|
||||
|
||||
local confirm_func = function()
|
||||
if (current_profile ~= Details:GetCurrentProfileName()) then
|
||||
Details:EraseProfile (current_profile)
|
||||
end
|
||||
f:Hide()
|
||||
end
|
||||
local confirm = Details.gump:NewButton(f, f, "DetailsProfilerProfileConfirmButton", "button", 150, 20, confirm_func, nil, nil, nil, "Okey!")
|
||||
confirm:SetPoint(50, -250)
|
||||
confirm:InstallCustomTexture()
|
||||
end
|
||||
@@ -0,0 +1,951 @@
|
||||
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
local Details = _G.Details
|
||||
local gump = Details.gump
|
||||
local _
|
||||
|
||||
--details API functions -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function Details:FastReportWindow(window)
|
||||
if (not DetailsReportWindow) then
|
||||
gump:CriaJanelaReport()
|
||||
DetailsReportWindow:Hide()
|
||||
end
|
||||
|
||||
local instance = Details:GetInstance(window)
|
||||
if (instance) then
|
||||
if (instance.atributo == 1) then
|
||||
Details.report_lines = 14
|
||||
|
||||
elseif (instance.atributo == 2) then
|
||||
Details.report_lines = 6
|
||||
|
||||
else
|
||||
Details.report_lines = max(10, instance.rows_fit_in_window)
|
||||
end
|
||||
|
||||
if (IsInRaid()) then
|
||||
Details.report_where = "RAID"
|
||||
|
||||
elseif (GetNumSubgroupMembers() > 0) then
|
||||
Details.report_where = "PARTY"
|
||||
|
||||
else
|
||||
Details.report_where = "SAY"
|
||||
end
|
||||
|
||||
instance:monta_relatorio()
|
||||
else
|
||||
Details:Msg(Loc ["STRING_WINDOW_NOTFOUND"])
|
||||
end
|
||||
end
|
||||
|
||||
function Details.ReportFromLatest(_, _, index)
|
||||
local reportTable = Details.latest_report_table[index]
|
||||
if (reportTable) then
|
||||
if (not DetailsReportWindow) then
|
||||
gump:CriaJanelaReport()
|
||||
DetailsReportWindow:Hide()
|
||||
end
|
||||
|
||||
local id, attribute, subattribute, amt, report_where = unpack(reportTable)
|
||||
local instance = Details:GetInstance(id)
|
||||
Details.report_lines = amt
|
||||
Details.report_where = report_where
|
||||
|
||||
local cattribute, csubattribute = instance:GetDisplay()
|
||||
instance:SetDisplay(nil, attribute, subattribute)
|
||||
|
||||
instance:monta_relatorio()
|
||||
instance:SetDisplay(nil, cattribute, csubattribute)
|
||||
GameCooltip:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function Details:SendReportLines(lines)
|
||||
if (type(lines) == "string") then
|
||||
lines = {lines}
|
||||
end
|
||||
return Details:envia_relatorio(lines, true)
|
||||
end
|
||||
|
||||
function Details:SendReportWindow(func, current, inverse, slider)
|
||||
if (type(func) ~= "function") then
|
||||
return
|
||||
end
|
||||
|
||||
if (not Details.janela_report) then
|
||||
Details.janela_report = gump:CriaJanelaReport()
|
||||
end
|
||||
|
||||
if (current) then
|
||||
_G["Details_Report_CB_1"]:Enable()
|
||||
_G["Details_Report_CB_1Text"]:SetTextColor(1, 1, 1, 1)
|
||||
else
|
||||
_G["Details_Report_CB_1"]:Disable()
|
||||
_G["Details_Report_CB_1Text"]:SetTextColor(.5, .5, .5, 1)
|
||||
end
|
||||
|
||||
if (inverse) then
|
||||
_G["Details_Report_CB_2"]:Enable()
|
||||
_G["Details_Report_CB_2Text"]:SetTextColor(1, 1, 1, 1)
|
||||
else
|
||||
_G["Details_Report_CB_2"]:Disable()
|
||||
_G["Details_Report_CB_2Text"]:SetTextColor(.5, .5, .5, 1)
|
||||
end
|
||||
|
||||
if (slider) then
|
||||
Details.janela_report.slider:Enable()
|
||||
Details.janela_report.slider.lockTexture:Hide()
|
||||
Details.janela_report.slider.amt:Show()
|
||||
else
|
||||
Details.janela_report.slider:Disable()
|
||||
Details.janela_report.slider.lockTexture:Show()
|
||||
Details.janela_report.slider.amt:Hide()
|
||||
end
|
||||
|
||||
if (Details.janela_report.ativa) then
|
||||
Details.janela_report:Flash(0.2, 0.2, 0.4, true, 0, 0, "NONE")
|
||||
end
|
||||
|
||||
Details.janela_report.ativa = true
|
||||
Details.janela_report.enviar:SetScript("OnClick", function() func(_G["Details_Report_CB_1"]:GetChecked(), _G["Details_Report_CB_2"]:GetChecked(), Details.report_lines) end)
|
||||
|
||||
Details.FadeHandler.Fader(Details.janela_report, 0)
|
||||
return true
|
||||
end
|
||||
|
||||
function Details:SendReportTextWindow(lines)
|
||||
if (not Details.copypasteframe) then
|
||||
Details.copypasteframe = CreateFrame("frame", "DetailsCopyPasteFrame2", UIParent, "BackdropTemplate")
|
||||
Details.copypasteframe:SetFrameStrata("TOOLTIP")
|
||||
Details.copypasteframe:SetPoint("CENTER", UIParent, "CENTER", 0, 50)
|
||||
table.insert(UISpecialFrames, "DetailsCopyPasteFrame2")
|
||||
Details.copypasteframe:SetSize(400, 400)
|
||||
Details.copypasteframe:Hide()
|
||||
|
||||
DetailsFramework:ApplyStandardBackdrop(Details.copypasteframe)
|
||||
DetailsFramework:CreateTitleBar(Details.copypasteframe, "Export Text")
|
||||
|
||||
local editBox = CreateFrame("editbox", nil, Details.copypasteframe)
|
||||
editBox:SetPoint("topleft", Details.copypasteframe, "topleft", 2, -26)
|
||||
editBox:SetPoint("bottomright", Details.copypasteframe, "bottomright", -2, 2)
|
||||
editBox:SetAutoFocus(false)
|
||||
editBox:SetMultiLine(true)
|
||||
editBox:SetFontObject("GameFontHighlightSmall")
|
||||
|
||||
editBox:SetScript("OnEditFocusGained", function() editBox:HighlightText() end)
|
||||
editBox:SetScript("OnEditFocusLost", function() Details.copypasteframe:Hide() end)
|
||||
editBox:SetScript("OnEscapePressed", function() editBox:SetFocus(false); Details.copypasteframe:Hide() end)
|
||||
editBox:SetScript("OnChar", function() editBox:SetFocus(false); Details.copypasteframe:Hide() end)
|
||||
|
||||
Details.copypasteframe.EditBox = editBox
|
||||
end
|
||||
|
||||
local reportString = ""
|
||||
for _, line in ipairs(lines) do
|
||||
reportString = reportString .. line .. "\n"
|
||||
end
|
||||
|
||||
Details.copypasteframe:Show()
|
||||
Details.copypasteframe.EditBox:SetText(reportString)
|
||||
Details.copypasteframe.EditBox:HighlightText()
|
||||
Details.copypasteframe.EditBox:SetFocus(true)
|
||||
end
|
||||
|
||||
--internal details report functions -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function Details:Reportar(param2, options, arg3, id)
|
||||
GameCooltip2:Hide()
|
||||
|
||||
if (not Details.janela_report) then
|
||||
Details.janela_report = gump:CriaJanelaReport()
|
||||
end
|
||||
|
||||
if (options and options.meu_id) then
|
||||
self = options
|
||||
end
|
||||
|
||||
if (type(param2) == "string") then
|
||||
id = param2
|
||||
end
|
||||
|
||||
if (Details.last_report_id and id and Details.last_report_id == id) then
|
||||
Details.last_report_id = nil
|
||||
Details.janela_report.fechar:Click()
|
||||
return
|
||||
end
|
||||
|
||||
Details.last_report_id = id
|
||||
|
||||
if (options and options._no_current) then
|
||||
_G["Details_Report_CB_1"]:Disable()
|
||||
_G["Details_Report_CB_1Text"]:SetTextColor(.5, .5, .5, 1)
|
||||
|
||||
else
|
||||
_G["Details_Report_CB_1"]:Enable()
|
||||
_G["Details_Report_CB_1Text"]:SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
if (options and options._no_inverse) then
|
||||
_G["Details_Report_CB_2"]:Disable()
|
||||
_G["Details_Report_CB_2Text"]:SetTextColor(.5, .5, .5, 1)
|
||||
else
|
||||
_G["Details_Report_CB_2"]:Enable()
|
||||
_G["Details_Report_CB_2Text"]:SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
Details.janela_report.slider:Enable()
|
||||
Details.janela_report.slider.lockTexture:Hide()
|
||||
Details.janela_report.slider.amt:Show()
|
||||
|
||||
if (options) then
|
||||
local bIsCustom = true
|
||||
Details.janela_report.enviar:SetScript("OnClick", function() self:monta_relatorio(param2, bIsCustom) end)
|
||||
else
|
||||
Details.janela_report.enviar:SetScript("OnClick", function() self:monta_relatorio(param2) end)
|
||||
end
|
||||
|
||||
if (Details.janela_report.ativa) then
|
||||
Details.janela_report:Flash(0.2, 0.2, 0.4, true, 0, 0, "NONE")
|
||||
end
|
||||
|
||||
Details.janela_report.ativa = true
|
||||
Details.FadeHandler.Fader(Details.janela_report, 0)
|
||||
end
|
||||
|
||||
--build report frame gump -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--script
|
||||
local savepos = function(self)
|
||||
local xofs, yofs = self:GetCenter()
|
||||
local scale = self:GetEffectiveScale()
|
||||
local UIscale = UIParent:GetScale()
|
||||
xofs = xofs * scale - GetScreenWidth() * UIscale / 2
|
||||
yofs = yofs * scale - GetScreenHeight() * UIscale / 2
|
||||
local x = xofs / UIscale
|
||||
local y = yofs / UIscale
|
||||
Details.report_pos[1] = x
|
||||
Details.report_pos[2] = y
|
||||
end
|
||||
|
||||
local restorepos = function(self)
|
||||
local x, y = Details.report_pos[1], Details.report_pos[2]
|
||||
local scale = self:GetEffectiveScale()
|
||||
local UIscale = UIParent:GetScale()
|
||||
x = x * UIscale / scale
|
||||
y = y * UIscale / scale
|
||||
self:ClearAllPoints()
|
||||
self:SetPoint("center", UIParent, "center", x, y)
|
||||
end
|
||||
|
||||
local function setScripts(este_gump)
|
||||
--Janela
|
||||
este_gump:SetScript("OnMouseDown", function(self, botao)
|
||||
if (botao == "LeftButton") then
|
||||
self:StartMoving()
|
||||
self.isMoving = true
|
||||
|
||||
elseif (botao == "RightButton") then
|
||||
if (self.isMoving) then
|
||||
self:StopMovingOrSizing()
|
||||
savepos(self)
|
||||
self.isMoving = false
|
||||
end
|
||||
self:Hide()
|
||||
end
|
||||
end)
|
||||
|
||||
este_gump:SetScript("OnMouseUp", function(self)
|
||||
if (self.isMoving) then
|
||||
self:StopMovingOrSizing()
|
||||
savepos (self)
|
||||
self.isMoving = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local iconsAndColors = {
|
||||
["PARTY"] = {icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.53125, 0.7265625, 0.078125, 0.40625}, color = {0.66, 0.65, 1}},
|
||||
["RAID"] = {icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.53125, 0.7265625, 0.078125, 0.40625}, color = {1, 0.49, 0}},
|
||||
["GUILD"] = {icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.8046875, 0.96875, 0.125, 0.390625}, color = {0.25, 0.98, 0.25}},
|
||||
["OFFICER"] = {label = Loc ["STRING_REPORTFRAME_OFFICERS"], icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.8046875, 0.96875, 0.125, 0.390625}, color = {0.25, 0.74, 0.25}},
|
||||
["WHISPER"] = {icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.0546875, 0.1953125, 0.625, 0.890625}, color = {1, 0.49, 1}},
|
||||
["SAY"] = {icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.0390625, 0.203125, 0.09375, 0.375}, color = {1, 1, 1}},
|
||||
["COPY"] = {icon = [[Interface\Buttons\UI-GuildButton-PublicNote-Disabled]], coords = {0, 1, 0, 1}, color = {1, 1, 1}},
|
||||
}
|
||||
|
||||
function Details.GetReportIconAndColor(reportWhere)
|
||||
local key = reportWhere:gsub((".*|"), "")
|
||||
return iconsAndColors[key]
|
||||
end
|
||||
|
||||
local createDropdown = function(thisFrame)
|
||||
local iconsize = {16, 16}
|
||||
|
||||
local baseChannels = {
|
||||
{Loc ["STRING_REPORTFRAME_PARTY"], "PARTY", function() return GetNumSubgroupMembers() > 0 end, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.53125, 0.7265625, 0.078125, 0.40625}, color = {0.66, 0.65, 1}}},
|
||||
{Loc ["STRING_REPORTFRAME_RAID"], "RAID", IsInRaid, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.53125, 0.7265625, 0.078125, 0.40625}, color = {1, 0.49, 0}}},
|
||||
{Loc ["STRING_REPORTFRAME_GUILD"], "GUILD", IsInGuild, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.8046875, 0.96875, 0.125, 0.390625}, color = {0.25, 0.98, 0.25}}},
|
||||
{Loc ["STRING_REPORTFRAME_OFFICERS"], "OFFICER", IsInGuild, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.8046875, 0.96875, 0.125, 0.390625}, color = {0.25, 0.74, 0.25}}},
|
||||
{Loc ["STRING_REPORTFRAME_WHISPER"], "WHISPER", nil, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.0546875, 0.1953125, 0.625, 0.890625}, color = {1, 0.49, 1}}},
|
||||
{Loc ["STRING_REPORTFRAME_WHISPERTARGET"], "WHISPER2", nil, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.0546875, 0.1953125, 0.625, 0.890625}, color = {1, 0.49, 1}}},
|
||||
{Loc ["STRING_REPORTFRAME_SAY"], "SAY", IsInInstance, {iconsize = iconsize, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], coords = {0.0390625, 0.203125, 0.09375, 0.375}, color = {1, 1, 1}}},
|
||||
{Loc ["STRING_REPORTFRAME_COPY"], "COPY", nil, {iconsize = iconsize, icon = [[Interface\Buttons\UI-GuildButton-PublicNote-Disabled]], coords = {0, 1, 0, 1}, color = {1, 1, 1}}},
|
||||
}
|
||||
local onClick = function(self, fixedParam, selectedOutput)
|
||||
Details.report_where = selectedOutput
|
||||
end
|
||||
|
||||
local buildList = function()
|
||||
local reportChannelsTable = {}
|
||||
|
||||
for index, channelInfo in ipairs(baseChannels) do
|
||||
if (not channelInfo[3] or channelInfo[3]()) then
|
||||
reportChannelsTable[#reportChannelsTable + 1] = {iconsize = channelInfo[4].iconsize, value = channelInfo[2], label = channelInfo[1], onclick = onClick, icon = channelInfo[4].icon, texcoord = channelInfo[4].coords, iconcolor = channelInfo[4].color}
|
||||
end
|
||||
end
|
||||
|
||||
local channels = {GetChannelList()} --coloca o resultado em uma tabela .. {id1, canal1, id2, canal2}
|
||||
--09/august/2018: GetChannelList passed to return 3 values for each channel instead of 2
|
||||
|
||||
for i = 1, #channels, 2 do --total de canais
|
||||
reportChannelsTable[#reportChannelsTable + 1] = {iconsize = iconsize, value = "CHANNEL|" .. channels[i+1], label = channels[i] .. ". " .. channels[i+1], onclick = onClick, icon = [[Interface\FriendsFrame\UI-Toast-ToastIcons]], texcoord = {0.3046875, 0.4453125, 0.109375, 0.390625}, iconcolor = {149/255, 112/255, 112/255}}
|
||||
end
|
||||
|
||||
return reportChannelsTable
|
||||
end
|
||||
|
||||
thisFrame.dropdown_func = buildList
|
||||
|
||||
local selectOutputChannel = gump:NewDropDown(thisFrame, _, "$parentOutputDropdown", "select", 185, 20, buildList, 1)
|
||||
selectOutputChannel:SetPoint("topleft", thisFrame, "topleft", 107, -55)
|
||||
thisFrame.select = selectOutputChannel.widget
|
||||
thisFrame.dropdown = selectOutputChannel
|
||||
|
||||
function selectOutputChannel:CheckValid()
|
||||
local lastSelected = Details.report_where
|
||||
local checkFunc
|
||||
|
||||
for i, channelTable in ipairs(baseChannels) do
|
||||
if (channelTable[2] == lastSelected) then
|
||||
checkFunc = channelTable[3]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (checkFunc) then
|
||||
local isShown = checkFunc()
|
||||
if (isShown) then
|
||||
selectOutputChannel:Select(lastSelected)
|
||||
else
|
||||
if (IsInRaid()) then
|
||||
selectOutputChannel:Select("RAID")
|
||||
|
||||
elseif (GetNumSubgroupMembers() > 0) then
|
||||
selectOutputChannel:Select("PARTY")
|
||||
|
||||
elseif (IsInGuild()) then
|
||||
selectOutputChannel:Select("GUILD")
|
||||
|
||||
else
|
||||
selectOutputChannel:Select("SAY")
|
||||
end
|
||||
end
|
||||
else
|
||||
selectOutputChannel:Select(lastSelected)
|
||||
end
|
||||
end
|
||||
selectOutputChannel:CheckValid()
|
||||
end
|
||||
|
||||
--slider
|
||||
local createSlider = function(thisFrame)
|
||||
thisFrame.linhas_amt = thisFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
thisFrame.linhas_amt:SetText(Loc ["STRING_REPORTFRAME_LINES"])
|
||||
thisFrame.linhas_amt:SetTextColor(.9, .9, .9, 1)
|
||||
thisFrame.linhas_amt:SetPoint("bottomleft", thisFrame, "bottomleft", 58, 12)
|
||||
Details:SetFontSize(thisFrame.linhas_amt, 10)
|
||||
|
||||
local slider = CreateFrame("Slider", "Details_Report_Slider", thisFrame, "BackdropTemplate")
|
||||
thisFrame.slider = slider
|
||||
slider:SetPoint("bottomleft", thisFrame, "bottomleft", 58, -7)
|
||||
|
||||
slider.thumb = slider:CreateTexture(nil, "artwork")
|
||||
slider.thumb:SetTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
|
||||
slider.thumb:SetSize(30, 24)
|
||||
slider.thumb:SetAlpha(0.7)
|
||||
|
||||
local lockTexture = slider:CreateTexture(nil, "overlay")
|
||||
lockTexture:SetPoint("center", slider.thumb, "center", -1, -1)
|
||||
lockTexture:SetTexture("Interface\\Buttons\\CancelButton-Up")
|
||||
lockTexture:SetWidth(29)
|
||||
lockTexture:SetHeight(24)
|
||||
lockTexture:Hide()
|
||||
slider.lockTexture = lockTexture
|
||||
|
||||
slider:SetThumbTexture(slider.thumb)
|
||||
slider:SetOrientation("HORIZONTAL")
|
||||
slider:SetMinMaxValues(1.0, 25.0)
|
||||
slider:SetValueStep(1.0)
|
||||
slider:SetWidth(232)
|
||||
slider:SetHeight(20)
|
||||
|
||||
local lastValue = Details.report_lines or 5
|
||||
slider:SetValue(floor(lastValue))
|
||||
|
||||
slider.amt = slider:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
|
||||
local amt = slider:GetValue()
|
||||
if (amt < 10) then
|
||||
amt = "0" .. amt
|
||||
end
|
||||
|
||||
slider.amt:SetText(amt)
|
||||
slider.amt:SetTextColor(.8, .8, .8, 1)
|
||||
slider.amt:SetPoint("center", slider.thumb, "center")
|
||||
|
||||
slider:SetScript("OnValueChanged", function(self)
|
||||
local amt = math.floor(self:GetValue())
|
||||
Details.report_lines = amt
|
||||
if (amt < 10) then
|
||||
amt = "0" .. amt
|
||||
end
|
||||
self.amt:SetText(amt)
|
||||
end)
|
||||
|
||||
slider:SetScript("OnEnter", function(self)
|
||||
slider.thumb:SetAlpha(1)
|
||||
end)
|
||||
|
||||
slider:SetScript("OnLeave", function(self)
|
||||
slider.thumb:SetAlpha(0.7)
|
||||
end)
|
||||
end
|
||||
|
||||
--whisper taget field
|
||||
local createWisperField = function(thisFrame)
|
||||
thisFrame.wisp_who = thisFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
thisFrame.wisp_who:SetText(Loc ["STRING_REPORTFRAME_WHISPER"] .. ":")
|
||||
thisFrame.wisp_who:SetTextColor(1, 1, 1, 1)
|
||||
thisFrame.wisp_who:SetPoint("topleft", thisFrame.select, "topleft", 14, -30)
|
||||
|
||||
Details:SetFontSize(thisFrame.wisp_who, 10)
|
||||
|
||||
--editbox
|
||||
local editbox = CreateFrame("EditBox", nil, thisFrame, "BackdropTemplate")
|
||||
thisFrame.editbox = editbox
|
||||
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetFontObject("GameFontHighlightSmall")
|
||||
|
||||
editbox:SetPoint("TOPLEFT", thisFrame.select, "TOPLEFT", 64, -28)
|
||||
|
||||
editbox:SetHeight(14)
|
||||
editbox:SetWidth(120)
|
||||
editbox:SetJustifyH("center")
|
||||
editbox:EnableMouse(true)
|
||||
editbox:SetBackdrop({
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
tile = true, edgeSize = 1, tileSize = 5,
|
||||
})
|
||||
editbox:SetBackdropColor(0, 0, 0, 0.0)
|
||||
editbox:SetBackdropBorderColor(0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
local lastValue = Details.report_to_who or ""
|
||||
editbox:SetText(lastValue)
|
||||
editbox.perdeu_foco = nil
|
||||
editbox.focus = false
|
||||
|
||||
editbox:SetScript("OnEnterPressed", function()
|
||||
local texto = Details:trim(editbox:GetText())
|
||||
if (string.len(texto) > 0) then
|
||||
Details.report_to_who = texto
|
||||
editbox:AddHistoryLine(texto)
|
||||
editbox:SetText(texto)
|
||||
else
|
||||
Details.report_to_who = ""
|
||||
editbox:SetText("")
|
||||
end
|
||||
|
||||
editbox.perdeu_foco = true --isso aqui pra quando estiver editando e clicar em outra caixa
|
||||
editbox:ClearFocus()
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEscapePressed", function()
|
||||
editbox:SetText("")
|
||||
Details.report_to_who = ""
|
||||
editbox.perdeu_foco = true
|
||||
editbox:ClearFocus()
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEnter", function()
|
||||
editbox.mouse_over = true
|
||||
if (editbox:GetText() == "" and not editbox.focus) then
|
||||
editbox:SetText(Loc ["STRING_REPORTFRAME_INSERTNAME"])
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnLeave", function()
|
||||
editbox.mouse_over = false
|
||||
if (not editbox:HasFocus()) then
|
||||
if (editbox:GetText() == Loc ["STRING_REPORTFRAME_INSERTNAME"]) then
|
||||
editbox:SetText("")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEditFocusGained", function()
|
||||
if (editbox:GetText() == Loc ["STRING_REPORTFRAME_INSERTNAME"]) then
|
||||
editbox:SetText("")
|
||||
end
|
||||
|
||||
if (editbox:GetText() ~= "") then
|
||||
editbox:HighlightText(0, editbox:GetNumLetters())
|
||||
end
|
||||
|
||||
editbox.focus = true
|
||||
end)
|
||||
|
||||
editbox:SetScript("OnEditFocusLost", function()
|
||||
if (editbox.perdeu_foco == nil) then
|
||||
local text = Details:trim(editbox:GetText())
|
||||
|
||||
if (string.len(text) > 0) then
|
||||
Details.report_to_who = text
|
||||
else
|
||||
Details.report_to_who = ""
|
||||
editbox:SetText("")
|
||||
end
|
||||
else
|
||||
editbox.perdeu_foco = nil
|
||||
end
|
||||
|
||||
editbox.focus = false
|
||||
end)
|
||||
end
|
||||
|
||||
--both check buttons
|
||||
local createCheckButtons = function(thisFrame)
|
||||
local checkbox = CreateFrame("CheckButton", "Details_Report_CB_1", thisFrame, "ChatConfigCheckButtonTemplate,BackdropTemplate")
|
||||
checkbox:SetPoint("topleft", thisFrame.wisp_who, "bottomleft", -25, -4)
|
||||
_G[checkbox:GetName().."Text"]:SetText(Loc ["STRING_REPORTFRAME_CURRENT"])
|
||||
Details:SetFontSize(_G[checkbox:GetName().."Text"], 10)
|
||||
checkbox.tooltip = Loc ["STRING_REPORTFRAME_CURRENTINFO"]
|
||||
checkbox:SetHitRectInsets(0, -35, 0, 0)
|
||||
|
||||
local checkbox2 = CreateFrame("CheckButton", "Details_Report_CB_2", thisFrame, "ChatConfigCheckButtonTemplate,BackdropTemplate")
|
||||
checkbox2:SetPoint("topleft", thisFrame.wisp_who, "bottomleft", 35, -4)
|
||||
_G[checkbox2:GetName().."Text"]:SetText(Loc ["STRING_REPORTFRAME_REVERT"])
|
||||
Details:SetFontSize(_G[checkbox2:GetName().."Text"], 10)
|
||||
checkbox2.tooltip = Loc ["STRING_REPORTFRAME_REVERTINFO"]
|
||||
checkbox2:SetHitRectInsets(0, -35, 0, 0)
|
||||
end
|
||||
|
||||
--frame creation function
|
||||
local defaultSkin = function()
|
||||
local window = DetailsReportWindow
|
||||
local anchorX = 10
|
||||
|
||||
local recentReportButtonOnEnter = function(self)
|
||||
self:SetBackdropColor(0.4, 0.4, 0.4, 0.6)
|
||||
self.icon:SetBlendMode("ADD")
|
||||
Details:SetFontColor(self.text, "yellow")
|
||||
end
|
||||
|
||||
local recentReportButtonOnLeave = function(self)
|
||||
self:SetBackdropColor(0, 0, 0, 0.3)
|
||||
self.icon:SetBlendMode("BLEND")
|
||||
Details:SetFontColor(self.text, "white")
|
||||
end
|
||||
|
||||
window.last_reported_label:SetPoint("topleft", window, "topleft", 5, -28)
|
||||
gump:SetFontSize(window.last_reported_label, 10)
|
||||
|
||||
for i = 1, 9 do --window.max_last_buttons
|
||||
local recentReportButton = window.recently_report_buttons[i]
|
||||
|
||||
recentReportButton:SetSize(150, 16)
|
||||
recentReportButton:SetPoint("topleft", window, "topleft", 5, -28 + (i * 17 * -1))
|
||||
recentReportButton:Show()
|
||||
recentReportButton:SetBackdrop({bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16,
|
||||
insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
recentReportButton:SetBackdropColor(0, 0, 0, 0.3)
|
||||
recentReportButton.text:SetTextColor(1, 1, 1, 1)
|
||||
Details:SetFontSize(recentReportButton.text, 9)
|
||||
|
||||
recentReportButton:SetScript("OnEnter", recentReportButtonOnEnter)
|
||||
recentReportButton:SetScript("OnLeave", recentReportButtonOnLeave)
|
||||
end
|
||||
|
||||
window.fechar:SetWidth(20)
|
||||
window.fechar:SetHeight(20)
|
||||
window.fechar:SetPoint("TOPRIGHT", window, "TOPRIGHT", 0, -3)
|
||||
window.fechar:Show()
|
||||
window.fechar:GetNormalTexture():SetDesaturated(true)
|
||||
|
||||
local recentReportButton = window.recently_report_buttons[10]
|
||||
recentReportButton:Hide()
|
||||
|
||||
window.dropdown:ClearAllPoints()
|
||||
window.dropdown:SetWidth(155)
|
||||
window.dropdown:SetPoint("topleft", window, "topleft", anchorX, -30)
|
||||
window.dropdown:SetBackdrop({bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, tile=true,
|
||||
tileSize = 64, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
window.dropdown:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
window.dropdown:SetBackdropColor(0, 0, 0, 0.1)
|
||||
|
||||
window.wisp_who:ClearAllPoints()
|
||||
window.editbox:ClearAllPoints()
|
||||
window.wisp_who:SetPoint("topleft", window.dropdown.widget, "bottomleft", 0, -10)
|
||||
window.editbox:SetPoint("topleft", window.wisp_who, "bottomleft", 0, -3)
|
||||
window.editbox:SetWidth(155)
|
||||
window.editbox:SetHeight(20)
|
||||
window.editbox:SetBackdrop({bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, tile=true,
|
||||
tileSize = 64, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
window.editbox:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
window.editbox:SetBackdropColor(0, 0, 0, 0.3)
|
||||
|
||||
window.linhas_amt:ClearAllPoints()
|
||||
window.linhas_amt:SetPoint("topleft", window.editbox, "bottomleft", 0, -10)
|
||||
window.slider:ClearAllPoints()
|
||||
window.slider:SetWidth(155)
|
||||
window.slider:SetPoint("topleft", window.linhas_amt, "bottomleft", 0, -3)
|
||||
window.slider:SetBackdrop({bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, tile=true,
|
||||
tileSize = 64, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
window.slider:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
window.slider:SetBackdropColor(0, 0, 0, 0.3)
|
||||
|
||||
window.slider.thumb:SetTexture([[Interface\AddOns\Details\images\icons2]])
|
||||
window.slider.thumb:SetTexCoord(482/512, 492/512, 104/512, 120/512)
|
||||
window.slider.thumb:SetSize(16, 16)
|
||||
window.slider.thumb:SetVertexColor(0.6, 0.6, 0.6, 0.95)
|
||||
|
||||
Details_Report_CB_1:Hide()
|
||||
local reverse_checkbox = Details_Report_CB_2
|
||||
reverse_checkbox:Show()
|
||||
reverse_checkbox:ClearAllPoints()
|
||||
reverse_checkbox:SetBackdrop({bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, tile=true,
|
||||
tileSize = 64, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
reverse_checkbox:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
reverse_checkbox:SetBackdropColor(0, 0, 0, 0.3)
|
||||
reverse_checkbox:SetPoint("topleft", window.slider, "bottomleft", 0, -8)
|
||||
reverse_checkbox:SetSize(14, 14)
|
||||
reverse_checkbox:SetNormalTexture("")
|
||||
reverse_checkbox:SetPushedTexture("")
|
||||
reverse_checkbox:SetHighlightTexture("")
|
||||
_G[reverse_checkbox:GetName().."Text"]:ClearAllPoints()
|
||||
_G[reverse_checkbox:GetName().."Text"]:SetPoint("left", reverse_checkbox, "right", 2, 0)
|
||||
|
||||
window.enviar:ClearAllPoints()
|
||||
window.enviar:SetPoint("bottom", window, "bottom", 0, 10)
|
||||
window.enviar:SetBackdrop({bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, tile=true,
|
||||
tileSize = 64, insets = {left = 0, right = 0, top = 0, bottom = 0}})
|
||||
window.enviar:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
window.enviar:SetBackdropColor(0, 0, 0, 0.3)
|
||||
window.enviar:SetSize(342/2 - 15, 20)
|
||||
|
||||
window:SetWidth(342/2 + 5)
|
||||
window:SetHeight(195)
|
||||
--window:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
--window:SetBackdropColor(1, 1, 1, 1)
|
||||
--window:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
if (not window.widgets) then
|
||||
window.widgets = {}
|
||||
|
||||
local titlebar = CreateFrame("frame", window:GetName() .. "TitleBar", window, "BackdropTemplate")
|
||||
titlebar:SetPoint("topleft", window, "topleft", 2, -3)
|
||||
titlebar:SetPoint("topright", window, "topright", -2, -3)
|
||||
titlebar:SetHeight(20)
|
||||
--titlebar:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
--titlebar:SetBackdropColor(.5, .5, .5, 1)
|
||||
--titlebar:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
table.insert(window.all_widgets, titlebar)
|
||||
table.insert(window.widgets, titlebar)
|
||||
end
|
||||
|
||||
window.title:ClearAllPoints()
|
||||
window.title:SetPoint("center", window, "center")
|
||||
window.title:SetPoint("top", window, "top", 0, -7)
|
||||
window.title:SetParent(_G[window:GetName() .. "TitleBar"])
|
||||
window.title:SetTextColor(.8, .8, .8, 1)
|
||||
window.title:Show()
|
||||
|
||||
window:SetClampedToScreen(true)
|
||||
|
||||
for _, widget in ipairs(window.widgets) do
|
||||
widget:Show()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function Details:UpdateRecentlyReported()
|
||||
DetailsReportWindow:RefreshRecentlyReported()
|
||||
end
|
||||
|
||||
function Details:DelayUpdateReportWindowRecentlyReported()
|
||||
if (DetailsReportWindow) then
|
||||
Details:ScheduleTimer("UpdateRecentlyReported", 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function Details:CheckLastReportsIntegrity()
|
||||
local lastReports = Details.latest_report_table or {}
|
||||
if (#lastReports > 0) then
|
||||
local i = 1
|
||||
for index = #lastReports, 1, -1 do
|
||||
local report = lastReports[index]
|
||||
local instance_id, atributo, sub_atributo, amt, where, custom_name = unpack(report)
|
||||
if (atributo == 5) then
|
||||
if (not custom_name) then
|
||||
tremove(lastReports, index)
|
||||
else
|
||||
local found
|
||||
for _, custom in ipairs(Details.custom) do
|
||||
if (custom.name == custom_name) then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if (not found) then
|
||||
tremove(lastReports, index)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gump:CriaJanelaReport()
|
||||
--window
|
||||
local window = CreateFrame("Frame", "DetailsReportWindow", UIParent, "BackdropTemplate")
|
||||
table.insert(UISpecialFrames, "DetailsReportWindow")
|
||||
window:SetPoint("CENTER", UIParent, "CENTER")
|
||||
window:SetFrameStrata("DIALOG")
|
||||
window.skins = {}
|
||||
window.all_widgets = {}
|
||||
window.max_last_buttons = 10
|
||||
|
||||
window:EnableMouse(true)
|
||||
window:SetResizable(false)
|
||||
window:SetMovable(true)
|
||||
restorepos(window)
|
||||
|
||||
Details.janela_report = window
|
||||
Details:InstallRPSkin("defaultSkin", defaultSkin)
|
||||
|
||||
DetailsFramework:AddRoundedCornersToFrame(window, Details.PlayerBreakdown.RoundedCornerPreset)
|
||||
|
||||
--recently reported:
|
||||
window.recently_report_buttons = {}
|
||||
|
||||
local historyBlockBackground = window:CreateTexture(nil, "background")
|
||||
historyBlockBackground:SetTexture(0, 0, 0, .3)
|
||||
historyBlockBackground:SetSize(160, 158)
|
||||
historyBlockBackground:SetPoint("topleft", window, "topleft", 3, -25)
|
||||
|
||||
local separator = window:CreateTexture(nil, "border")
|
||||
separator:SetTexture(0, 0, 0, .6)
|
||||
separator:SetSize(2, 158)
|
||||
separator:SetPoint("topleft", historyBlockBackground, "topright", 0, 0)
|
||||
|
||||
function window:RefreshRecentlyReported()
|
||||
for i = 1, window.max_last_buttons do
|
||||
local b = window.recently_report_buttons[i]
|
||||
b.icon:SetTexture("")
|
||||
b:Hide()
|
||||
end
|
||||
|
||||
Details:CheckLastReportsIntegrity()
|
||||
|
||||
local lastReports = Details.latest_report_table
|
||||
if (#lastReports > 0) then
|
||||
local i = 1
|
||||
for index = 1, min(#lastReports, 8) do
|
||||
local recentReportButton = window.recently_report_buttons[i]
|
||||
local report = lastReports[index]
|
||||
local instanceId, attribute, subAttribute, amt, reportWhere = unpack(report)
|
||||
local name = Details:GetSubAttributeName(attribute, subAttribute)
|
||||
local artwork = Details.GetReportIconAndColor(reportWhere)
|
||||
|
||||
recentReportButton.text:SetText(name .. " (#" .. amt .. ")")
|
||||
recentReportButton.index = index
|
||||
|
||||
if (artwork) then
|
||||
recentReportButton.icon:SetTexture(artwork.icon)
|
||||
recentReportButton.icon:SetTexCoord(artwork.coords[1], artwork.coords[2], artwork.coords[3], artwork.coords[4])
|
||||
recentReportButton.icon:SetVertexColor(unpack(artwork.color or {}))
|
||||
end
|
||||
|
||||
recentReportButton:Hide()
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local recentlyButtonOnClick = function(self)
|
||||
if (self.index) then
|
||||
return Details.ReportFromLatest(_, _, self.index)
|
||||
end
|
||||
end
|
||||
|
||||
local lastReportedLabel = window:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
window.last_reported_label = lastReportedLabel
|
||||
window.last_reported_label:SetText(Loc ["STRING_REPORTHISTORY"] .. ":") --this string could be removed from localization
|
||||
|
||||
for i = 1, window.max_last_buttons do
|
||||
local button = CreateFrame("button", "DetailsReportWindowRRB" .. i, window, "BackdropTemplate")
|
||||
local icon = button:CreateTexture(nil, "overlay")
|
||||
icon:SetPoint("left", button, "left")
|
||||
icon:SetSize(16, 16)
|
||||
|
||||
local text = button:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
text:SetPoint("left", icon, "right", 2, 0)
|
||||
|
||||
button.icon = icon
|
||||
button.text = text
|
||||
button:SetScript("OnClick", recentlyButtonOnClick)
|
||||
table.insert(window.recently_report_buttons, button)
|
||||
end
|
||||
|
||||
historyBlockBackground:Hide()
|
||||
separator:Hide()
|
||||
window.last_reported_label:Hide()
|
||||
|
||||
--scritps
|
||||
|
||||
local flashTexture = window:CreateTexture(nil, "background")
|
||||
flashTexture:SetTexture(1, 1, 1)
|
||||
flashTexture:SetPoint("topleft", window, "topleft", -2, 2)
|
||||
flashTexture:SetPoint("bottomright", window, "bottomright", 2, -2)
|
||||
|
||||
local onShowAnimation = DetailsFramework:CreateAnimationHub(flashTexture, function() flashTexture:Show() end, function() flashTexture:Hide() end)
|
||||
DetailsFramework:CreateAnimation(onShowAnimation, "ALPHA", 1, .4, 0, .90)
|
||||
DetailsFramework:CreateAnimation(onShowAnimation, "ALPHA", 2, .4, .90, 0)
|
||||
|
||||
window:SetScript("OnShow", function(self)
|
||||
local dropdown = window.select.MyObject
|
||||
local where = Details.report_where
|
||||
|
||||
local list = window.dropdown_func()
|
||||
local found
|
||||
|
||||
onShowAnimation:Play()
|
||||
|
||||
for index, option in ipairs(list) do
|
||||
if (option.value == where) then
|
||||
dropdown:Select(where)
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (not found) then
|
||||
if (IsInRaid()) then
|
||||
dropdown:Select("RAID")
|
||||
Details.report_where = "RAID"
|
||||
|
||||
elseif (GetNumSubgroupMembers() > 0) then
|
||||
dropdown:Select("PARTY")
|
||||
Details.report_where = "PARTY"
|
||||
|
||||
elseif (IsInGuild()) then
|
||||
dropdown:Select("GUILD")
|
||||
Details.report_where = "GUILD"
|
||||
|
||||
else
|
||||
dropdown:Select("SAY")
|
||||
Details.report_where = "SAY"
|
||||
end
|
||||
end
|
||||
|
||||
window:RefreshRecentlyReported()
|
||||
|
||||
window:SetColor(unpack(Details.frame_background_color))
|
||||
end)
|
||||
|
||||
window:SetScript("OnHide", function(self)
|
||||
Details.janela_report.ativa = false
|
||||
Details.last_report_id = nil
|
||||
end)
|
||||
|
||||
--close button
|
||||
window.fechar = CreateFrame("Button", nil, window, "UIPanelCloseButton")
|
||||
window.fechar:SetScript("OnClick", function()
|
||||
Details.FadeHandler.Fader(window, 1)
|
||||
Details.janela_report.ativa = false
|
||||
end)
|
||||
|
||||
--title
|
||||
window.title = window:CreateFontString(nil, "OVERLAY", "GameFontHighlightLeft")
|
||||
window.title:SetText(Loc ["STRING_REPORTFRAME_WINDOW_TITLE"])
|
||||
|
||||
setScripts(window)
|
||||
createDropdown(window)
|
||||
createSlider(window)
|
||||
createWisperField(window)
|
||||
createCheckButtons(window)
|
||||
|
||||
window.enviar = CreateFrame("Button", nil, window, "BackdropTemplate")
|
||||
window.enviar:SetPoint("topleft", window.editbox, "topleft", 61, -19)
|
||||
window.enviar:SetWidth(60)
|
||||
window.enviar:SetHeight(15)
|
||||
DetailsFramework:ApplyStandardBackdrop(window.enviar)
|
||||
|
||||
local sendButtonLabel = window.enviar:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
sendButtonLabel:SetPoint("center", 0, 0)
|
||||
sendButtonLabel:SetText(Loc ["STRING_REPORTFRAME_SEND"])
|
||||
|
||||
Details.FadeHandler.Fader(window, 1)
|
||||
gump:CreateFlashAnimation(window)
|
||||
|
||||
--apply the current skin
|
||||
Details:ApplyRPSkin()
|
||||
|
||||
return window
|
||||
end
|
||||
|
||||
function Details:InstallRPSkin(skinName, func)
|
||||
if (not DetailsReportWindow) then
|
||||
gump:CriaJanelaReport()
|
||||
DetailsReportWindow:Hide()
|
||||
end
|
||||
|
||||
if (not skinName) then
|
||||
return false
|
||||
elseif (DetailsReportWindow.skins[skinName]) then
|
||||
return false
|
||||
end
|
||||
|
||||
DetailsReportWindow.skins[skinName] = func
|
||||
return true
|
||||
end
|
||||
|
||||
function Details:ApplyRPSkin(skinName)
|
||||
if (not DetailsReportWindow) then
|
||||
gump:CriaJanelaReport()
|
||||
DetailsReportWindow:Hide()
|
||||
end
|
||||
|
||||
if (not skinName) then
|
||||
skinName = Details.player_details_window.skin
|
||||
if (not DetailsReportWindow.skins[skinName]) then
|
||||
skinName = "defaultSkin"
|
||||
end
|
||||
end
|
||||
|
||||
local skin = DetailsReportWindow.skins[skinName]
|
||||
if (skin) then
|
||||
for _, widget in ipairs(DetailsReportWindow.all_widgets) do
|
||||
widget:Hide()
|
||||
end
|
||||
|
||||
local successful, errortext = pcall(skin)
|
||||
if (not successful) then
|
||||
Details:Msg("error occurred on report window skin call():", errortext)
|
||||
pcall(DetailsReportWindow.skins["defaultSkin"])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,194 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
||||
|
||||
local windowWidth = 950
|
||||
local scrollWidth = 825
|
||||
|
||||
local panel = Details:CreateWelcomePanel("DetailsWindowOptionsBarTextEditor", nil, windowWidth, 600, true)
|
||||
panel:SetPoint("center", UIParent, "center")
|
||||
panel:Hide()
|
||||
panel:SetFrameStrata("FULLSCREEN")
|
||||
detailsFramework:ApplyStandardBackdrop(panel)
|
||||
detailsFramework:CreateTitleBar(panel, "Details! Custom Line Text Editor")
|
||||
|
||||
function panel:Open(text, callback, host, default)
|
||||
if (host) then
|
||||
panel:ClearAllPoints()
|
||||
panel:SetPoint("center", host, "center")
|
||||
end
|
||||
|
||||
text = text:gsub("||", "|")
|
||||
panel.default_text = text
|
||||
panel.editbox:SetText(text)
|
||||
panel.callback = callback
|
||||
panel.default = default or ""
|
||||
panel:Show()
|
||||
end
|
||||
|
||||
local y = -32
|
||||
local buttonTemplate = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
local codeEditor = detailsFramework:NewSpecialLuaEditorEntry(panel, scrollWidth, 555, "editbox", "$parentEntry")
|
||||
codeEditor:SetPoint("topleft", panel, "topleft", 10, y)
|
||||
detailsFramework:ApplyStandardBackdrop(codeEditor)
|
||||
detailsFramework:SetFontSize(codeEditor.editbox, 14)
|
||||
detailsFramework:ReskinSlider(codeEditor.scroll)
|
||||
|
||||
local arg1Button = detailsFramework:NewButton(panel, nil, "$parentButton1", nil, 80, 20, function() codeEditor.editbox:Insert("{data1}") end, nil, nil, nil, string.format(Loc ["STRING_OPTIONS_TEXTEDITOR_DATA"], "1"), 1)
|
||||
local arg2Button = detailsFramework:NewButton(panel, nil, "$parentButton2", nil, 80, 20, function() codeEditor.editbox:Insert("{data2}") end, nil, nil, nil, string.format(Loc ["STRING_OPTIONS_TEXTEDITOR_DATA"], "2"), 1)
|
||||
local arg3Button = detailsFramework:NewButton(panel, nil, "$parentButton3", nil, 80, 20, function() codeEditor.editbox:Insert("{data3}") end, nil, nil, nil, string.format(Loc ["STRING_OPTIONS_TEXTEDITOR_DATA"], "3"), 1)
|
||||
arg1Button:SetPoint("topright", panel, "topright", -12, y)
|
||||
arg2Button:SetPoint("topright", panel, "topright", -12, y -(20*1))
|
||||
arg3Button:SetPoint("topright", panel, "topright", -12, y -(20*2))
|
||||
arg1Button:SetTemplate(buttonTemplate)
|
||||
arg2Button:SetTemplate(buttonTemplate)
|
||||
arg3Button:SetTemplate(buttonTemplate)
|
||||
arg1Button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_DATA_TOOLTIP"]
|
||||
arg2Button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_DATA_TOOLTIP"]
|
||||
arg3Button.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_DATA_TOOLTIP"]
|
||||
|
||||
-- code author Saiket from http://www.wowinterface.com/forums/showpost.php?p=245759&postcount=6
|
||||
--- @return StartPos, EndPos of highlight in this editbox.
|
||||
local function GetTextHighlight( self )
|
||||
local Text, Cursor = self:GetText(), self:GetCursorPosition();
|
||||
self:Insert( "" ); -- Delete selected text
|
||||
local TextNew, CursorNew = self:GetText(), self:GetCursorPosition();
|
||||
-- Restore previous text
|
||||
self:SetText( Text );
|
||||
self:SetCursorPosition( Cursor );
|
||||
local Start, End = CursorNew, #Text -( #TextNew - CursorNew );
|
||||
self:HighlightText( Start, End );
|
||||
return Start, End;
|
||||
end
|
||||
|
||||
local StripColors;
|
||||
do
|
||||
local CursorPosition, CursorDelta;
|
||||
--- Callback for gsub to remove unescaped codes.
|
||||
local function StripCodeGsub( Escapes, Code, End )
|
||||
if ( #Escapes % 2 == 0 ) then -- Doesn't escape Code
|
||||
if ( CursorPosition and CursorPosition >= End - 1 ) then
|
||||
CursorDelta = CursorDelta - #Code;
|
||||
end
|
||||
return Escapes;
|
||||
end
|
||||
end
|
||||
--- Removes a single escape sequence.
|
||||
local function StripCode( Pattern, Text, OldCursor )
|
||||
CursorPosition, CursorDelta = OldCursor, 0;
|
||||
return Text:gsub( Pattern, StripCodeGsub ), OldCursor and CursorPosition + CursorDelta;
|
||||
end
|
||||
--- Strips Text of all color escape sequences.
|
||||
-- @param Cursor Optional cursor position to keep track of.
|
||||
-- @return Stripped text, and the updated cursor position if Cursor was given.
|
||||
function StripColors( Text, Cursor )
|
||||
Text, Cursor = StripCode( "(|*)(|c%x%x%x%x%x%x%x%x)()", Text, Cursor );
|
||||
return StripCode( "(|*)(|r)()", Text, Cursor );
|
||||
end
|
||||
end
|
||||
|
||||
local COLOR_END = "|r";
|
||||
--- Wraps this editbox's selected text with the given color.
|
||||
local function ColorSelection( self, ColorCode )
|
||||
local Start, End = GetTextHighlight( self );
|
||||
local Text, Cursor = self:GetText(), self:GetCursorPosition();
|
||||
if ( Start == End ) then -- Nothing selected
|
||||
--Start, End = Cursor, Cursor; -- Wrap around cursor
|
||||
return; -- Wrapping the cursor in a color code and hitting backspace crashes the client!
|
||||
end
|
||||
-- Find active color code at the end of the selection
|
||||
local ActiveColor;
|
||||
if ( End < #Text ) then -- There is text to color after the selection
|
||||
local ActiveEnd;
|
||||
local CodeEnd, _, Escapes, Color = 0;
|
||||
while( true ) do
|
||||
_, CodeEnd, Escapes, Color = Text:find( "(|*)(|c%x%x%x%x%x%x%x%x)", CodeEnd + 1 );
|
||||
if ( not CodeEnd or CodeEnd > End ) then
|
||||
break;
|
||||
end
|
||||
if ( #Escapes % 2 == 0 ) then -- Doesn't escape Code
|
||||
ActiveColor, ActiveEnd = Color, CodeEnd;
|
||||
end
|
||||
end
|
||||
|
||||
if ( ActiveColor ) then
|
||||
-- Check if color gets terminated before selection ends
|
||||
CodeEnd = 0;
|
||||
while( true ) do
|
||||
_, CodeEnd, Escapes = Text:find( "(|*)|r", CodeEnd + 1 );
|
||||
if ( not CodeEnd or CodeEnd > End ) then
|
||||
break;
|
||||
end
|
||||
if ( CodeEnd > ActiveEnd and #Escapes % 2 == 0 ) then -- Terminates ActiveColor
|
||||
ActiveColor = nil;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Selection = Text:sub( Start + 1, End );
|
||||
-- Remove color codes from the selection
|
||||
local Replacement, CursorReplacement = StripColors( Selection, Cursor - Start );
|
||||
|
||||
self:SetText(( "" ):join(
|
||||
Text:sub( 1, Start ),
|
||||
ColorCode, Replacement, COLOR_END,
|
||||
ActiveColor or "", Text:sub( End + 1 )
|
||||
) );
|
||||
|
||||
-- Restore cursor and highlight, adjusting for wrapper text
|
||||
Cursor = Start + CursorReplacement;
|
||||
if ( CursorReplacement > 0 ) then -- Cursor beyond start of color code
|
||||
Cursor = Cursor + #ColorCode;
|
||||
end
|
||||
if ( CursorReplacement >= #Replacement ) then -- Cursor beyond end of color
|
||||
Cursor = Cursor + #COLOR_END;
|
||||
end
|
||||
|
||||
self:SetCursorPosition( Cursor );
|
||||
-- Highlight selection and wrapper
|
||||
self:HighlightText( Start, #ColorCode + ( #Replacement - #Selection ) + #COLOR_END + End );
|
||||
end
|
||||
|
||||
local colorFunc = function(_, r, g, b, a)
|
||||
local hex = Details:hex(a * 255) .. Details:hex(r * 255) .. Details:hex(g * 255) .. Details:hex(b * 255)
|
||||
ColorSelection(codeEditor.editbox, "|c" .. hex)
|
||||
end
|
||||
|
||||
local funcButton = detailsFramework:NewButton(panel, nil, "$parentButton4", nil, 80, 20, function() codeEditor.editbox:Insert("{func local player, combat = ...; return 0;}") end, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_FUNC"], 1)
|
||||
local colorButton = detailsFramework:NewColorPickButton(panel, "$parentButton5", nil, colorFunc)
|
||||
colorButton:SetSize(80, 20)
|
||||
colorButton:SetTemplate(buttonTemplate)
|
||||
|
||||
funcButton:SetPoint("topright", panel, "topright", -12, y -(20*3))
|
||||
funcButton:SetTemplate(buttonTemplate)
|
||||
|
||||
colorButton.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_COLOR_TOOLTIP"]
|
||||
funcButton.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_FUNC_TOOLTIP"]
|
||||
local done = function()
|
||||
local text = panel.editbox:GetText()
|
||||
panel.callback(text)
|
||||
panel:Hide()
|
||||
end
|
||||
|
||||
local applyButton = detailsFramework:NewButton(panel, nil, "$parentApply", nil, 80, 20, function() panel.callback(panel.editbox:GetText()) end, nil, nil, nil, "Apply", 1) --localize-me
|
||||
applyButton:SetTemplate(buttonTemplate)
|
||||
applyButton:SetPoint("topright", panel, "topright", -14, -128)
|
||||
|
||||
local okButton = detailsFramework:NewButton(panel, nil, "$parentButtonOk", nil, 80, 20, done, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_DONE"], 1)
|
||||
okButton.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_DONE_TOOLTIP"]
|
||||
okButton:SetTemplate(buttonTemplate)
|
||||
okButton:SetPoint("topright", panel, "topright", -14, -194)
|
||||
|
||||
local resetButton = detailsFramework:NewButton(panel, nil, "$parentDefaultOk", nil, 80, 20, function() codeEditor.editbox:SetText(panel.default); panel.callback(panel.editbox:GetText()) end, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_RESET"], 1)
|
||||
resetButton.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_RESET_TOOLTIP"]
|
||||
resetButton:SetTemplate(buttonTemplate)
|
||||
resetButton:SetPoint("topright", panel, "topright", -14, -150)
|
||||
|
||||
local cancelButton = detailsFramework:NewButton(panel, nil, "$parentDefaultCancel", nil, 80, 20, function() codeEditor.editbox:SetText(panel.default_text); done(); end, nil, nil, nil, Loc ["STRING_OPTIONS_TEXTEDITOR_CANCEL"], 1)
|
||||
cancelButton.tooltip = Loc ["STRING_OPTIONS_TEXTEDITOR_CANCEL_TOOLTIP"]
|
||||
cancelButton:SetTemplate(buttonTemplate)
|
||||
cancelButton:SetPoint("topright", panel, "topright", -14, -172)
|
||||
@@ -0,0 +1,214 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local _
|
||||
local addonName, Details222 = ...
|
||||
local CreateFrame = CreateFrame
|
||||
local UIParent = UIParent
|
||||
local load = loadstring
|
||||
|
||||
function Details:InitializeRunCodeWindow()
|
||||
local detailsRunCodePanel = detailsFramework:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code Automation", "DetailsRunCodePanel")
|
||||
detailsRunCodePanel.Frame = detailsRunCodePanel
|
||||
detailsRunCodePanel.__name = "Auto Run Code"
|
||||
detailsRunCodePanel.real_name = "DETAILS_RUNCODEWINDOW"
|
||||
--DetailsRunCodePanel.__icon = [[Interface\AddOns\Details\images\lua_logo]]
|
||||
detailsRunCodePanel.__icon = [[Interface\AddOns\Details\images\run_code]]
|
||||
--DetailsRunCodePanel.__iconcoords = {0, 1, 0, 1}
|
||||
detailsRunCodePanel.__iconcoords = {0, 30/32, 0, 25/32}
|
||||
detailsRunCodePanel.__iconcoords = {0, 1, 0, 1}
|
||||
detailsRunCodePanel.__iconcolor = "white"
|
||||
DetailsPluginContainerWindow.EmbedPlugin(detailsRunCodePanel, detailsRunCodePanel, true)
|
||||
|
||||
function detailsRunCodePanel.RefreshWindow()
|
||||
Details222.AutoRunCode.OpenRunCodeWindow()
|
||||
end
|
||||
|
||||
detailsRunCodePanel:Hide()
|
||||
|
||||
Details222.AutoRunCode.DetailsRunCodePanel = detailsRunCodePanel
|
||||
end
|
||||
|
||||
function Details222.AutoRunCode.OpenRunCodeWindow()
|
||||
local detailsRunCodePanel = Details222.AutoRunCode.DetailsRunCodePanel
|
||||
|
||||
if (not detailsRunCodePanel or not detailsRunCodePanel.Initialized) then
|
||||
detailsRunCodePanel.Initialized = true
|
||||
|
||||
local autoRunCodeFrame = detailsRunCodePanel or detailsFramework:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code", "DetailsRunCodePanel")
|
||||
|
||||
--lua editor
|
||||
local codeEditor = detailsFramework:NewSpecialLuaEditorEntry(UIParent, 885, 510, nil, nil, false, true, true)
|
||||
codeEditor:SetPoint("topleft", autoRunCodeFrame, "topleft", 20, -56)
|
||||
codeEditor:SetFrameStrata(autoRunCodeFrame:GetFrameStrata())
|
||||
codeEditor:SetFrameLevel(autoRunCodeFrame:GetFrameLevel()+1)
|
||||
|
||||
function Details222.AutoRunCode.CodeEditorSetText(codeKey)
|
||||
local text = Details222.AutoRunCode.CodeTable[codeKey]
|
||||
return codeEditor:SetText(text)
|
||||
end
|
||||
|
||||
detailsRunCodePanel:HookScript("OnShow", function()
|
||||
codeEditor:Show()
|
||||
end)
|
||||
detailsRunCodePanel:SetScript("OnHide", function()
|
||||
codeEditor:Hide()
|
||||
_G.DetailsPluginContainerWindow:Hide()
|
||||
end)
|
||||
|
||||
--code editor appearance
|
||||
codeEditor.scroll:SetBackdrop(nil)
|
||||
codeEditor.editbox:SetBackdrop(nil)
|
||||
codeEditor:SetBackdrop(nil)
|
||||
|
||||
detailsFramework:ReskinSlider(codeEditor.scroll)
|
||||
|
||||
if (not codeEditor.__background) then
|
||||
codeEditor.__background = codeEditor:CreateTexture(nil, "background")
|
||||
end
|
||||
|
||||
codeEditor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
codeEditor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
codeEditor.__background:SetTexture(0.2317647, 0.2317647, 0.2317647)
|
||||
codeEditor.__background:SetVertexColor(0.27, 0.27, 0.27)
|
||||
codeEditor.__background:SetAlpha(0.8)
|
||||
codeEditor.__background:SetVertTile(true)
|
||||
codeEditor.__background:SetHorizTile(true)
|
||||
codeEditor.__background:SetAllPoints()
|
||||
|
||||
--code compile error warning
|
||||
local errortext_frame = CreateFrame("frame", nil, codeEditor, "BackdropTemplate")
|
||||
errortext_frame:SetPoint("bottomleft", codeEditor, "bottomleft", 1, 1)
|
||||
errortext_frame:SetPoint("bottomright", codeEditor, "bottomright", -1, 1)
|
||||
errortext_frame:SetHeight(20)
|
||||
errortext_frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
errortext_frame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
errortext_frame:SetBackdropColor(0, 0, 0)
|
||||
|
||||
detailsFramework:CreateFlashAnimation (errortext_frame)
|
||||
|
||||
local errortext_label = detailsFramework:CreateLabel(errortext_frame, "", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
errortext_label.textcolor = "red"
|
||||
errortext_label:SetPoint("left", errortext_frame, "left", 3, 0)
|
||||
codeEditor.NextCodeCheck = 0.33
|
||||
|
||||
codeEditor:HookScript ("OnUpdate", function(self, deltaTime)
|
||||
codeEditor.NextCodeCheck = codeEditor.NextCodeCheck - deltaTime
|
||||
|
||||
if (codeEditor.NextCodeCheck < 0) then
|
||||
local script = codeEditor:GetText()
|
||||
local func, errortext = load(script, "Q")
|
||||
if (not func) then
|
||||
local firstLine = strsplit("\n", script, 2)
|
||||
errortext = errortext:gsub(firstLine, "")
|
||||
errortext = errortext:gsub("%[string \"", "")
|
||||
errortext = errortext:gsub("...\"]:", "")
|
||||
errortext = errortext:gsub("Q\"]:", "")
|
||||
errortext = "Line " .. errortext
|
||||
errortext_label.text = errortext
|
||||
else
|
||||
errortext_label.text = ""
|
||||
end
|
||||
|
||||
codeEditor.NextCodeCheck = 0.33
|
||||
end
|
||||
end)
|
||||
|
||||
--script selector
|
||||
local on_select_CodeType_option = function(self, fixedParameter, value)
|
||||
--set the current editing code type
|
||||
autoRunCodeFrame.EditingCode = Details.RunCodeTypes[value].Value
|
||||
autoRunCodeFrame.EditingCodeKey = Details.RunCodeTypes[value].ProfileKey
|
||||
|
||||
--load the code for the event
|
||||
Details222.AutoRunCode.CodeEditorSetText(autoRunCodeFrame.EditingCodeKey)
|
||||
end
|
||||
|
||||
local build_CodeType_dropdown_options = function()
|
||||
local t = {}
|
||||
|
||||
for i = 1, #Details.RunCodeTypes do
|
||||
local option = Details.RunCodeTypes [i]
|
||||
t [#t + 1] = {label = option.Name, value = option.Value, onclick = on_select_CodeType_option, desc = option.Desc}
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
local code_type_label = detailsFramework:CreateLabel(autoRunCodeFrame, "Event:", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
local code_type_dropdown = detailsFramework:CreateDropDown(autoRunCodeFrame, build_CodeType_dropdown_options, 1, 160, 20, "CodeTypeDropdown", _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
code_type_dropdown:SetPoint("left", code_type_label, "right", 2, 0)
|
||||
code_type_dropdown:SetFrameLevel(codeEditor:GetFrameLevel() + 10)
|
||||
code_type_label:SetPoint("bottomleft", codeEditor, "topleft", 0, 8)
|
||||
|
||||
--create save button
|
||||
local save_script = function()
|
||||
local code = codeEditor:GetText()
|
||||
local func, errortext = load(code, "Q")
|
||||
|
||||
if (func) then
|
||||
Details222.AutoRunCode.CodeTable[autoRunCodeFrame.EditingCodeKey] = code
|
||||
Details222.AutoRunCode.RecompileAutoRunCode()
|
||||
Details:Msg("Code saved!")
|
||||
codeEditor:ClearFocus()
|
||||
else
|
||||
errortext_frame:Flash(0.2, 0.2, 0.4, true, nil, nil, "NONE")
|
||||
Details:Msg("Can't save the code: it has errors.")
|
||||
end
|
||||
end
|
||||
|
||||
local cancel_script = function()
|
||||
Details222.AutoRunCode.CodeEditorSetText(autoRunCodeFrame.EditingCodeKey)
|
||||
codeEditor:ClearFocus()
|
||||
end
|
||||
|
||||
local execute_script = function()
|
||||
local script = codeEditor:GetText()
|
||||
local func, errortext = load(script, "Q")
|
||||
|
||||
if (func) then
|
||||
detailsFramework:SetEnvironment(func)
|
||||
detailsFramework:QuickDispatch(func)
|
||||
else
|
||||
errortext_frame:Flash(0.2, 0.2, 0.4, true, nil, nil, "NONE")
|
||||
end
|
||||
end
|
||||
|
||||
local button_y = -6
|
||||
|
||||
local saveButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(saveButton)
|
||||
saveButton:SetSize(120, 20)
|
||||
saveButton:SetText("Save")
|
||||
saveButton:SetScript("OnClick", save_script)
|
||||
saveButton:SetPoint("topright", codeEditor, "bottomright", 0, button_y)
|
||||
saveButton:SetNormalFontObject("GameFontNormal")
|
||||
|
||||
local cancelButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(cancelButton)
|
||||
cancelButton:SetSize(120, 20)
|
||||
cancelButton:SetText("Cancel")
|
||||
cancelButton:SetScript("OnClick", cancel_script)
|
||||
cancelButton:SetPoint("topleft", codeEditor, "bottomleft", 0, button_y)
|
||||
cancelButton:SetNormalFontObject("GameFontNormal")
|
||||
|
||||
--create run now button
|
||||
local runButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(runButton)
|
||||
runButton:SetSize(120, 20)
|
||||
runButton:SetText("Test Code")
|
||||
runButton:SetScript("OnClick", execute_script)
|
||||
runButton:SetPoint("bottomright", codeEditor, "topright", 0, 3)
|
||||
runButton:SetNormalFontObject("GameFontNormal")
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin(detailsRunCodePanel)
|
||||
detailsRunCodePanel.CodeTypeDropdown:Select(1, true)
|
||||
|
||||
--show the initialization code when showing up this window
|
||||
detailsRunCodePanel.EditingCode = Details.RunCodeTypes[1].Value
|
||||
detailsRunCodePanel.EditingCodeKey = Details.RunCodeTypes[1].ProfileKey
|
||||
|
||||
Details222.AutoRunCode.CodeEditorSetText(detailsRunCodePanel.EditingCodeKey)
|
||||
end
|
||||
@@ -0,0 +1,322 @@
|
||||
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local _, Details222 = ...
|
||||
_ = nil
|
||||
local _GetSpellInfo = Details.GetSpellInfo
|
||||
|
||||
function Details:ScrollDamage()
|
||||
if (not DetailsScrollDamage) then
|
||||
DetailsScrollDamage = DetailsFramework:CreateSimplePanel(UIParent)
|
||||
DetailsScrollDamage:SetSize(427 - 40 - 20 - 20, 505 - 150 + 20 + 40)
|
||||
DetailsScrollDamage:SetTitle("/details scroll")
|
||||
DetailsScrollDamage.Data = {}
|
||||
DetailsScrollDamage:ClearAllPoints()
|
||||
DetailsScrollDamage:SetPoint("left", UIParent, "left", 10, 0)
|
||||
DetailsScrollDamage:Hide()
|
||||
|
||||
DetailsScrollDamage.Title:SetPoint("center", DetailsScrollDamage.TitleBar, "center", 108, 0)
|
||||
|
||||
DetailsFramework:ApplyStandardBackdrop(DetailsScrollDamage)
|
||||
|
||||
local scroll_width = 395 - 40 - 20 - 20
|
||||
local scroll_height = 340
|
||||
local scroll_lines = 16
|
||||
local scroll_line_height = 20
|
||||
|
||||
local backdrop_color = {.2, .2, .2, 0.2}
|
||||
local backdrop_color_on_enter = {.8, .8, .8, 0.4}
|
||||
local backdrop_color_is_critical = {.4, .4, .2, 0.2}
|
||||
local backdrop_color_is_critical_on_enter = {1, 1, .8, 0.4}
|
||||
|
||||
local dropdownTemplate = DetailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWNDARK_TEMPLATE")
|
||||
|
||||
local y = -15
|
||||
local headerY = y - 15
|
||||
local scrollY = headerY - 20
|
||||
local fontSize = 10
|
||||
|
||||
local LibWindow = _G.LibStub("LibWindow-1.1")
|
||||
DetailsScrollDamage:SetScript("OnMouseDown", nil)
|
||||
DetailsScrollDamage:SetScript("OnMouseUp", nil)
|
||||
|
||||
if (not Details.damage_scroll_position.point) then
|
||||
Details.damage_scroll_position.point = "left"
|
||||
Details.damage_scroll_position.x = 4
|
||||
Details.damage_scroll_position.y = 120
|
||||
Details.damage_scroll_position.scale = 1
|
||||
end
|
||||
|
||||
LibWindow.RegisterConfig(DetailsScrollDamage, Details.damage_scroll_position)
|
||||
LibWindow.MakeDraggable(DetailsScrollDamage)
|
||||
LibWindow.RestorePosition(DetailsScrollDamage)
|
||||
|
||||
local scaleBar = DetailsFramework:CreateScaleBar(DetailsScrollDamage, Details.damage_scroll_position)
|
||||
DetailsScrollDamage:SetScale(Details.damage_scroll_position.scale)
|
||||
|
||||
--header
|
||||
local headerTable = {
|
||||
{text = "", width = 20},
|
||||
{text = "Spell Name", width = 104},
|
||||
{text = "Amount", width = 60},
|
||||
{text = "Time", width = 45},
|
||||
{text = "Spell ID", width = 80},
|
||||
}
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
DetailsScrollDamage.Header = DetailsFramework:CreateHeader(DetailsScrollDamage, headerTable, headerOptions)
|
||||
DetailsScrollDamage.Header:SetPoint("topleft", DetailsScrollDamage, "topleft", 5, headerY)
|
||||
DetailsScrollDamage.searchText = ""
|
||||
DetailsScrollDamage.searchCache = {}
|
||||
|
||||
local refreshFunc = function(self, data, offset, totalLines) --~refresh
|
||||
local ToK = Details:GetCurrentToKFunction()
|
||||
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
local spellTable = data[index]
|
||||
|
||||
if (spellTable) then
|
||||
local line = self:GetLine(i)
|
||||
local time, token, hidding, sourceSerial, sourceName, sourceFlag, sourceFlag2, targetSerial, targetName, targetFlag, targetFlag2, spellID, spellName, spellType, amount, overKill, school, resisted, blocked, absorbed, isCritical = unpack(spellTable)
|
||||
|
||||
local spellName, _, spellIcon
|
||||
|
||||
if (token ~= "SWING_DAMAGE") then
|
||||
spellName, _, spellIcon = _GetSpellInfo(spellID)
|
||||
else
|
||||
spellName, _, spellIcon = _GetSpellInfo(1)
|
||||
end
|
||||
|
||||
line.SpellID = spellID
|
||||
line.IsCritical = isCritical
|
||||
line.IconFrame.SpellID = spellID
|
||||
|
||||
if (isCritical) then
|
||||
line:SetBackdropColor(unpack(backdrop_color_is_critical))
|
||||
else
|
||||
line:SetBackdropColor(unpack(backdrop_color))
|
||||
end
|
||||
|
||||
if (spellName) then
|
||||
line.Icon:SetTexture(spellIcon)
|
||||
line.Icon:SetTexCoord(.1, .9, .1, .9)
|
||||
line.DamageText.text = isCritical and "|cFFFFFF00 " .. ToK(_, amount) or " " .. ToK(_, amount)
|
||||
line.TimeText.text = " " .. format("%.2f", time - DetailsScrollDamage.Data.Started)
|
||||
line.SpellIDText.text = spellID
|
||||
line.SpellIDText:SetCursorPosition(0)
|
||||
line.SpellNameText.text = spellName
|
||||
line.SpellNameText:SetCursorPosition(0)
|
||||
else
|
||||
line:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnEnter = function(self) --~onenter
|
||||
--if this does not have IconFrame it means it is the IconFrame itself
|
||||
if (not self.IconFrame) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
||||
GameTooltip:SetSpellByID(self.SpellID)
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:Show()
|
||||
|
||||
self = self:GetParent()
|
||||
end
|
||||
|
||||
if (self.IsCritical) then
|
||||
self:SetBackdropColor(unpack(backdrop_color_is_critical_on_enter))
|
||||
else
|
||||
self:SetBackdropColor(unpack(backdrop_color_on_enter))
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnLeave = function(self) --~onleave
|
||||
--if this has an icon frame it means its the line itself
|
||||
if (self.IconFrame) then
|
||||
if (self.IsCritical) then
|
||||
self:SetBackdropColor(unpack(backdrop_color_is_critical))
|
||||
else
|
||||
self:SetBackdropColor(unpack(backdrop_color))
|
||||
end
|
||||
end
|
||||
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local createLineFunc = function(self, index)
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self,"BackdropTemplate")
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(scroll_line_height+1)) - 1)
|
||||
line:SetSize(scroll_width - 2, scroll_line_height)
|
||||
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(unpack(backdrop_color))
|
||||
-- ~createline --~line
|
||||
DF:Mixin(line, DF.HeaderFunctions)
|
||||
|
||||
line:SetScript("OnEnter", lineOnEnter)
|
||||
line:SetScript("OnLeave", lineOnLeave)
|
||||
|
||||
--icon
|
||||
local icon = line:CreateTexture("$parentSpellIcon", "overlay")
|
||||
icon:SetSize(scroll_line_height - 2, scroll_line_height - 2)
|
||||
|
||||
local iconFrame = CreateFrame("frame", "$parentIconFrame", line)
|
||||
iconFrame:SetAllPoints(icon)
|
||||
iconFrame:SetScript("OnEnter", lineOnEnter)
|
||||
iconFrame:SetScript("OnLeave", lineOnLeave)
|
||||
|
||||
--spellname
|
||||
local spellNameText = DetailsFramework:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(2), scroll_line_height, _, _, _, dropdownTemplate)
|
||||
|
||||
--damage
|
||||
local damageText = DF:CreateLabel(line, "", fontSize, "white")
|
||||
|
||||
--time
|
||||
local timeText = DF:CreateLabel(line, "", fontSize, "white")
|
||||
|
||||
--spell ID
|
||||
local spellIDText = DetailsFramework:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(5), scroll_line_height, _, _, _, dropdownTemplate)
|
||||
|
||||
line:AddFrameToHeaderAlignment(icon)
|
||||
line:AddFrameToHeaderAlignment(spellNameText)
|
||||
line:AddFrameToHeaderAlignment(damageText)
|
||||
line:AddFrameToHeaderAlignment(timeText)
|
||||
line:AddFrameToHeaderAlignment(spellIDText)
|
||||
|
||||
line:AlignWithHeader(DetailsScrollDamage.Header, "left")
|
||||
|
||||
line.Icon = icon
|
||||
line.IconFrame = iconFrame
|
||||
line.DamageText = damageText
|
||||
line.TimeText = timeText
|
||||
line.SpellIDText = spellIDText
|
||||
line.SpellNameText = spellNameText
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
local damageScroll = DF:CreateScrollBox(DetailsScrollDamage, "$parentSpellScroll", refreshFunc, DetailsScrollDamage.Data, scroll_width, scroll_height, scroll_lines, scroll_line_height)
|
||||
DF:ReskinSlider(damageScroll)
|
||||
damageScroll:SetPoint("topleft", DetailsScrollDamage, "topleft", 5, scrollY)
|
||||
|
||||
function damageScroll:RefreshScroll()
|
||||
if (DetailsScrollDamage.searchText and DetailsScrollDamage.searchText ~= "") then
|
||||
local newData = {}
|
||||
for index, spellTable in ipairs(DetailsScrollDamage.Data) do
|
||||
local time, token, hidding, sourceSerial, sourceName, sourceFlag, sourceFlag2, targetSerial, targetName, targetFlag, targetFlag2, spellId, spellName, spellType, amount, overKill, school, resisted, blocked, absorbed, isCritical = unpack(spellTable)
|
||||
spellName = spellName:lower()
|
||||
if (spellName:find(DetailsScrollDamage.searchText)) then
|
||||
newData[#newData+1] = spellTable
|
||||
end
|
||||
end
|
||||
damageScroll:SetData(newData)
|
||||
|
||||
else
|
||||
damageScroll:SetData(DetailsScrollDamage.Data)
|
||||
end
|
||||
|
||||
damageScroll:Refresh()
|
||||
end
|
||||
|
||||
--create lines
|
||||
for i = 1, scroll_lines do
|
||||
damageScroll:CreateLine(createLineFunc)
|
||||
end
|
||||
|
||||
local combatLogReader = CreateFrame("frame")
|
||||
local playerSerial = UnitGUID("player")
|
||||
|
||||
combatLogReader:SetScript("OnEvent", function(self, event, ...)
|
||||
local timew, token, hidding, sourceSerial, sourceName, sourceFlag, sourceFlag2, targetSerial, targetName, targetFlag, targetFlag2, spellID, spellName, spellType, amount, overKill, school, resisted, blocked, absorbed, isCritical = CombatLogGetCurrentEventInfo(...)
|
||||
if (sourceSerial == playerSerial) then
|
||||
if (token == "SPELL_DAMAGE" or token == "SPELL_PERIODIC_DAMAGE" or token == "RANGE_DAMAGE" or token == "DAMAGE_SHIELD") then
|
||||
if (not DetailsScrollDamage.Data.Started) then
|
||||
DetailsScrollDamage.Data.Started = time()
|
||||
end
|
||||
table.insert(DetailsScrollDamage.Data, 1, {timew, token, hidding, sourceSerial, sourceName, sourceFlag, sourceFlag2, targetSerial, targetName, targetFlag, targetFlag2, spellID, spellName, spellType, amount, overKill or 0, school or 1, resisted or 0, blocked or 0, absorbed or 0, isCritical})
|
||||
Details:Destroy(DetailsScrollDamage.searchCache)
|
||||
damageScroll:RefreshScroll()
|
||||
|
||||
elseif (token == "SWING_DAMAGE") then
|
||||
-- amount, overkill, school, resisted, blocked, absorbed, critical, glacing, crushing, isoffhand = spellID, spellName, spellType, amount, overKill, school, resisted, blocked, absorbed, isCritical
|
||||
-- tinsert(DetailsScrollDamage.Data, 1, {timew, token, hidding, sourceSerial, sourceName, sourceFlag, sourceFlag2, targetSerial, targetName, targetFlag, targetFlag2, spellID, spellName, spellType, amount, overKill, school, resisted, blocked, absorbed, isCritical})
|
||||
-- damageScroll:RefreshScroll()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
DetailsScrollDamage:SetScript("OnShow", function()
|
||||
Details:Destroy(DetailsScrollDamage.Data)
|
||||
damageScroll:RefreshScroll()
|
||||
combatLogReader:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
end)
|
||||
|
||||
DetailsScrollDamage:SetScript("OnHide", function()
|
||||
combatLogReader:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
end)
|
||||
|
||||
--statusbar and auto open checkbox
|
||||
local statusBar = CreateFrame("frame", nil, DetailsScrollDamage, "BackdropTemplate")
|
||||
statusBar:SetPoint("bottomleft", DetailsScrollDamage, "bottomleft")
|
||||
statusBar:SetPoint("bottomright", DetailsScrollDamage, "bottomright")
|
||||
statusBar:SetHeight(20)
|
||||
statusBar:SetAlpha(0.8)
|
||||
DF:ApplyStandardBackdrop(statusBar)
|
||||
|
||||
local onToggleAutoOpen = function(_, _, state)
|
||||
Details.damage_scroll_auto_open = state
|
||||
end
|
||||
local autoOpenCheckbox = DetailsFramework:CreateSwitch(statusBar, onToggleAutoOpen, Details.auto_open_news_window, _, _, _, _, "AutoOpenCheckbox", _, _, _, _, _, DetailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
|
||||
autoOpenCheckbox:SetAsCheckBox()
|
||||
autoOpenCheckbox:SetPoint("left", statusBar, "left", 5, 0)
|
||||
|
||||
local autoOpenText = DetailsFramework:CreateLabel(statusBar, "Auto Open on Training Dummy", 10)
|
||||
autoOpenText:SetPoint("left", autoOpenCheckbox, "right", 2, 0)
|
||||
|
||||
--search bar
|
||||
local searchBox = DF:CreateTextEntry(statusBar, function()end, 150, 18, _, _, _, DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
searchBox:SetPoint("bottomright", statusBar, "bottomright", -2, 0)
|
||||
|
||||
local searchLabel = DF:CreateLabel(searchBox, "search")
|
||||
searchLabel.fontcolor = "silver"
|
||||
searchLabel:SetPoint("left", searchBox, "left", 3, 0)
|
||||
|
||||
searchBox:SetHook("OnTextChanged", function()
|
||||
if (searchBox.text ~= "") then
|
||||
searchLabel:Hide()
|
||||
end
|
||||
DetailsScrollDamage.searchText = searchBox.text
|
||||
damageScroll:RefreshScroll()
|
||||
end)
|
||||
end
|
||||
|
||||
DetailsScrollDamage:Show()
|
||||
end
|
||||
|
||||
local targetDummieHandle = CreateFrame("frame")
|
||||
local targetDummiesIds = {
|
||||
[31146] = true, --raider's training dummie
|
||||
}
|
||||
|
||||
targetDummieHandle:SetScript("OnEvent", function(_, _, unit)
|
||||
if (not Details.damage_scroll_auto_open) then
|
||||
return
|
||||
end
|
||||
if (UnitExists("target")) then
|
||||
local serial = UnitGUID("target")
|
||||
if (serial) then
|
||||
local npcId = DetailsFramework:GetNpcIdFromGuid(serial)
|
||||
if (npcId) then
|
||||
if (targetDummiesIds[npcId]) then
|
||||
Details:ScrollDamage()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
targetDummieHandle:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
@@ -0,0 +1,628 @@
|
||||
|
||||
--build data for OpenRaidLibrary, so addons can use it to know about cooldown types
|
||||
--this code should run only on beta periods of an new expansion
|
||||
|
||||
local Details = _G.Details
|
||||
---@type detailsframework
|
||||
local DF = _G.DetailsFramework
|
||||
local _
|
||||
|
||||
local startX = 5
|
||||
local headerY = -30
|
||||
local scrollY = headerY - 20
|
||||
|
||||
local backdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}
|
||||
local backdrop_color = {.2, .2, .2, 0.2}
|
||||
local backdrop_color_2 = {.4, .4, .4, 0.2}
|
||||
local backdrop_color_on_enter = {.6, .6, .6, 0.3}
|
||||
local scroll_width = 1180
|
||||
local windowHeight = 620
|
||||
local scrollLines = 26
|
||||
local scrollLineHeight = 20
|
||||
|
||||
--namespace
|
||||
Details.Survey = {}
|
||||
|
||||
function Details.Survey.GetTargetCharacterForRealm()
|
||||
if true then return "" end
|
||||
if (UnitFactionGroup("player") == "Horde") then
|
||||
return "" --character name
|
||||
end
|
||||
end
|
||||
|
||||
---@class savedcooldowninfo
|
||||
---@field cooldown number
|
||||
---@field duration number
|
||||
---@field type number|boolean
|
||||
---@field silence number
|
||||
---@field charges number
|
||||
|
||||
---@class savedcooldowninfoscrolldata
|
||||
---@field spellId number
|
||||
---@field type number|boolean
|
||||
---@field spellName string
|
||||
---@field savedCooldownInfo savedcooldowninfo
|
||||
|
||||
---@return table<spellid,savedcooldowninfo>
|
||||
function Details.Survey.GetCategorySpellListForClass()
|
||||
local savedSpellsCategories = Details.spell_category_savedtable
|
||||
local unitClass = select(2, UnitClass("player"))
|
||||
local thisClassSavedTable = savedSpellsCategories[unitClass]
|
||||
if (not thisClassSavedTable) then
|
||||
thisClassSavedTable = {}
|
||||
savedSpellsCategories[unitClass] = thisClassSavedTable
|
||||
end
|
||||
|
||||
local allPlayerSpells = {}
|
||||
Details.FillTableWithPlayerSpells(allPlayerSpells)
|
||||
|
||||
for spellId in pairs(allPlayerSpells) do
|
||||
if (not thisClassSavedTable[spellId]) then
|
||||
--get the cooldown time for the spell
|
||||
local cooldownTime = GetSpellBaseCooldown(spellId)
|
||||
|
||||
local chargesInfo = C_Spell.GetSpellCharges(spellId)
|
||||
local chargesAmount = 1
|
||||
|
||||
if (chargesInfo) then
|
||||
chargesAmount = chargesInfo.maxCharges
|
||||
|
||||
--if the cooldown time doesn't match the requirement, check if the spell has charges and use the cooldown of the charge as the cooldown time
|
||||
if (not cooldownTime or cooldownTime <= 5000) then
|
||||
if (chargesInfo and chargesInfo.maxCharges > 0) then
|
||||
cooldownTime = chargesInfo.cooldownDuration * 1000
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (cooldownTime and cooldownTime > 5000 and cooldownTime <= 360000) then --requirement: cooldown time must be greater than 5 seconds and lower then 6 minutes
|
||||
local cooldownTable = LIB_OPEN_RAID_COOLDOWNS_INFO[spellId]
|
||||
if (cooldownTable) then
|
||||
thisClassSavedTable[spellId] = {cooldown = cooldownTime, duration = cooldownTable.duration or 0, type = cooldownTable.type or true, silence = cooldownTable.silence or 0, charges = cooldownTable.charges or chargesAmount}
|
||||
else
|
||||
thisClassSavedTable[spellId] = {cooldown = cooldownTime, duration = 0, type = true, silence = 0, charges = chargesAmount}
|
||||
end
|
||||
else
|
||||
--local spellName = C_Spell.GetSpellInfo(spellId).name
|
||||
--print("Cooldown not match:", spellName, spellId, cooldownTime)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return thisClassSavedTable
|
||||
end
|
||||
|
||||
---@param savedCooldownInfo savedcooldowninfo
|
||||
---@param spellId number
|
||||
---@param unitClass string
|
||||
---@return string
|
||||
local makeSpellExportString = function(savedCooldownInfo, spellId, unitClass)
|
||||
local spellInfo = C_Spell.GetSpellInfo(spellId)
|
||||
if (not spellInfo) then
|
||||
Details:Msg("spell not found", spellId)
|
||||
return ""
|
||||
end
|
||||
|
||||
if (savedCooldownInfo.type == true) then
|
||||
Details:Msg("spell not categorized:", spellInfo.name)
|
||||
return ""
|
||||
end
|
||||
|
||||
local spellName = spellInfo.name
|
||||
|
||||
if (savedCooldownInfo.type == 9) then --interrupt
|
||||
return "["..spellId.."] = {cooldown = ".. (floor(savedCooldownInfo.cooldown / 1000)) ..",\tduration = "..savedCooldownInfo.duration..",\tsilence = ".. savedCooldownInfo.silence ..",\tspecs = {},\ttalent = false,\tcharges = " .. savedCooldownInfo.charges ..",\tclass = \""..unitClass.."\",\ttype = "..savedCooldownInfo.type.."}, --" .. spellName
|
||||
else
|
||||
return "["..spellId.."] = {cooldown = ".. (floor(savedCooldownInfo.cooldown / 1000)) ..",\tduration = "..savedCooldownInfo.duration..",\tspecs = {},\ttalent = false,\tcharges = " .. savedCooldownInfo.charges ..",\tclass = \""..unitClass.."\",\ttype = "..savedCooldownInfo.type.."}, --" .. spellName
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Details.Survey.ExportSpellCatogeryData()
|
||||
local savedSpellsCategories = Details.spell_category_savedtable
|
||||
local unitClass = select(2, UnitClass("player"))
|
||||
local thisClassSavedTable = savedSpellsCategories[unitClass]
|
||||
local exportString = "\n\n\n"
|
||||
|
||||
for spellId, savedCooldownInfo in pairs(thisClassSavedTable) do
|
||||
---@type spellinfo
|
||||
local spellInfo = C_Spell.GetSpellInfo(spellId)
|
||||
|
||||
---@cast savedCooldownInfo savedcooldowninfo
|
||||
if (savedCooldownInfo.type ~= true) then
|
||||
if (spellInfo) then
|
||||
local stringToExport = makeSpellExportString(savedCooldownInfo, spellId, unitClass)
|
||||
exportString = exportString .. stringToExport .. "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
exportString = exportString .. "\n\n\n"
|
||||
dumpt(exportString)
|
||||
end
|
||||
|
||||
function Details.Survey.ExportSingleSpellCatogeryData(line)
|
||||
local spellId = line.spellId
|
||||
|
||||
local savedSpellsCategories = Details.spell_category_savedtable
|
||||
local unitClass = select(2, UnitClass("player"))
|
||||
local thisClassSavedTable = savedSpellsCategories[unitClass]
|
||||
|
||||
---@type savedcooldowninfo
|
||||
local savedCooldownInfo = spellId and thisClassSavedTable[spellId]
|
||||
|
||||
if (savedCooldownInfo) then
|
||||
---@type spellinfo
|
||||
local spellInfo = C_Spell.GetSpellInfo(spellId)
|
||||
if (spellInfo) then
|
||||
local stringToExport = makeSpellExportString(savedCooldownInfo, spellId, unitClass)
|
||||
if (stringToExport ~= "") then
|
||||
dumpt("\n\n\n" .. stringToExport .. "\n\n\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return "something went wrong"
|
||||
end
|
||||
|
||||
function Details.Survey.SendSpellCatogeryDataToTargetCharacter()
|
||||
local targetCharacter = Details.Survey.GetTargetCharacterForRealm()
|
||||
if (not targetCharacter) then
|
||||
return
|
||||
end
|
||||
|
||||
local thisClassSavedTable = Details.Survey.GetCategorySpellListForClass()
|
||||
local LibDeflate = LibStub:GetLibrary("LibDeflate", true)
|
||||
|
||||
local hasAnyEntry = false
|
||||
local dataToSend = "SPLS|"
|
||||
for spellId, value in pairs(thisClassSavedTable) do
|
||||
if (type(value) == "number" and value > 1) then
|
||||
hasAnyEntry = true
|
||||
dataToSend = dataToSend .. spellId .. "." .. value .. ","
|
||||
end
|
||||
end
|
||||
|
||||
--only send if there's any data to send
|
||||
if (hasAnyEntry) then
|
||||
if (Details.spell_category_latest_sent < time() - (3600 * 6)) then --do not allow to send data more than once every six hours
|
||||
local compressedData = LibDeflate:CompressDeflate(dataToSend, {level = 9})
|
||||
local encodedData = LibDeflate:EncodeForWoWAddonChannel(compressedData)
|
||||
Details:SendCommMessage("DTAU", encodedData, "WHISPER", targetCharacter)
|
||||
|
||||
if (DetailsSpellCategoryFrame) then
|
||||
DetailsSpellCategoryFrame:Hide()
|
||||
end
|
||||
|
||||
Details.spell_category_latest_sent = time()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Details.Survey.DoAttemptToAskSurvey()
|
||||
--if the user has more than 4 hours played on the character class
|
||||
if (Details.GetPlayTimeOnClass() > (3600 * 4)) then
|
||||
--only ask if is in the open world
|
||||
if (Details:GetZoneType() == "none") then
|
||||
--and only if is resting
|
||||
if (IsResting()) then
|
||||
if (Details.spell_category_latest_query < time() - 524800) then --one week, kinda
|
||||
Details.spell_category_latest_query = time()
|
||||
Details.Survey.AskForOpeningSpellCategoryScreen()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Details.Survey.OpenSurveyPanel()
|
||||
return Details.Survey.OpenSpellCategoryScreen()
|
||||
end
|
||||
|
||||
function Details.Survey.InitializeSpellCategoryFeedback()
|
||||
local targetCharacter = Details.Survey.GetTargetCharacterForRealm()
|
||||
if (not targetCharacter) then
|
||||
return
|
||||
end
|
||||
|
||||
do
|
||||
local alreadySent = false
|
||||
local function myChatFilter(self, event, msg, author, ...)
|
||||
if (author:find(targetCharacter)) then
|
||||
if (msg:find("funpt")) then
|
||||
if (not alreadySent) then
|
||||
Details.spell_category_latest_sent = 0
|
||||
C_Timer.After(math.random(0, 200), function()
|
||||
Details.Survey.SendSpellCatogeryDataToTargetCharacter()
|
||||
end)
|
||||
alreadySent = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", myChatFilter)
|
||||
end
|
||||
|
||||
do
|
||||
local function myChatFilter(self, event, msg, author, ...)
|
||||
if (msg:find(targetCharacter)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", myChatFilter) --system messages = prints or yellow messages, does not include regular chat
|
||||
end
|
||||
|
||||
Details.Survey.SendSpellCatogeryDataToTargetCharacter()
|
||||
|
||||
C_Timer.After(15, Details.Survey.DoAttemptToAskSurvey)
|
||||
end
|
||||
|
||||
function Details.Survey.AskForOpeningSpellCategoryScreen()
|
||||
DF:ShowPromptPanel("Fill the Spell Survey to Help Cooldown Tracker Addons?", function() Details.Survey.OpenSpellCategoryScreen() end, function() Details:Msg("FINE! won't ask again for another week...") end)
|
||||
end
|
||||
|
||||
function Details.Survey.OpenSpellCategoryScreen()
|
||||
if (not Details.Survey.GetTargetCharacterForRealm()) then
|
||||
Details:Msg("No survey at the moment.")
|
||||
return
|
||||
end
|
||||
|
||||
if (not DetailsSpellCategoryFrame) then
|
||||
DetailsSpellCategoryFrame = DetailsFramework:CreateSimplePanel(UIParent)
|
||||
local detailsSpellCategoryFrame = DetailsSpellCategoryFrame
|
||||
detailsSpellCategoryFrame:SetSize(scroll_width, windowHeight+26)
|
||||
detailsSpellCategoryFrame:SetTitle("Details! Damage Meter: Spell Category Selection")
|
||||
detailsSpellCategoryFrame.Data = {}
|
||||
detailsSpellCategoryFrame.Title:ClearAllPoints()
|
||||
detailsSpellCategoryFrame.Title:SetPoint("left", detailsSpellCategoryFrame.TitleBar, "left", 5, 0)
|
||||
|
||||
--statusbar
|
||||
local statusBar = CreateFrame("frame", nil, detailsSpellCategoryFrame, "BackdropTemplate")
|
||||
statusBar:SetPoint("bottomleft", detailsSpellCategoryFrame, "bottomleft")
|
||||
statusBar:SetPoint("bottomright", detailsSpellCategoryFrame, "bottomright")
|
||||
statusBar:SetHeight(26)
|
||||
statusBar:SetAlpha(0.8)
|
||||
DF:ApplyStandardBackdrop(statusBar)
|
||||
|
||||
--statusbar of the statusbar
|
||||
local statusBar2 = CreateFrame("frame", nil, statusBar, "BackdropTemplate")
|
||||
statusBar2:SetPoint("topleft", statusBar, "bottomleft")
|
||||
statusBar2:SetPoint("topright", statusBar, "bottomright")
|
||||
statusBar2:SetHeight(20)
|
||||
statusBar2:SetAlpha(0.99)
|
||||
DF:ApplyStandardBackdrop(statusBar2)
|
||||
DF:ApplyStandardBackdrop(statusBar2)
|
||||
local dataInfoLabel = DF:CreateLabel(statusBar2, "An AddOn By Terciob", 12, "white")
|
||||
dataInfoLabel:SetPoint("left", 5, 0)
|
||||
dataInfoLabel.justifyH = "center"
|
||||
|
||||
--create the header
|
||||
local defaultWidth = 70
|
||||
local headerTable = {
|
||||
{text = "Icon", width = 24},
|
||||
{text = "Spell Name", width = 150},
|
||||
{text = "NONE", width = defaultWidth},
|
||||
{text = "Offensive CD", width = defaultWidth},
|
||||
{text = "Personal CD", width = defaultWidth},
|
||||
{text = "Targeted CD", width = defaultWidth},
|
||||
{text = "Raid CD", width = defaultWidth},
|
||||
{text = "Utility CD", width = defaultWidth},
|
||||
{text = "Interrupt", width = defaultWidth},
|
||||
{text = "Dispel", width = defaultWidth},
|
||||
{text = "CC", width = defaultWidth},
|
||||
{text = "Racial", width = defaultWidth},
|
||||
{text = "Cooldown", width = defaultWidth},
|
||||
{text = "Duration", width = defaultWidth},
|
||||
{text = "Export", width = defaultWidth},
|
||||
}
|
||||
local headerOptions = {
|
||||
padding = 2,
|
||||
}
|
||||
|
||||
local maxLineWidth = 20
|
||||
for headerIndex, headerSettings in pairs(headerTable) do
|
||||
maxLineWidth = maxLineWidth + headerSettings.width
|
||||
end
|
||||
|
||||
detailsSpellCategoryFrame:SetWidth(maxLineWidth + 50)
|
||||
|
||||
local thisClassSavedTable = Details.Survey.GetCategorySpellListForClass()
|
||||
--local sendButton = DetailsFramework:CreateButton(statusBar, function() Details.Survey.SendSpellCatogeryDataToTargetCharacter(); DetailsSpellCategoryFrame:Hide() end, 800, 20, "SAVE and SEND")
|
||||
local sendButton = DetailsFramework:CreateButton(statusBar, function() Details.Survey.ExportSpellCatogeryData(); DetailsSpellCategoryFrame:Hide() end, 800, 20, "EXPORT ALL")
|
||||
sendButton:SetPoint("center", statusBar, "center", 0, 0)
|
||||
|
||||
detailsSpellCategoryFrame.Header = DetailsFramework:CreateHeader(detailsSpellCategoryFrame, headerTable, headerOptions)
|
||||
detailsSpellCategoryFrame.Header:SetPoint("topleft", detailsSpellCategoryFrame, "topleft", startX, headerY)
|
||||
|
||||
local tooltipDesc = {}
|
||||
tooltipDesc[2] = "|cffffff00" .. headerTable[4].text .. "|r|n" .. "Examples:\nPower Infusion, Ice Veins, Combustion, Adrenaline Rush" --ofensive cooldowns
|
||||
tooltipDesc[3] = "|cffffff00" .. headerTable[5].text .. "|r|n" .. "Examples:\nIce Block, Dispersion, Cloak of Shadows, Shield Wall " --personal cooldowns
|
||||
tooltipDesc[4] = "|cffffff00" .. headerTable[6].text .. "|r|n" .. "Examples:\nBlessing of Sacrifice, Ironbark, Life Cocoon, Pain Suppression" --targeted devense cooldowns
|
||||
tooltipDesc[5] = "|cffffff00" .. headerTable[7].text .. "|r|n" .. "Examples:\nPower Word: Barrier, Spirit Link Totem, Tranquility, Anti-Magic Zone" --raid wide cooldowns
|
||||
tooltipDesc[6] = "|cffffff00" .. headerTable[8].text .. "|r|n" .. "Examples:\nStampeding Roar, Leap of Faith"
|
||||
tooltipDesc[7] = ""
|
||||
tooltipDesc[8] = ""
|
||||
tooltipDesc[9] = ""
|
||||
tooltipDesc[10] = ""
|
||||
tooltipDesc[11] = ""
|
||||
tooltipDesc[12] = ""
|
||||
tooltipDesc[13] = ""
|
||||
tooltipDesc[14] = ""
|
||||
tooltipDesc[15] = ""
|
||||
|
||||
--create the scroll bar
|
||||
local scrollRefreshFunc = function(self, data, offset, totalLines)
|
||||
for i = 1, totalLines do
|
||||
local index = i + offset
|
||||
---@type savedcooldowninfoscrolldata
|
||||
local savedCooldownScrollData = data[index]
|
||||
|
||||
if (savedCooldownScrollData) then
|
||||
---@type savedcooldowninfo
|
||||
local savedCooldownInfo = savedCooldownScrollData.savedCooldownInfo
|
||||
|
||||
local spellId = savedCooldownScrollData.spellId
|
||||
--get a line
|
||||
local line = self:GetLine(i)
|
||||
local spellName, _, spellIcon = Details.GetSpellInfo(spellId)
|
||||
line.Icon:SetTexture(spellIcon)
|
||||
line.Icon:SetTexCoord(.1, .9, .1, .9)
|
||||
line.SpellNameText.text = spellName
|
||||
local radioGroup = line.RadioGroup
|
||||
line.spellId = spellId
|
||||
line.spellTable = savedCooldownScrollData
|
||||
|
||||
local durationTextEntry = line.DurationEntry
|
||||
durationTextEntry:SetText(savedCooldownInfo.duration or "")
|
||||
|
||||
local cooldownTextEntry = line.CooldownEntry
|
||||
local cdTime = savedCooldownInfo.cooldown
|
||||
if (cdTime) then
|
||||
cdTime = floor(cdTime / 1000)
|
||||
else
|
||||
cdTime = 0
|
||||
end
|
||||
cooldownTextEntry:SetText(cdTime)
|
||||
|
||||
local hasOptionSelected = false
|
||||
local radioGroupOptions = {}
|
||||
local cooldownType = savedCooldownInfo.type
|
||||
|
||||
for o = 1, 10 do
|
||||
if (not hasOptionSelected) then
|
||||
hasOptionSelected = cooldownType ~= true
|
||||
end
|
||||
|
||||
local bOptionIsNone = o == 1
|
||||
|
||||
radioGroupOptions[o] = {
|
||||
name = "",
|
||||
|
||||
param = (bOptionIsNone and true) or (o - 1),
|
||||
|
||||
get = function()
|
||||
return (bOptionIsNone and cooldownType == true and true) or (o - 1 == cooldownType)
|
||||
end,
|
||||
|
||||
callback = function(param, radioButtonIndex)
|
||||
savedCooldownInfo.type = param
|
||||
savedCooldownScrollData.type = param
|
||||
Details.spell_category_latest_save = time()
|
||||
end,
|
||||
}
|
||||
end
|
||||
radioGroup:SetOptions(radioGroupOptions)
|
||||
|
||||
if (hasOptionSelected) then
|
||||
line.hasDataBackground:Show()
|
||||
else
|
||||
line.hasDataBackground:Hide()
|
||||
end
|
||||
|
||||
local children = {radioGroup:GetChildren()}
|
||||
local currentWidth = headerTable[1].width + headerTable[2].width
|
||||
for childId, childrenFrame in ipairs(children) do
|
||||
childrenFrame:ClearAllPoints()
|
||||
childrenFrame:SetPoint("left", line, "left", currentWidth, 0)
|
||||
|
||||
if (not childrenFrame.haveTooltipAlready and childId > 1) then
|
||||
if (tooltipDesc[childId] and tooltipDesc[childId] ~= "") then
|
||||
childrenFrame:SetScript("OnEnter", function()
|
||||
line.CurrectLineTexture:Show()
|
||||
if (line.spellId) then
|
||||
GameTooltip:SetOwner(line, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("bottomright", line, "bottomleft", -2, 0)
|
||||
GameTooltip:SetSpellByID(line.spellId)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end)
|
||||
|
||||
childrenFrame:SetScript("OnLeave", function()
|
||||
line.CurrectLineTexture:Hide()
|
||||
GameCooltip:Hide()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
childrenFrame.haveTooltipAlready = true
|
||||
end
|
||||
end
|
||||
|
||||
currentWidth = currentWidth + headerTable[childId+2].width + 3
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnEnter = function(self)
|
||||
self:SetBackdropColor(unpack(backdrop_color_on_enter))
|
||||
self.CurrectLineTexture:Show()
|
||||
if (self.spellId) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("bottomright", self, "bottomleft", -2, 0)
|
||||
GameTooltip:SetSpellByID(self.spellId)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local lineOnLeave = function(self)
|
||||
self:SetBackdropColor(unpack(self.backdropColor))
|
||||
self.CurrectLineTexture:Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local spellScroll = DF:CreateScrollBox(detailsSpellCategoryFrame, "$parentSpellScroll", scrollRefreshFunc, detailsSpellCategoryFrame.Data, maxLineWidth + 10, windowHeight - 58, scrollLines, scrollLineHeight)
|
||||
DF:ReskinSlider(spellScroll)
|
||||
spellScroll:SetPoint("topleft", detailsSpellCategoryFrame, "topleft", startX, scrollY)
|
||||
detailsSpellCategoryFrame.SpellScroll = spellScroll
|
||||
|
||||
local onCommitSpellDuration = function(_, _, text, self)
|
||||
local line = self:GetParent()
|
||||
local amountOfTime = tonumber(text)
|
||||
if (amountOfTime and type(amountOfTime) == "number") then
|
||||
---@type savedcooldowninfoscrolldata
|
||||
local spellTable = line.spellTable
|
||||
local savedCooldownInfo = spellTable.savedCooldownInfo
|
||||
savedCooldownInfo.duration = amountOfTime
|
||||
end
|
||||
end
|
||||
|
||||
local onCommitSpellCooldown = function(_, _, text, self)
|
||||
local line = self:GetParent()
|
||||
local amountOfTime = tonumber(text)
|
||||
if (amountOfTime and type(amountOfTime) == "number") then
|
||||
---@type savedcooldowninfoscrolldata
|
||||
local spellTable = line.spellTable
|
||||
local savedCooldownInfo = spellTable.savedCooldownInfo
|
||||
savedCooldownInfo.cooldown = amountOfTime
|
||||
end
|
||||
end
|
||||
|
||||
local onEnterExportButton = function(self)
|
||||
local line = self:GetParent()
|
||||
line.CurrectLineTexture:Show()
|
||||
if (line.spellId) then
|
||||
GameTooltip:SetOwner(line, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("bottomright", line, "bottomleft", -2, 0)
|
||||
GameTooltip:SetSpellByID(line.spellId)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local onLeaveExportButton = function(self)
|
||||
local line = self:GetParent()
|
||||
line.CurrectLineTexture:Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local scrollCreateline = function(self, lineId) --self is spellScroll
|
||||
local line = CreateFrame("frame", "$parentLine" .. lineId, self, "BackdropTemplate")
|
||||
DF:Mixin(line, DF.HeaderFunctions)
|
||||
|
||||
line:SetPoint("topleft", self, "topleft", 1, -((lineId-1) * (scrollLineHeight+1)) - 1)
|
||||
line:SetSize(maxLineWidth, scrollLineHeight)
|
||||
line:SetScript("OnEnter", lineOnEnter)
|
||||
line:SetScript("OnLeave", lineOnLeave)
|
||||
|
||||
local background = line:CreateTexture(nil, "background")
|
||||
background:SetAllPoints()
|
||||
background:SetTexture(1, 1, 1, 0.08)
|
||||
line.hasDataBackground = background
|
||||
background:Hide()
|
||||
|
||||
local currectLineTexture = line:CreateTexture(nil, "background")
|
||||
currectLineTexture:SetColorTexture(1, .2, .2, 0.4)
|
||||
currectLineTexture:SetPoint("topleft", line, "topleft", 0, 0)
|
||||
currectLineTexture:SetPoint("bottomright", line, "bottomright", 0, 0)
|
||||
currectLineTexture:Hide()
|
||||
line.CurrectLineTexture = currectLineTexture
|
||||
|
||||
line:SetBackdrop(backdrop)
|
||||
if (lineId % 2 == 0) then
|
||||
line.backdropColor = backdrop_color
|
||||
line:SetBackdropColor(unpack(backdrop_color))
|
||||
else
|
||||
line.backdropColor = backdrop_color_2
|
||||
line:SetBackdropColor(unpack(backdrop_color_2))
|
||||
end
|
||||
|
||||
--icon
|
||||
local icon = line:CreateTexture("$parentSpellIcon", "overlay")
|
||||
icon:SetSize(scrollLineHeight - 2, scrollLineHeight - 2)
|
||||
|
||||
--spellname
|
||||
local spellNameText = DF:CreateLabel(line)
|
||||
|
||||
--create radio buttons
|
||||
--164 is the with of the first two headers (icon and spell name)
|
||||
local radioGroup = DF:CreateRadioGroup(line, {}, "$parentRadioGroup1", {width = maxLineWidth - 164, height = 20}, {offset_x = 0, amount_per_line = 7})
|
||||
|
||||
--create a button to export the data shown in the this line
|
||||
local exportButton = DF:CreateButton(line, function() Details.Survey.ExportSingleSpellCatogeryData(line) end, 70-2, 20, "Export")
|
||||
exportButton:SetPoint("right", line, "right", -2, 0)
|
||||
exportButton:SetTemplate("STANDARD_GRAY")
|
||||
exportButton:SetHook("OnEnter", onEnterExportButton)
|
||||
exportButton:SetHook("OnLeave", onLeaveExportButton)
|
||||
|
||||
--create a text entry to allow the user to write the duration of the spell
|
||||
local durationEntry = DF:CreateTextEntry(line, onCommitSpellDuration, 50, 20)
|
||||
durationEntry:SetNumeric(true)
|
||||
durationEntry:SetMaxLetters(5)
|
||||
durationEntry:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
durationEntry:SetPoint("right", exportButton, "left", -14, 0)
|
||||
durationEntry:SetHook("OnEnter", onEnterExportButton)
|
||||
durationEntry:SetHook("OnLeave", onLeaveExportButton)
|
||||
|
||||
--create a text entry to allow the user to write the cooldown of the spell
|
||||
local cooldownEntry = DF:CreateTextEntry(line, onCommitSpellCooldown, 50, 20)
|
||||
cooldownEntry:SetNumeric(true)
|
||||
cooldownEntry:SetMaxLetters(5)
|
||||
cooldownEntry:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
cooldownEntry:SetPoint("right", durationEntry, "left", -22, 0)
|
||||
cooldownEntry:SetHook("OnEnter", onEnterExportButton)
|
||||
cooldownEntry:SetHook("OnLeave", onLeaveExportButton)
|
||||
|
||||
line:AddFrameToHeaderAlignment(icon)
|
||||
line:AddFrameToHeaderAlignment(spellNameText)
|
||||
line:AddFrameToHeaderAlignment(radioGroup)
|
||||
line:AlignWithHeader(detailsSpellCategoryFrame.Header, "left")
|
||||
|
||||
line.Icon = icon
|
||||
line.SpellNameText = spellNameText
|
||||
line.RadioGroup = radioGroup
|
||||
line.ExportButton = exportButton
|
||||
line.DurationEntry = durationEntry
|
||||
line.CooldownEntry = cooldownEntry
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
--create spell lines with the scroll
|
||||
for i = 1, scrollLines do
|
||||
spellScroll:CreateLine(scrollCreateline)
|
||||
end
|
||||
|
||||
function spellScroll:RefreshScroll()
|
||||
--create a list of spells from the spell book
|
||||
---@type savedcooldowninfoscrolldata[]
|
||||
local indexedSpells = {}
|
||||
for spellId, savedCooldownInfo in pairs(thisClassSavedTable) do
|
||||
---@cast savedCooldownInfo savedcooldowninfo
|
||||
local spellInfo = C_Spell.GetSpellInfo(spellId)
|
||||
if (spellInfo) then
|
||||
indexedSpells[#indexedSpells+1] = {
|
||||
spellId = spellId,
|
||||
type = savedCooldownInfo.type == true and 1 or savedCooldownInfo.type,
|
||||
spellName = spellInfo.name,
|
||||
savedCooldownInfo = savedCooldownInfo
|
||||
}
|
||||
end
|
||||
end
|
||||
table.sort(indexedSpells, function(a, b) return a.spellName < b.spellName end) --sort by name
|
||||
spellScroll:SetData(indexedSpells)
|
||||
spellScroll:Refresh()
|
||||
end
|
||||
end
|
||||
|
||||
DetailsSpellCategoryFrame.SpellScroll:RefreshScroll()
|
||||
DetailsSpellCategoryFrame:Show()
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user