vrtc / chorus (public) (License: CC0) (since 2023-08-12) (hash sha1)
World of Warcraft add-on stub. The overall goal is to create a specialized raid frame.
List of commits:
Subject Hash Author Date (UTC)
fix!: Update party frame to unprotected strategy 470935eb589f7ab2fa77ae1335a194420e597340 Vladyslav Bondarenko 2023-08-30 22:52:34
fix!: Render solo status bar textures correctly 22d89fffabad69df1e7dcf078805e3ff341c5023 Vladyslav Bondarenko 2023-08-30 19:14:13
fix!: Restore solo frame context menu popup 0cc446f33351c8998d2359a42000f84da19defcd Vladyslav Bondarenko 2023-08-29 22:43:22
feat!: Update unit frame layout framework 1af4c0bd53a474483d60425f2a4e40250367ecf1 Vladyslav Bondarenko 2023-08-29 21:20:40
feat: Classify rare or elite units dd2c1f490c08a75774be085b318ebcd1b2788a2b Vladyslav Bondarenko 2023-08-29 21:18:49
feat(build): Remove cgitrc 1e6b59264abab70e1f2fa9ae494c74d2606c060f Vladyslav Bondarenko 2023-08-29 14:37:03
feat(build): Add cgitrc 7288f0336e36010fb92bf60479fdca3a0082ecd1 Vladyslav Bondarenko 2023-08-29 14:14:24
feat(build): Add cgitrc ea45afc0375774c2fe6bb0a3237cfd1817529ff0 Vladyslav Bondarenko 2023-08-29 14:14:24
feat(test)!: Toggle debug mode at runtime 23c37e3ab2eaf924f41fe51adc1e54f525222a8b Vladyslav Bondarenko 2023-08-29 03:41:55
fix: Aura tooltip is always opaque 1f7ba009c71796093b8cfa63cb38d918b9696c79 Vladyslav Bondarenko 2023-08-29 01:31:40
fix: Adjust aura tooltip toggle button layout fc72d10b09f44ef9ba6f2f93413a20def40c2d4a Vladyslav Bondarenko 2023-08-29 01:30:27
feat!: Add role widget 0ac8cda6522056c8adb527ba2f144229f251f69e Vladyslav Bondarenko 2023-08-29 00:59:14
fix: Only show power bar when appropriate 5313d1bfbf676c88b5c2a0a56fbea88549633b7b Vladyslav Bondarenko 2023-08-28 22:46:36
feat!: Toggle detailed unit aura tooltip in combat 460c622c04a8b0fa503c2a5d45313b667809b95c Vladyslav Bondarenko 2023-08-28 19:26:25
feat!: Add detailed buff and debuff popup 1ff7bcff470419c7fa40c6b946e441867dda4825 Vladyslav Bondarenko 2023-08-27 20:42:05
fix!: Further specialize every aura frame 1ec8385427bda76ea40840e68da7f5948d5af9bd Vladyslav Bondarenko 2023-08-27 18:40:55
feat: Add combat status indicator to unit buttons 38e469e01eb581693fd22f69b0739ea308d94966 Vladyslav Bondarenko 2023-08-27 16:35:38
fix!: Show raid targeting icon correctly ae5a1c5541d4bf137ea287671eb1f558422b26f4 Vladyslav Bondarenko 2023-08-27 15:24:57
fix!: Disable test mockup for release 0.4 54113d6a7f222ea2f382a1d5382c8e941e7537b1 Vladyslav Bondarenko 2023-08-26 22:42:33
fix: Apply source formatting before 0.4 cb1c5f11b553aba43751091c8746abdf261806e6 Vladyslav Bondarenko 2023-08-26 22:36:57
Commit 470935eb589f7ab2fa77ae1335a194420e597340 - fix!: Update party frame to unprotected strategy
Previously all party frames were explicitly protected (descended from
`SecureUnitButtonTemplate`). This resulted in some difficulties. Update
party frame to use newer visual layout and underlying frames that are
not explicitly protected.

The reliance on unprotected frames is experimental. Serious performance
issues were discovered with playtesting. The exact reason is unknown.
Possible reasons include.

1. `function SecureButton_GetUnit` implementation.

This commit adds failsafes to improve robustness and allow `function
SecureButton_GetUnit` and other related methods to access the unit
property more readily. This results in more obvious complexity, more
code, and value duplication at runtime. The value duplication may result
in incorrect representation of game state at runtime. However, the
current implementation completely assumes that the unit properties are
immutable after initialization. Therefore, it is robust enough at the
moment, since the whole premise of the add-on is to not require
configuration by the user.

2. Update processors.

Range approximation, target-of-target (TOT) updates, or `function
UnitInRange` transparency implementations are expensive by their nature.
Some corners need to be cut. This commit __did not__ delve deeper into
this particular issue.

3. Unit watches.

`function RegisterUnitWatch` is arcane. It's purpose is to toggle frame
visibility based on unit's existance. However, it is expensive
performance wise at runtime. Additionally in most cases it's purpose can
be fulfilled using the usual event processors, so long as the
implementation does not require explicitly protected frames (frames
executed in restricted environment).

