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:
2026-05-25 10:59:28 +02:00
parent 0b0a5004eb
commit 5bb7be4968
421 changed files with 7 additions and 0 deletions
+409
View File
@@ -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
+423
View File
@@ -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>
+716
View File
@@ -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 posio 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
+40
View File
@@ -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>
+668
View File
@@ -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
+349
View File
@@ -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
+253
View File
@@ -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
+289
View File
@@ -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
+153
View File
@@ -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
+221
View File
@@ -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
+911
View File
@@ -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
+159
View File
@@ -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
+65
View File
@@ -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
+946
View File
@@ -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
--ento 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
+84
View File
@@ -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
--
+455
View File
@@ -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
+145
View File
@@ -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
+907
View File
@@ -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
+148
View File
@@ -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
+189
View File
@@ -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
+464
View File
@@ -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
+451
View File
@@ -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
+6
View File
@@ -0,0 +1,6 @@
local Details = Details
local addonName, Details222 = ...
---@type detailsframework
local detailsFramework = DetailsFramework
local _
+86
View File
@@ -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
+951
View File
@@ -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
+194
View File
@@ -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)
+214
View File
@@ -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
+322
View File
@@ -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")
+628
View File
@@ -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