This commit implicitly tries to fix performance issues with points 1 and
3. More playtesting is required.
Author: Vladyslav Bondarenko
Author date (UTC): 2023-08-30 22:52
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2023-08-30 22:52
Parent(s): 22d89fffabad69df1e7dcf078805e3ff341c5023
Signer:
Signing key: EFF9624877D25D02
Signing status: E
Tree: 47ea67eaa2f0f84ecfe181e5ff6376abe859cd07
File Lines added Lines deleted
src/Chorus.xml 4 0
src/ChorusAuraFrameTemplate.xml 59 0
src/ChorusLargeUnitFrameTemplate.xml 17 33
src/ChorusPartyFrame.lua 43 6
src/ChorusPartyFrame.xml 53 120
src/ChorusSmallUnitFrameTemplate.xml 81 0
src/ChorusTinyUnitFrameTemplate.xml 26 0
src/ChorusUnitButtonTemplate.lua 1 127
src/ChorusUnitFrameTemplate.lua 239 0
src/ChorusUnitFrameTemplate.xml 28 0
src/ChorusUnitGroupRoleFrameTemplate.lua 2 0
File src/Chorus.xml changed (mode: 100644) (index 6305201..94fb0cf)
21 21 <Include file="ChorusUnitAffectingCombatFrameTemplate.xml"/> <Include file="ChorusUnitAffectingCombatFrameTemplate.xml"/>
22 22 <Include file="ChorusUnitGroupRoleFrameTemplate.xml"/> <Include file="ChorusUnitGroupRoleFrameTemplate.xml"/>
23 23 <Include file="ChorusUnitButtonTemplate.xml"/> <Include file="ChorusUnitButtonTemplate.xml"/>
24 <Include file="ChorusUnitFrameTemplate.xml"/>
24 25 <Include file="ChorusHugeUnitFrameTemplate.xml"/> <Include file="ChorusHugeUnitFrameTemplate.xml"/>
26 <Include file="ChorusLargeUnitFrameTemplate.xml"/>
27 <Include file="ChorusSmallUnitFrameTemplate.xml"/>
28 <Include file="ChorusTinyUnitFrameTemplate.xml"/>
25 29 <Include file="ChorusPartyFrame.xml"/> <Include file="ChorusPartyFrame.xml"/>
26 30 <Include file="ChorusRaidFrame.xml"/> <Include file="ChorusRaidFrame.xml"/>
27 31 <Include file="ChorusFrame.xml"/> <Include file="ChorusFrame.xml"/>
File src/ChorusAuraFrameTemplate.xml changed (mode: 100644) (index dfaea8e..7a78e48)
71 71 </Frame> </Frame>
72 72 </Frames> </Frames>
73 73 </Frame> </Frame>
74 <Frame name="ChorusSmallAuraFrameTemplate" inherits="ChorusAuraFrameTemplate" virtual="true">
75 <Size>
76 <AbsDimension x="120" y="30"/>
77 </Size>
78 <Frames>
79 <Frame name="$parentAuraButton1" inherits="ChorusAuraButtonTemplate" id="1">
80 <Anchors>
81 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
82 <Offset>
83 <AbsDimension x="0" y="0"/>
84 </Offset>
85 </Anchor>
86 </Anchors>
87 </Frame>
88 <Frame name="$parentAuraButton2" inherits="ChorusAuraButtonTemplate" id="2">
89 <Anchors>
90 <Anchor point="BOTTOMLEFT" relativeTo="$parentAuraButton1" relativePoint="BOTTOMRIGHT">
91 <Offset>
92 <AbsDimension x="0" y="0"/>
93 </Offset>
94 </Anchor>
95 </Anchors>
96 </Frame>
97 <Frame name="$parentAuraButton3" inherits="ChorusAuraButtonTemplate" id="3">
98 <Anchors>
99 <Anchor point="BOTTOMLEFT" relativeTo="$parentAuraButton2" relativePoint="BOTTOMRIGHT">
100 <Offset>
101 <AbsDimension x="0" y="0"/>
102 </Offset>
103 </Anchor>
104 </Anchors>
105 </Frame>
106 <Frame name="$parentAuraButton4" inherits="ChorusAuraButtonTemplate" id="4">
107 <Anchors>
108 <Anchor point="BOTTOMLEFT" relativeTo="$parentAuraButton3" relativePoint="BOTTOMRIGHT">
109 <Offset>
110 <AbsDimension x="0" y="0"/>
111 </Offset>
112 </Anchor>
113 </Anchors>
114 </Frame>
115 </Frames>
116 </Frame>
117 <Frame name="ChorusTinyAuraFrameTemplate" inherits="ChorusAuraFrameTemplate" virtual="true">
118 <Size>
119 <AbsDimension x="30" y="30"/>
120 </Size>
121 <Frames>
122 <Frame name="$parentAuraButton1" inherits="ChorusAuraButtonTemplate" id="1">
123 <Anchors>
124 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
125 <Offset>
126 <AbsDimension x="0" y="0"/>
127 </Offset>
128 </Anchor>
129 </Anchors>
130 </Frame>
131 </Frames>
132 </Frame>
74 133 </Ui> </Ui>
File src/ChorusLargeUnitFrameTemplate.xml copied from file src/ChorusHugeUnitFrameTemplate.xml (similarity 74%) (mode: 100644) (index 2f83523..c43da34)
1 1 <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
2 2 <Ui xmlns="http://www.blizzard.com/wow/ui/"> <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 <Frame name="ChorusHugeUnitFrameTemplate" virtual="true">
3 <Frame name="ChorusLargeUnitFrameTemplate" inherits="ChorusUnitFrameTemplate" virtual="true">
4 4 <Size> <Size>
5 <AbsDimension x="200" y="150"/>
5 <AbsDimension x="160" y="100"/>
6 6 </Size> </Size>
7 7 <Frames> <Frames>
8 8 <!-- Clickable area. --> <!-- Clickable area. -->
9 9 <Button name="$parentSecureUnitButton" inherits="ChorusUnitButtonTemplate" setAllPoints="true"> <Button name="$parentSecureUnitButton" inherits="ChorusUnitButtonTemplate" setAllPoints="true">
10 <Size>
11 <AbsDimension x="160" y="60"/>
12 </Size>
10 13 <Anchors> <Anchors>
11 <Anchor point="TOPRIGHT">
14 <Anchor point="TOPLEFT">
12 15 <Offset x="0" y="0"/> <Offset x="0" y="0"/>
13 16 </Anchor> </Anchor>
14 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
15 <Offset x="0" y="-80"/>
16 </Anchor>
17 17 </Anchors> </Anchors>
18 18 </Button> </Button>
19 19 <!-- Header --> <!-- Header -->
 
103 103 </Anchors> </Anchors>
104 104 </Frame> </Frame>
105 105 <!-- Footer --> <!-- Footer -->
106 <StatusBar name="$parentCastFrame" inherits="ChorusCastFrameTemplate">
106 <Frame name="$parentBuffFrame" inherits="ChorusTinyAuraFrameTemplate">
107 107 <Anchors> <Anchors>
108 <Anchor point="TOPRIGHT">
109 <Offset x="0" y="-72"/>
110 </Anchor>
111 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
112 <Offset x="0" y="-88"/>
113 </Anchor>
114 </Anchors>
115 </StatusBar>
116 <Frame name="$parentBuffFrame" inherits="ChorusLargeAuraFrameTemplate">
117 <Anchors>
118 <Anchor point="TOPRIGHT">
119 <Offset x="0" y="-90"/>
120 </Anchor>
121 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
122 <Offset x="0" y="-120"/>
108 <Anchor point="BOTTOMRIGHT">
109 <Offset x="-10" y="0"/>
123 110 </Anchor> </Anchor>
124 111 </Anchors> </Anchors>
125 112 <Attributes> <Attributes>
126 113 <Attribute name="filter" type="string" value="HELPFUL"/> <Attribute name="filter" type="string" value="HELPFUL"/>
127 114 </Attributes> </Attributes>
128 115 </Frame> </Frame>
129 <Frame name="$parentDebuffFrame" inherits="ChorusLargeAuraFrameTemplate">
116 <Frame name="$parentDebuffFrame" inherits="ChorusSmallAuraFrameTemplate">
130 117 <Anchors> <Anchors>
131 <Anchor point="TOPRIGHT">
132 <Offset x="0" y="-120"/>
133 </Anchor>
134 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
135 <Offset x="0" y="-150"/>
118 <Anchor point="BOTTOMLEFT">
119 <Offset x="0" y="0"/>
136 120 </Anchor> </Anchor>
137 121 </Anchors> </Anchors>
138 122 <Attributes> <Attributes>
 
147 131 </Anchors> </Anchors>
148 132 </Frame> </Frame>
149 133 <Button name="$parentAuraTooltipToggleButton" inherits="ChorusAuraTooltipFrameToggleButtonTemplate"> <Button name="$parentAuraTooltipToggleButton" inherits="ChorusAuraTooltipFrameToggleButtonTemplate">
134 <Size>
135 <AbsDimension x="10" y="30"/>
136 </Size>
150 137 <Anchors> <Anchors>
151 <Anchor point="TOPRIGHT">
152 <Offset x="0" y="-90"/>
153 </Anchor>
154 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPRIGHT">
155 <Offset x="-12" y="-150"/>
138 <Anchor point="BOTTOMRIGHT">
139 <Offset x="0" y="0"/>
156 140 </Anchor> </Anchor>
157 141 </Anchors> </Anchors>
158 142 </Button> </Button>
File src/ChorusPartyFrame.lua changed (mode: 100644) (index 466b3c4..0a46010)
... ... local function partyFrameEventProcessor(self)
16 16 end end
17 17 end end
18 18
19 local function mapUnitDesignation(unitDesignation)
20 assert(unitDesignation ~= nil)
21
22 if 'player' == unitDesignation then
23 return 'player', 'pet', 'target'
24 elseif 'party1' == unitDesignation then
25 return 'party1', 'partypet1', 'party1target'
26 elseif 'party2' == unitDesignation then
27 return 'party2', 'partypet2', 'party2target'
28 elseif 'party3' == unitDesignation then
29 return 'party3', 'partypet3', 'party3target'
30 elseif 'party4' == unitDesignation then
31 return 'party4', 'partypet4', 'party4target'
32 else
33 error('unexpected value: expect at most four party members excluding player')
34 end
35 end
36
37 local function initPartyMemberFrame(partyMemberFrame)
38 assert(partyMemberFrame ~= nil)
39
40 local n = partyMemberFrame:GetName()
41 assert(n ~= nil)
42
43 local u = partyMemberFrame:GetAttribute('unit')
44 local _, upet, utarget = mapUnitDesignation(u)
45
46 local unitFrame = _G[n .. 'UnitFrame']
47 local petFrame = _G[n .. 'PetFrame']
48 local targetFrame = _G[n .. 'TargetFrame']
49 assert(unitFrame ~= nil)
50 assert(petFrame ~= nil)
51 assert(targetFrame ~= nil)
52
53 unitFrame:SetAttribute('unit', u)
54 petFrame:SetAttribute('unit', upet)
55 targetFrame:SetAttribute('unit', utarget)
56 end
57
19 58 local function partyFrameMain(self) local function partyFrameMain(self)
20 59 assert(self ~= nil) assert(self ~= nil)
21 60
22 61 local t = {self:GetChildren()} local t = {self:GetChildren()}
23 62 local i = 0 local i = 0
63 assert(5 == #t, 'invalid state: must be exactly five party member frames')
24 64 while (i < #t) do while (i < #t) do
25 65 i = i + 1 i = i + 1
26 local unitButton = t[i]
27 assert(unitButton ~= nil)
66 local partyMemberFrame = t[i]
67 assert(partyMemberFrame ~= nil)
28 68
29 local healthFrame = unitButton.healthFrame or _G[unitButton:GetName() .. 'HealthFrame']
30 assert(healthFrame ~= nil)
31 --[[ Color every health bar with the unit class color. ]]--
32 healthFrame.strategy = 'UnitClass'
69 initPartyMemberFrame(partyMemberFrame)
33 70 end end
34 71
35 72 self:SetScript('OnEvent', partyFrameEventProcessor) self:SetScript('OnEvent', partyFrameEventProcessor)
File src/ChorusPartyFrame.xml changed (mode: 100644) (index 39cbb7e..5cd1563)
1 1 <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
2 2 <Ui xmlns="http://www.blizzard.com/wow/ui/"> <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 3 <Script file="ChorusPartyFrame.lua"/> <Script file="ChorusPartyFrame.lua"/>
4 <Include file="ChorusUnitButtonTemplate.xml"/>
4 <Frame name="ChorusPartyUnitFrameTemplate" inherits="ChorusLargeUnitFrameTemplate,ChorusMemberUnitFrameTemplate" virtual="true"/>
5 <Frame name="ChorusPartyPetUnitFrameTemplate" inherits="ChorusSmallUnitFrameTemplate" virtual="true"/>
6 <Frame name="ChorusPartyTOTUnitFrameTemplate" inherits="ChorusTinyUnitFrameTemplate,ChorusTOTUnitFrameTemplate" virtual="true"/>
7 <Frame name="ChorusPartyMemberFrameTemplate" protected="false" virtual="true">
8 <Size>
9 <AbsDimension x="180" y="150"/>
10 </Size>
11 <Frames>
12 <Frame name="$parentUnitFrame" inherits="ChorusPartyUnitFrameTemplate">
13 <Anchors>
14 <Anchor point="CENTER">
15 <Offset x="0" y="0"/>
16 </Anchor>
17 </Anchors>
18 </Frame>
19 <Frame name="$parentTargetFrame" inherits="ChorusPartyTOTUnitFrameTemplate">
20 <Anchors>
21 <Anchor point="BOTTOMLEFT" relativeTo="$parentUnitFrame" relativePoint="TOPLEFT">
22 <Offset x="48" y="4"/>
23 </Anchor>
24 </Anchors>
25 </Frame>
26 <Frame name="$parentPetFrame" inherits="ChorusPartyPetUnitFrameTemplate">
27 <Anchors>
28 <Anchor point="TOPLEFT" relativeTo="$parentUnitFrame" relativePoint="BOTTOMLEFT">
29 <Offset x="32" y="-12"/>
30 </Anchor>
31 </Anchors>
32 </Frame>
33 </Frames>
34 <Attributes>
35 <Attribute name="unit" type="string" value="none"/>
36 </Attributes>
37 </Frame>
5 38 <Frame name="ChorusPartyFrame"> <Frame name="ChorusPartyFrame">
6 39 <Size> <Size>
7 40 <AbsDimension x="768" y="128"/> <AbsDimension x="768" y="128"/>
 
15 48 </Anchor> </Anchor>
16 49 </Anchors> </Anchors>
17 50 <Frames> <Frames>
18 <Button name="$parentPlayerButton" inherits="ChorusLargeUnitButtonTemplate" id="1">
51 <Frame name="ChorusPartyMemberFrame1" inherits="ChorusPartyMemberFrameTemplate" id="1">
19 52 <Anchors> <Anchors>
20 53 <Anchor point="BOTTOMLEFT"> <Anchor point="BOTTOMLEFT">
21 <Offset x="0" y="32"/>
54 <Offset x="0" y="0"/>
22 55 </Anchor> </Anchor>
23 56 </Anchors> </Anchors>
24 57 <Attributes> <Attributes>
25 58 <Attribute name="unit" type="string" value="player"/> <Attribute name="unit" type="string" value="player"/>
26 59 </Attributes> </Attributes>
27 </Button>
28 <Button name="$parentParty1Button" inherits="ChorusLargeUnitButtonTemplate" id="2">
60 </Frame>
61 <Frame name="ChorusPartyMemberFrame2" inherits="ChorusPartyMemberFrameTemplate" id="2">
29 62 <Anchors> <Anchors>
30 <Anchor point="BOTTOMLEFT">
31 <Offset x="154" y="32"/>
63 <Anchor point="BOTTOMLEFT" relativeTo="ChorusPartyMemberFrame1" relativePoint="BOTTOMRIGHT">
64 <Offset x="0" y="0"/>
32 65 </Anchor> </Anchor>
33 66 </Anchors> </Anchors>
34 67 <Attributes> <Attributes>
35 68 <Attribute name="unit" type="string" value="party1"/> <Attribute name="unit" type="string" value="party1"/>
36 69 </Attributes> </Attributes>
37 </Button>
38 <Button name="$parentParty2Button" inherits="ChorusLargeUnitButtonTemplate" id="3">
70 </Frame>
71 <Frame name="ChorusPartyMemberFrame3" inherits="ChorusPartyMemberFrameTemplate" id="3">
39 72 <Anchors> <Anchors>
40 <Anchor point="BOTTOMLEFT">
41 <Offset x="308" y="32"/>
73 <Anchor point="BOTTOMLEFT" relativeTo="ChorusPartyMemberFrame2" relativePoint="BOTTOMRIGHT">
74 <Offset x="0" y="0"/>
42 75 </Anchor> </Anchor>
43 76 </Anchors> </Anchors>
44 77 <Attributes> <Attributes>
45 78 <Attribute name="unit" type="string" value="party2"/> <Attribute name="unit" type="string" value="party2"/>
46 79 </Attributes> </Attributes>
47 </Button>
48 <Button name="$parentParty3Button" inherits="ChorusLargeUnitButtonTemplate" id="4">
80 </Frame>
81 <Frame name="ChorusPartyMemberFrame4" inherits="ChorusPartyMemberFrameTemplate" id="4">
49 82 <Anchors> <Anchors>
50 <Anchor point="BOTTOMLEFT">
51 <Offset x="462" y="32"/>
83 <Anchor point="BOTTOMLEFT" relativeTo="ChorusPartyMemberFrame3" relativePoint="BOTTOMRIGHT">
84 <Offset x="0" y="0"/>
52 85 </Anchor> </Anchor>
53 86 </Anchors> </Anchors>
54 87 <Attributes> <Attributes>
55 88 <Attribute name="unit" type="string" value="party3"/> <Attribute name="unit" type="string" value="party3"/>
56 89 </Attributes> </Attributes>
57 </Button>
58 <Button name="$parentParty4Button" inherits="ChorusLargeUnitButtonTemplate" id="5">
90 </Frame>
91 <Frame name="ChorusPartyMemberFrame5" inherits="ChorusPartyMemberFrameTemplate" id="5">
59 92 <Anchors> <Anchors>
60 <Anchor point="BOTTOMLEFT">
61 <Offset x="616" y="32"/>
62 </Anchor>
63 </Anchors>
64 <Attributes>
65 <Attribute name="unit" type="string" value="party4"/>
66 </Attributes>
67 </Button>
68 <Button name="$parentPlayerPetButton" inherits="ChorusSmallUnitButtonTemplate" id="6">
69 <Anchors>
70 <Anchor point="BOTTOMLEFT">
93 <Anchor point="BOTTOMLEFT" relativeTo="ChorusPartyMemberFrame4" relativePoint="BOTTOMRIGHT">
71 94 <Offset x="0" y="0"/> <Offset x="0" y="0"/>
72 95 </Anchor> </Anchor>
73 96 </Anchors> </Anchors>
74 97 <Attributes> <Attributes>
75 <Attribute name="unit" type="string" value="playerpet"/>
76 </Attributes>
77 </Button>
78 <Button name="$parentPartyPet1Button" inherits="ChorusSmallUnitButtonTemplate" id="7">
79 <Anchors>
80 <Anchor point="BOTTOMLEFT">
81 <Offset x="154" y="0"/>
82 </Anchor>
83 </Anchors>
84 <Attributes>
85 <Attribute name="unit" type="string" value="partypet1"/>
86 </Attributes>
87 </Button>
88 <Button name="$parentPartyPet2Button" inherits="ChorusSmallUnitButtonTemplate" id="8">
89 <Anchors>
90 <Anchor point="BOTTOMLEFT">
91 <Offset x="308" y="0"/>
92 </Anchor>
93 </Anchors>
94 <Attributes>
95 <Attribute name="unit" type="string" value="partypet2"/>
96 </Attributes>
97 </Button>
98 <Button name="$parentPartyPet3Button" inherits="ChorusSmallUnitButtonTemplate" id="9">
99 <Anchors>
100 <Anchor point="BOTTOMLEFT">
101 <Offset x="462" y="0"/>
102 </Anchor>
103 </Anchors>
104 <Attributes>
105 <Attribute name="unit" type="string" value="partypet3"/>
106 </Attributes>
107 </Button>
108 <Button name="$parentPartyPet4Button" inherits="ChorusSmallUnitButtonTemplate" id="10">
109 <Anchors>
110 <Anchor point="BOTTOMLEFT">
111 <Offset x="616" y="0"/>
112 </Anchor>
113 </Anchors>
114 <Attributes>
115 <Attribute name="unit" type="string" value="partypet4"/>
116 </Attributes>
117 </Button>
118 <Button name="$parentPlayerTargetButton" inherits="ChorusTinyUnitButtonTemplate" id="11">
119 <Anchors>
120 <Anchor point="BOTTOMLEFT">
121 <Offset x="0" y="128"/>
122 </Anchor>
123 </Anchors>
124 <Attributes>
125 <Attribute name="unit" type="string" value="playertarget"/>
126 </Attributes>
127 </Button>
128 <Button name="$parentParty1TargetButton" inherits="ChorusTinyUnitButtonTemplate" id="12">
129 <Anchors>
130 <Anchor point="BOTTOMLEFT">
131 <Offset x="154" y="128"/>
132 </Anchor>
133 </Anchors>
134 <Attributes>
135 <Attribute name="unit" type="string" value="party1target"/>
136 </Attributes>
137 </Button>
138 <Button name="$parentParty2TargetButton" inherits="ChorusTinyUnitButtonTemplate" id="13">
139 <Anchors>
140 <Anchor point="BOTTOMLEFT">
141 <Offset x="308" y="128"/>
142 </Anchor>
143 </Anchors>
144 <Attributes>
145 <Attribute name="unit" type="string" value="party2target"/>
146 </Attributes>
147 </Button>
148 <Button name="$parentParty3TargetButton" inherits="ChorusTinyUnitButtonTemplate" id="14">
149 <Anchors>
150 <Anchor point="BOTTOMLEFT">
151 <Offset x="462" y="128"/>
152 </Anchor>
153 </Anchors>
154 <Attributes>
155 <Attribute name="unit" type="string" value="party3target"/>
156 </Attributes>
157 </Button>
158 <Button name="$parentParty4TargetButton" inherits="ChorusTinyUnitButtonTemplate" id="15">
159 <Anchors>
160 <Anchor point="BOTTOMLEFT">
161 <Offset x="616" y="128"/>
162 </Anchor>
163 </Anchors>
164 <Attributes>
165 <Attribute name="unit" type="string" value="party4target"/>
98 <Attribute name="unit" type="string" value="party4"/>
166 99 </Attributes> </Attributes>
167 </Button>
100 </Frame>
168 101 </Frames> </Frames>
169 102 <Scripts> <Scripts>
170 103 <OnLoad>Chorus.partyFrameMain(self);</OnLoad> <OnLoad>Chorus.partyFrameMain(self);</OnLoad>
File src/ChorusSmallUnitFrameTemplate.xml added (mode: 100644) (index 0000000..7149f95)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 <Frame name="ChorusSmallUnitFrameTemplate" virtual="true">
4 <Size>
5 <AbsDimension x="96" y="32"/>
6 </Size>
7 <Frames>
8 <!-- Clickable area. -->
9 <Button name="$parentSecureUnitButton" inherits="ChorusUnitButtonTemplate" setAllPoints="true"/>
10 <!-- Header -->
11 <Frame name="$parentUnitNameFrame" inherits="ChorusUnitNameFrameTemplate">
12 <Anchors>
13 <Anchor point="TOPLEFT">
14 <Offset x="0" y="0"/>
15 </Anchor>
16 </Anchors>
17 </Frame>
18 <Frame name="$parentUnitAffectingCombatFrame" inherits="ChorusUnitAffectingCombatFrameTemplate">
19 <Anchors>
20 <Anchor point="TOPRIGHT">
21 <Offset x="0" y="0"/>
22 </Anchor>
23 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPRIGHT">
24 <Offset x="-16" y="-16"/>
25 </Anchor>
26 </Anchors>
27 </Frame>
28 <Frame name="$parentRaidTargetIconFrame" inherits="ChorusRaidTargetIconFrameTemplate">
29 <Anchors>
30 <Anchor point="TOP">
31 <Offset x="0" y="4"/>
32 </Anchor>
33 <Anchor point="CENTER">
34 <Offset x="0" y="4"/>
35 </Anchor>
36 </Anchors>
37 </Frame>
38 <Frame name="$parentUnitGroupRoleFrame" inherits="ChorusUnitGroupRoleFrameTemplate">
39 <Anchors>
40 <Anchor point="TOPRIGHT">
41 <Offset x="-16" y="0"/>
42 </Anchor>
43 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="TOPRIGHT">
44 <Offset x="-32" y="-16"/>
45 </Anchor>
46 </Anchors>
47 </Frame>
48 <!-- Main -->
49 <StatusBar name="$parentHealthFrame" inherits="ChorusSmallHealthFrameTemplate">
50 <Anchors>
51 <Anchor point="TOPRIGHT">
52 <Offset x="0" y="0"/>
53 </Anchor>
54 <Anchor point="BOTTOMLEFT">
55 <Offset x="0" y="6"/>
56 </Anchor>
57 </Anchors>
58 </StatusBar>
59 <StatusBar name="$parentPowerFrame" inherits="ChorusTinyPowerFrameTemplate">
60 <Anchors>
61 <Anchor point="TOPRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT">
62 <Offset x="0" y="6"/>
63 </Anchor>
64 <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
65 <Offset x="0" y="0"/>
66 </Anchor>
67 </Anchors>
68 </StatusBar>
69 <Frame name="$parentDebuffFrame" inherits="ChorusTinyAuraFrameTemplate">
70 <Anchors>
71 <Anchor point="BOTTOMRIGHT">
72 <Offset x="0" y="0"/>
73 </Anchor>
74 </Anchors>
75 <Attributes>
76 <Attribute name="filter" type="string" value="HARMFUL RAID"/>
77 </Attributes>
78 </Frame>
79 </Frames>
80 </Frame>
81 </Ui>
File src/ChorusTinyUnitFrameTemplate.xml added (mode: 100644) (index 0000000..538b937)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 <Frame name="ChorusTinyUnitFrameTemplate" virtual="true">
4 <Size>
5 <AbsDimension x="64" y="16"/>
6 </Size>
7 <Frames>
8 <!-- Clickable area. -->
9 <Button name="$parentSecureUnitButton" inherits="ChorusUnitButtonTemplate" setAllPoints="true"/>
10 <!-- Header -->
11 <Frame name="$parentUnitNameFrame" inherits="ChorusUnitNameFrameTemplate" setAllPoints="true"/>
12 <Frame name="$parentRaidTargetIconFrame" inherits="ChorusRaidTargetIconFrameTemplate">
13 <Anchors>
14 <Anchor point="TOP">
15 <Offset x="0" y="4"/>
16 </Anchor>
17 <Anchor point="CENTER">
18 <Offset x="0" y="4"/>
19 </Anchor>
20 </Anchors>
21 </Frame>
22 <!-- Main -->
23 <StatusBar name="$parentHealthFrame" inherits="ChorusTinyHealthFrameTemplate" setAllPoints="true"/>
24 </Frames>
25 </Frame>
26 </Ui>
File src/ChorusUnitButtonTemplate.lua changed (mode: 100644) (index 9cd7d04..92320df)
... ... local GameTooltipTextLeft1 = GameTooltipTextLeft1
5 5
6 6 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor
7 7 local GameTooltip_UnitColor = GameTooltip_UnitColor local GameTooltip_UnitColor = GameTooltip_UnitColor
8 local RegisterUnitWatch = Chorus.test.RegisterUnitWatch or RegisterUnitWatch
9 8 local SecureButton_GetUnit = Chorus.test.SecureButton_GetUnit or SecureButton_GetUnit local SecureButton_GetUnit = Chorus.test.SecureButton_GetUnit or SecureButton_GetUnit
10 9
11 local UnitExists = Chorus.test.UnitExists or UnitExists
12 local UnitInParty = Chorus.test.UnitInParty or UnitInParty
13 local UnitInRaid = Chorus.test.UnitInRaid or UnitInRaid
14 local UnitInRange = Chorus.test.UnitInRange or UnitInRange
15 local UnitIsConnected = Chorus.test.UnitIsConnected or UnitIsConnected
16
17 10 --[[ TODO Add incoming healing bar. ]]-- --[[ TODO Add incoming healing bar. ]]--
18 11 --[[ TODO Add incoming resurrection indicator. ]]-- --[[ TODO Add incoming resurrection indicator. ]]--
19 --[[ FIXME Raid targeting icon state is incorrect when player target changes. ]]--
12 --[[ TODO Add menu popup for all unit frames ]]--
20 13
21 14 local function unitButtonLeaveProcessor() local function unitButtonLeaveProcessor()
22 15 assert(GameTooltip ~= nil) assert(GameTooltip ~= nil)
 
... ... local function unitButtonEnterProcessor(unitButton)
36 29 end end
37 30 end end
38 31
39 --[[ Targets of raid or party members or targets of targets (TOT) do not update
40 automatically. The add-on has to poll for it and update the frames
41 explicitly. There is no event trigger to do this natively. ]]--
42 local function unitButtonTOTUpdate(self)
43 assert(self ~= nil)
44
45 local n = self:GetName()
46 assert(n ~= nil)
47
48 local u = self:GetAttribute('unit')
49
50 if not u or not UnitExists(u) or not UnitIsConnected(u) then
51 return
52 end
53
54 local unitNameFrame = self.unitNameFrame or _G[n .. 'UnitNameFrame']
55 if unitNameFrame then
56 self.unitNameFrame = unitNameFrame
57 local callback0 = unitNameFrame:GetScript('OnEvent')
58 callback0(unitNameFrame, 'UNIT_NAME_UPDATE', u)
59 end
60
61 local healthFrame = self.healthFrame or _G[n .. 'HealthFrame']
62 if healthFrame then
63 self.healthFrame = healthFrame
64 local callback1 = healthFrame:GetScript('OnEvent')
65 callback1(healthFrame, 'UNIT_HEALTH', u)
66 end
67 end
68
69 local function unitButtonUnitInRangeUpdate(unitButton)
70 local u = unitButton:GetAttribute('unit')
71 if not u then
72 return
73 end
74
75 local a = 1
76 if UnitExists(u) and UnitIsConnected(u) and (UnitInRaid(u) or UnitInParty(u)) then
77 --[[ `function UnitInRange` only works for group members. ]]--
78 if not UnitInRange(u) then
79 a = 0.6
80 end
81 end
82
83 --[[ Only apply transparency to select subset of children or referenced
84 frames. Specifically exclude ChorusAuraTooltipFrame instances. ]]--
85
86 local healthFrame = unitButton.healthFrame or _G[unitButton:GetName() .. 'HealthFrame']
87 local powerFrame = unitButton.powerFrame or _G[unitButton:GetName() .. 'PowerFrame']
88 local buffFrame = unitButton.buffFrame or _G[unitButton:GetName() .. 'BuffFrame']
89 local debuffFrame = unitButton.debuffFrame or _G[unitButton:GetName() .. 'DebuffFrame']
90
91 local t = {healthFrame, powerFrame, buffFrame, debuffFrame}
92 local i = 0
93 while (i < #t) do
94 i = i + 1
95 local b = t[i]
96 if b then
97 b:SetAlpha(a)
98 end
99 end
100 end
101
102 local function unitButtonUnitInRangeUpdateProcessor(self)
103 --[[ Reduce update frequency to roughly 6 frames per second. ]]--
104 if self.lastUpdateInstance and 'number' == type(self.lastUpdateInstance) then
105 local now = GetTime()
106 if now - self.lastUpdateInstance > 0.1667 then
107 self.lastUpdateInstance = now
108 else
109 return
110 end
111 else
112 self.lastUpdateInstance = GetTime()
113 end
114
115 unitButtonUnitInRangeUpdate(self)
116 end
117
118 local function unitButtonTOTUpdateProcessor(self)
119 --[[ Reduce update frequency to roughly 6 frames per second. ]]--
120 if self.lastUpdateInstance and 'number' == type(self.lastUpdateInstance) then
121 local now = GetTime()
122 if now - self.lastUpdateInstance > 0.1667 then
123 self.lastUpdateInstance = now
124 else
125 return
126 end
127 else
128 self.lastUpdateInstance = GetTime()
129 end
130
131 unitButtonTOTUpdate(self)
132 unitButtonUnitInRangeUpdate(self)
133 end
134
135 32 function Chorus.unitButtonMain(self) function Chorus.unitButtonMain(self)
136 33 self:RegisterForClicks('AnyUp') self:RegisterForClicks('AnyUp')
137 34
138 --[[ Toggling frame visibility is a restricted action. Use feature that
139 was specifically provided by the environment to toggle unit button
140 visibility when the corresponding unit existance state changes. See
141 `FrameXML/SecureTemplates.lua`. ]]--
142 local useSecureTemplateMode = true
143 RegisterUnitWatch(self, useSecureTemplateMode)
144
145 35 --[[ Toggle game tooltip on mouseover. ]]-- --[[ Toggle game tooltip on mouseover. ]]--
146 36 self:SetScript('OnEnter', unitButtonEnterProcessor) self:SetScript('OnEnter', unitButtonEnterProcessor)
147 37 self:SetScript('OnLeave', unitButtonLeaveProcessor) self:SetScript('OnLeave', unitButtonLeaveProcessor)
148
149 --[[ Prefer hook to allow multiple update processors. Otherwise, new
150 assignments will be quietly ignored. ]]--
151
152 local u = self:GetAttribute('unit') or 'none'
153 assert(u ~= nil, self:GetName() .. ': invalid state: empty unit')
154
155 local isTOT = string.match(u, 'target') and string.len(u) > string.len('target')
156 if isTOT then
157 self:HookScript('OnUpdate', unitButtonTOTUpdateProcessor)
158 else
159 self:HookScript('OnUpdate', unitButtonUnitInRangeUpdateProcessor)
160 end
161
162 --[[ TODO Add menu popup for unit frames ]]--
163 --[[ TODO Add role indicator ]]--
164 38 end end
File src/ChorusUnitFrameTemplate.lua added (mode: 100644) (index 0000000..7c3bb5d)
1 local Chorus = Chorus
2
3 local UnitExists = Chorus.test.UnitExists or UnitExists
4 local UnitInParty = Chorus.test.UnitInParty or UnitInParty
5 local UnitInRaid = Chorus.test.UnitInRaid or UnitInRaid
6 local UnitInRange = Chorus.test.UnitInRange or UnitInRange
7 local UnitIsConnected = Chorus.test.UnitIsConnected or UnitIsConnected
8
9 --[[ Targets of raid or party members or targets of targets (TOT) do not update
10 automatically. The add-on has to poll for it and update the frames
11 explicitly. There is no event trigger to do this natively. ]]--
12 local function applyTOT(self)
13 assert(self ~= nil)
14
15 local n = self:GetName()
16 assert(n ~= nil)
17
18 local u = self:GetAttribute('unit')
19
20 if not u or not UnitExists(u) or not UnitIsConnected(u) then
21 return
22 end
23
24 local unitNameFrame = self.unitNameFrame
25 if unitNameFrame then
26 local callback0 = unitNameFrame:GetScript('OnEvent')
27 callback0(unitNameFrame, 'UNIT_NAME_UPDATE', u)
28 end
29
30 local healthFrame = self.healthFrame
31 if healthFrame then
32 local callback1 = healthFrame:GetScript('OnEvent')
33 callback1(healthFrame, 'UNIT_HEALTH', u)
34 end
35
36 local powerFrame = self.powerFrame
37 if powerFrame then
38 local callback2 = healthFrame:GetScript('OnEvent')
39 callback2(healthFrame, 'UNIT_POWER', u)
40 end
41 end
42
43 local function applyUnitInRange(self)
44 local u = self:GetAttribute('unit')
45 if not u then
46 return
47 end
48
49 local a = 1
50 if UnitExists(u) and UnitIsConnected(u) and (UnitInRaid(u) or UnitInParty(u)) then
51 --[[ `function UnitInRange` only works for group members. ]]--
52 if not UnitInRange(u) then
53 a = 0.6
54 end
55 else
56 self:SetAlpha(1)
57 return
58 end
59
60 --[[ Only apply transparency to select subset of children or referenced
61 frames. Specifically exclude ChorusAuraTooltipFrame instances. ]]--
62 --[[ FIXME Performance abyslmal, probably issue here . ]]--
63
64 local healthFrame = self.healthFrame
65 local powerFrame = self.powerFrame
66 local buffFrame = self.buffFrame
67 local debuffFrame = self.debuffFrame
68
69 if healthFrame then
70 healthFrame:SetAlpha(a)
71 end
72
73 if powerFrame then
74 powerFrame:SetAlpha(a)
75 end
76
77 if buffFrame then
78 buffFrame:SetAlpha(a)
79 end
80
81 if debuffFrame then
82 debuffFrame:SetAlpha(a)
83 end
84 end
85
86 function Chorus.unitFrameUnitInRangeUpdateProcessor(self)
87 --[[ Reduce update frequency to roughly 6 frames per second. ]]--
88 if self.lastUpdateInstance and 'number' == type(self.lastUpdateInstance) then
89 local now = GetTime()
90 if now - self.lastUpdateInstance > 0.1667 then
91 self.lastUpdateInstance = now
92 else
93 return
94 end
95 else
96 self.lastUpdateInstance = GetTime()
97 end
98
99 applyUnitInRange(self)
100 end
101
102 function Chorus.unitFrameTOTUpdateProcessor(self)
103 --[[ Reduce update frequency to roughly 6 frames per second. ]]--
104 if self.lastUpdateInstance and 'number' == type(self.lastUpdateInstance) then
105 local now = GetTime()
106 if now - self.lastUpdateInstance > 0.1667 then
107 self.lastUpdateInstance = now
108 else
109 return
110 end
111 else
112 self.lastUpdateInstance = GetTime()
113 end
114
115 applyTOT(self)
116 end
117
118 --[[
119 Inherit given property from self to all it's children once unprotected. Used at
120 initialization for performance considerations. This is a property access
121 optimization for children frame implementations. ]]
122 local function applyCascadeProperty(self, attributeName, value)
123 assert(self ~= nil)
124
125 assert(attributeName ~= nil)
126 assert('string' == type(attributeName))
127
128 value = value or self:GetAttribute(attributeName)
129 assert(value ~= nil)
130
131 local useparentKey = string.format('useparent-%s', attributeName)
132
133 local t = {self:GetChildren()}
134 local i = 0
135 while (i < #t) do
136 i = i + 1
137 local f = t[i]
138 if f then
139 local superFlag = f:GetAttribute(useparentKey) or f:GetAttribute('useparent*')
140 if superFlag then
141 f:SetAttribute(attributeName, value)
142 end
143 end
144 end
145 end
146
147 --[[
148 Inherit unit property from self to all it's children every time the property is
149 changed in a protected manner. This is a robustness feature used dynamically at
150 runtime, to make sure the frame behaves as expected even in somewhat unforseen
151 configurations. This is part of a performance optimization aspect for property
152 access. ]]
153 local function applySecureInheritance(self, secureHandler)
154 assert(self ~= nil)
155
156 local n = self:GetName()
157 assert(n ~= nil)
158
159 secureHandler = secureHandler or _G[n .. 'SecureHandlerAttributeFrame']
160 assert(secureHandler ~= nil)
161
162 secureHandler:WrapScript(self, 'OnAttributeChanged', [=[
163 print('protected', self:GetName(), name, value)
164 if not name then
165 return
166 end
167 if 'unit' ~= name then
168 return
169 end
170 local t = self:GetChildList(newtable())
171 local i = 0
172 local useparentKey = string.format('useparent-%s', name)
173 while (i < #t) do
174 i = i + 1
175 local f = t[i]
176 if f and (f:GetAttribute(useparentKey) or f:GetAttribute('useparent*')) then
177 f:SetAttribute(name, value)
178 print('protected', f:GetName(), name, f:GetAttribute(name))
179 end
180 end
181 ]=])
182 end
183
184 local function attributeProcessor(self, name, value)
185 assert(self ~= nil)
186
187 if 'unit' == name then
188 applyCascadeProperty(self, name, value)
189 end
190 end
191
192 local function unitFrameMain(self)
193 assert(self ~= nil)
194
195 local n = self:GetName()
196 assert(n ~= nil)
197
198 local secureHandler = _G[n .. 'SecureHandlerAttributeFrame']
199 assert(secureHandler ~= nil)
200
201 local _, explicitlySecureFlag = self:IsProtected()
202 if explicitlySecureFlag then
203 applySecureInheritance(self, secureHandler)
204 end
205
206 --[[ Initialize frames. Does not work in restricted environment. Never
207 rely on this at runtime. ]]--
208
209 applyCascadeProperty(self, 'unit')
210 self:SetScript('OnAttributeChanged', attributeProcessor)
211
212 local unitNameFrame = _G[self:GetName() .. 'UnitNameFrame']
213 self.unitNameFrame = unitNameFrame
214 local healthFrame = _G[self:GetName() .. 'HealthFrame']
215 self.healthFrame = healthFrame
216 local powerFrame = _G[self:GetName() .. 'PowerFrame']
217 self.powerFrame = powerFrame
218 local buffFrame = _G[self:GetName() .. 'BuffFrame']
219 self.buffFrame = buffFrame
220 local debuffFrame = _G[self:GetName() .. 'DebuffFrame']
221 self.debuffFrame = debuffFrame
222 end
223
224 local function unitMemberFrameMain(self, ...)
225 unitFrameMain(self, ...)
226
227 local healthFrame = self.healthFrame
228 if healthFrame then
229 healthFrame.strategy = 'UnitClass'
230 end
231 end
232
233 Chorus.unitFrameMain = function(...)
234 return unitFrameMain(...)
235 end
236
237 Chorus.unitMemberFrameMain = function(...)
238 return unitMemberFrameMain(...)
239 end
File src/ChorusUnitFrameTemplate.xml added (mode: 100644) (index 0000000..eca0937)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 <Script file="ChorusUnitFrameTemplate.lua"/>
4 <Frame name="ChorusUnitFrameTemplate" virtual="true" protected="false">
5 <Frames>
6 <Frame name="$parentSecureHandlerAttributeFrame" inherits="SecureHandlerAttributeTemplate"/>
7 </Frames>
8 <Attributes>
9 <Attribute name="unit" type="string" value="none"/>
10 </Attributes>
11 <Scripts>
12 <OnLoad>Chorus.unitFrameMain(self);</OnLoad>
13 </Scripts>
14 </Frame>
15 <!-- Raid or party members are rendered transparent when out of range. Only works for actual group members. -->
16 <Frame name="ChorusMemberUnitFrameTemplate" inherits="ChorusUnitFrameTemplate" virtual="true" protected="false">
17 <Scripts>
18 <OnUpdate>Chorus.unitFrameUnitInRangeUpdateProcessor(self);</OnUpdate>
19 <OnLoad>Chorus.unitMemberFrameMain(self);</OnLoad>
20 </Scripts>
21 </Frame>
22 <!-- Target-of-target (TOT) unit frame is updated multiple times a second. Use sparingly. -->
23 <Frame name="ChorusTOTUnitFrameTemplate" inherits="ChorusUnitFrameTemplate" virtual="true" protected="false">
24 <Scripts>
25 <OnUpdate>Chorus.unitFrameTOTUpdateProcessor(self);</OnUpdate>
26 </Scripts>
27 </Frame>
28 </Ui>
File src/ChorusUnitGroupRoleFrameTemplate.lua changed (mode: 100644) (index f0fa759..f2d3b33)
... ... local UnitIsConnected = Chorus.test.UnitIsConnected or UnitIsConnected
6 6
7 7 local SecureButton_GetUnit = Chorus.test.SecureButton_GetUnit or SecureButton_GetUnit local SecureButton_GetUnit = Chorus.test.SecureButton_GetUnit or SecureButton_GetUnit
8 8
9 --[[ FIXME Only tank role texture is ever rendered. ]]--
10
9 11 local function getUnitGroupRoleDesignation(unitDesignation) local function getUnitGroupRoleDesignation(unitDesignation)
10 12 local isTank, isHealer, isDamage = UnitGroupRolesAssigned(unitDesignation) local isTank, isHealer, isDamage = UnitGroupRolesAssigned(unitDesignation)
11 13
Date/time (UTC) Type Misc Labels
2024-01-04 13:33 build debian-11-amd64 worker/r1 builder/color=fff worker_elap/3559s wait_time/10934648s date/2023-08-30 time/23:09
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/chorus

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/chorus

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/chorus

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main